我有一个旧的应用程序,我需要以横向模式打印。我发现的文档说要获得DEVMODE结构,更改几个字段,然后重新输入。我得到的是:
HANDLE printer_handle;
LPHANDLE printer_handle_pointer(&printer_handle);
OpenPrinter(printer_name.get(), printer_handle_pointer, NULL);
size_t devmode_size = DocumentProperties(hWnd, printer_handle_pointer, printer_name.get(), NULL, NULL, 0);
DEVMODE * devmode = reinterpret_cast<DEVMODE *>(new char[devmode_size]);
DocumentProperties(NULL, printer_handle_pointer, printer_name.get(), devmode, NULL, DM_OUT_BUFFER);
devmode->dmSize = sizeof( DEVMODE);
devmode->dmFields |= DM_ORIENTATION;
devmode->dmOrientation = DMORIENT_LANDSCAPE;
DocumentProperties(NULL, printer_handle_pointer, printer_name.get(), devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER);
hdcPrint = CreateDC(NULL, printer_name.get(), NULL, devmode);
我当前的问题是第一个DocumentProperties(返回DEVMODE结构大小的那个)返回-1(实际上是无符号的等价物),表示错误情况。这在调试和发布模式下都会发生(我在Web上看到的一个报告在Debug中有这个问题,但没有发布)。 printer_name.get()
有效,但我不知道如何在调试器中检查hWnd
或printer_handle_pointer
的正确性。
所以,如果有人能告诉我我做错了什么,或者如何更好地诊断它,或者如何判断手柄是否有效并指向有效信息,我会喜欢它,我很感激。
我在Vista Business SP1上使用VS 2008SP1,如果这有任何区别的话。原始应用程序是在某些版本的XP上使用早期版本的VS编写的。
答案 0 :(得分:2)
你发布了真实的代码吗?
另外,请查看DocumentProperties函数签名:
LONG DocumentProperties(
__in HWND hWnd,
__in HANDLE hPrinter,
__in LPTSTR pDeviceName,
__out PDEVMODE pDevModeOutput,
__in PDEVMODE pDevModeInput,
__in DWORD fMode
第三个参数需要HANDLE
,而不是指向代码中HANDLE
(或LPHANDLE
)的指针:
DocumentProperties(NULL,
printer_handle_pointer, /* <--- ? */
printer_name.get(),
devmode,
NULL,
DM_OUT_BUFFER);
改为使用:
DocumentProperties(NULL,
printer_handle, /* <--- ? */
printer_name.get(),
devmode,
NULL,
DM_OUT_BUFFER);
查看this示例代码,使用Devmode
函数修改DocumentProperties
。
我通常使用GetPrinterW
来获取PRINTER_INFO_2W
结构。 pDevMode
成员返回devmode。我使用这个devmode有点运气。
答案 1 :(得分:2)
来自DocumentProperties的Microsoft文档:
要更改应用程序本地的打印设置,应用程序应遵循以下步骤:
- 通过调用DocumentProperties并在fMode参数中指定零来获取完整DEVMODE结构所需的字节数。
- 为完整的DEVMODE结构分配内存。
- 通过调用DocumentProperties获取当前的打印机设置。将指向步骤2中分配的DEVMODE结构的指针作为pDevModeOutput参数传递,并指定DM_OUT_BUFFER值。
- 修改返回的DEVMODE结构的相应成员,并通过设置DEVMODE的dmFields成员中的相应位来指示更改了哪些成员。
- 调用DocumentProperties并将修改后的DEVMODE结构作为pDevModeInput和pDevModeOutput参数传回,并指定DM_IN_BUFFER和DM_OUT_BUFFER值(使用OR运算符组合)。可以使用第三次调用DocumentProperties返回的DEVMODE结构作为CreateDC函数调用中的参数。
醇>
看起来你错过了第1步,这可能是你第一次调用DocumentProperties失败的原因。
在我自己的程序中,我还设置了页面大小,交换长度和宽度。这是一个带有自定义纸张尺寸的特殊小型标签打印机,但我不知道更多花园品种的打印机是否需要这种打印机。
double width = 8.5;
double height = 11.0;
devmode.dmFields = DM_ORIENTATION | DM_PAPERSIZE | DM_PAPERLENGTH | DM_PAPERWIDTH;
devmode.dmOrientation = DMORIENT_LANDSCAPE;
devmode.dmPaperSize = DMPAPER_USER;
devmode.dmPaperLength = (short)(width * 25.4 * 10);
devmode.dmPaperWidth = (short)(height * 25.4 * 10);