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

Winapi Win32打印-无法设置横向模式,winapi,visual-c++,printing,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 = DocumentPr

我有一个旧的应用程序,需要以横向模式打印。我找到的文档说,获取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);
手柄打印机\ U手柄;
LPHANDLE打印机\u句柄\u指针(&打印机\u句柄);
OpenPrinter(打印机名称.get(),打印机句柄指针,NULL);
size_t devmode_size=DocumentProperties(hWnd,打印机句柄指针,打印机名称get(),NULL,NULL,0);
DEVMODE*DEVMODE=reinterpret_cast(新字符[DEVMODE_size]);
DocumentProperties(NULL,打印机句柄指针,打印机名称.get(),devmode,NULL,DM\u OUT\u缓冲区);
devmode->dmSize=sizeof(devmode);
devmode->dmFields |=DM|u方向;
devmode->dmOrientation=dmOrientation\u景观;
DocumentProperties(NULL,打印机句柄指针,打印机名称.get(),devmode,devmode,DM_IN_BUFFER | DM_OUT_BUFFER);
hdcPrint=CreateDC(NULL,打印机名称.get(),NULL,devmode);
我当前的问题是,第一个DocumentProperties(返回DEVMODE结构大小的DocumentProperties)返回一个-1(实际上是无符号的等效项),表示出现了错误情况。这在调试和发布模式下都会发生(我在web上看到的一个报告在调试时出现了这个问题,但在发布时没有)。
printer\u name.get()
是有效的,但我不知道如何在调试器中检查
hWnd
printer\u handle\u指针的正确性

所以,如果有人能告诉我我做错了什么,或者如何更好地诊断,或者如何判断句柄是否有效并指向有效信息,我将不胜感激


我在Vista Business SP1上使用VS 2008SP1,如果这有什么区别的话。最初的应用程序是在XP的某个版本上使用早期版本的VS编写的。

你发布了真实的代码吗

另外,请查看DocumentProperties函数签名:

LONG DocumentProperties(
     __in   HWND hWnd,
     __in   HANDLE hPrinter,         
     __in   LPTSTR pDeviceName,
     __out  PDEVMODE pDevModeOutput,
     __in   PDEVMODE pDevModeInput,
     __in   DWORD fMode
第三个参数采用
句柄
,而不是指向
句柄
(或
LPHANDLE
)的指针,正如您在代码中所做的那样:

DocumentProperties(NULL, 
                   printer_handle_pointer, /* <--- ? */
                   printer_name.get(), 
                   devmode, 
                   NULL, 
                   DM_OUT_BUFFER);
DocumentProperties(空,

打印机\u句柄\u指针,/*您发布了真实代码了吗

另外,请查看DocumentProperties函数签名:

LONG DocumentProperties(
     __in   HWND hWnd,
     __in   HANDLE hPrinter,         
     __in   LPTSTR pDeviceName,
     __out  PDEVMODE pDevModeOutput,
     __in   PDEVMODE pDevModeInput,
     __in   DWORD fMode
第三个参数采用
句柄
,而不是指向
句柄
(或
LPHANDLE
)的指针,正如您在代码中所做的那样:

DocumentProperties(NULL, 
                   printer_handle_pointer, /* <--- ? */
                   printer_name.get(), 
                   devmode, 
                   NULL, 
                   DM_OUT_BUFFER);
DocumentProperties(空,

Microsoft文档中的打印机\u句柄\u指针,/*,用于:

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

  • 通过调用DocumentProperties并在fMode参数中指定零,获取完整DEVMODE结构所需的字节数
  • 为完整的DEVMODE结构分配内存
  • 通过调用DocumentProperties获取当前打印机设置。将指向在步骤2中分配的DEVMODE结构的指针作为pDevModeOutput参数传递,并指定DM_OUT_缓冲区值
  • 修改返回的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);
    

    从Microsoft文档中获取:

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

  • 通过调用DocumentProperties并在fMode参数中指定零,获取完整DEVMODE结构所需的字节数
  • 为完整的DEVMODE结构分配内存
  • 通过调用DocumentProperties获取当前打印机设置。将指向在步骤2中分配的DEVMODE结构的指针作为pDevModeOutput参数传递,并指定DM_OUT_缓冲区值
  • 修改返回的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);
    

    谢谢你的指针,但是GetPrinter()技术对我来说没有更好的效果。谢谢你的指针,但是GetPrinter()技术对我来说没有更好的效果。事实上,我有第1步(行开头是“size_t devmode_size”),问题是devmode_size(返回值)不准确。我显然不清楚。为了让问题更清楚,我稍微修改了一下。希望这能有所帮助。事实上,我有第一步(行开头是“size_t devmode_size”),问题是devmode_