Win32打印 - 无法设置横向模式

时间:2009-03-24 15:34:08

标签: winapi visual-c++ printing

我有一个旧的应用程序,我需要以横向模式打印。我发现的文档说要获得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()有效,但我不知道如何在调试器中检查hWndprinter_handle_pointer的正确性。

所以,如果有人能告诉我我做错了什么,或者如何更好地诊断它,或者如何判断手柄是否有效并指向有效信息,我会喜欢它,我很感激。

我在Vista Business SP1上使用VS 2008SP1,如果这有任何区别的话。原始应用程序是在某些版本的XP上使用早期版本的VS编写的。

2 个答案:

答案 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文档:

  

要更改应用程序本地的打印设置,应用程序应遵循以下步骤:

     
      
  1. 通过调用DocumentProperties并在fMode参数中指定零来获取完整DEVMODE结构所需的字节数。
  2.   
  3. 为完整的DEVMODE结构分配内存。
  4.   
  5. 通过调用DocumentProperties获取当前的打印机设置。将指向步骤2中分配的DEVMODE结构的指针作为pDevModeOutput参数传递,并指定DM_OUT_BUFFER值。
  6.   
  7. 修改返回的DEVMODE结构的相应成员,并通过设置DEVMODE的dmFields成员中的相应位来指示更改了哪些成员。
  8.   
  9. 调用DocumentProperties并将修改后的DEVMODE结构作为pDevModeInput和pDevModeOutput参数传回,并指定DM_IN_BUFFER和DM_OUT_BUFFER值(使用OR运算符组合)。可以使用第三次调用DocumentProperties返回的DEVMODE结构作为CreateDC函数调用中的参数。
  10.   

看起来你错过了第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);