0

I am trying to make a AddForm function using C++ Windows.h's Print Spooler API. I haven't find any C++ examples or couldn't figure out solution, so I wanted ask your help.

My code should done same as in this picture:

My code should done same as in this picture

Source Material

Code input:

#include <iostream>
#include "Windows.h"
#include "Winspool.h"

using namespace std;

int main() {

    LPHANDLE hPrinter = NULL;
    OpenPrinter(
        NULL,
        hPrinter,
        NULL
    );  // No critical error here: "hPrinter could be "0"

    FORM_INFO_1 exampleform;
    exampleform.Flags = 0;
    exampleform.pName = (LPWSTR)"0A"; // No critical error here: "Cast between semantically different string types. Use of invalid string can lead to undefined behaviour."
    exampleform.Size.cx = 1260 * 1000;
    exampleform.Size.cy = 891 * 1000;
    exampleform.ImageableArea.left = 0;
    exampleform.ImageableArea.top = 0;
    exampleform.ImageableArea.right = exampleform.Size.cx;
    exampleform.ImageableArea.bottom = exampleform.Size.cy;

    cout << exampleform.pName; //output as: "00007FF68EFA9C24"

    AddForm(hPrinter, 1, reinterpret_cast<LPBYTE>(&exampleform)); // No critical error here : "hPrinter could be "0"

    //C:\Users\XXX\source\repos\paperApp\x64\Debug\paperApp.exe (process 16792) exited with code 0.
}

Problem: The code looks good, but nothing really happens.

Thank you all for your responses!

Khaniini
  • 11
  • 2
  • What is [AddForm](https://learn.microsoft.com/en-us/windows/win32/printdocs/addform) returning? If zero, then what is [GetLastError()](https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror)? – Nick Westgate Jan 19 '23 at 12:48
  • AddForm returns 0. I looked at GetLastError, which returns 6, which means the handle is invalid. My guess is that the error is in the OpenPrinter function. – Khaniini Jan 20 '23 at 19:39
  • If OpenPrinter returns zero, call GetLastError. – Nick Westgate Jan 22 '23 at 23:48

1 Answers1

0

Why are you defining your own FORM_INFO_1? Just use the header provided by Windows:

#include "Winspool.h"

Then fix the differences from your definition:

FORM_INFO_1 exampleform;
exampleform.Flags = 0;
exampleform.pName = (LPWSTR)"MyName";
exampleform.Size.cx = 1260 * 1000;
exampleform.Size.cy = 891 * 1000;
exampleform.ImageableArea.left = 0;
exampleform.ImageableArea.top = 0;
exampleform.ImageableArea.right = exampleform.Size.cx;
exampleform.ImageableArea.bottom = exampleform.Size.cy;

Then fix the error you're getting with a C-style cast:

test = AddForm(hPrinter, 1, (LPBYTE)&exampleform);

Or a C++-style cast:

test = AddForm(hPrinter, 1, reinterpret_cast<LPBYTE>(&exampleform));
Nick Westgate
  • 3,088
  • 2
  • 34
  • 41
  • Thank you very much Westgate for your reply! I still got couple challenges with the code. I made post about it in this topic. – Khaniini Jan 19 '23 at 07:05
  • Like most Windows APIs, if AddForm() returns false, you can call [GetLastError()](https://stackoverflow.com/q/1387064/313445) to find out what the error is. This is basic Windows programming and debugging. If you don't know these things then you need to find some [tutorials](https://riptutorial.com/winapi/example/8521/error-reported-with-additional-information-on-failure) or books on the topic. – Nick Westgate Jan 19 '23 at 07:49