2009-03-24 4 views
0

У меня есть старое приложение, которое мне нужно для печати в ландшафтном режиме. В документации я нашел говорит, чтобы получить структуру DEVMODE, изменить пару полей, и положил его обратно в То, что я получил, это:.Win32 печать - невозможно установить ландшафтный режим

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 (фактически беззнаковый эквивалент), что означает условие ошибки. Это происходит как в режиме отладки, так и в режиме Release (один отчет, который я видел в Интернете, имел эту проблему в Debug, но не Release). printer_name.get() действителен, но я не знаю, как проверить hWnd или printer_handle_pointer на правильность в отладчике.

Итак, мне бы хотелось, чтобы кто-нибудь мог сказать мне, что я делаю неправильно, или как лучше диагностировать его, или как определить правильность дескрипторов и указать на достоверную информацию, я был бы признателен ,

Я использую VS 2008SP1 для Vista Business SP1, если это имеет значение. Первоначальное приложение было написано с более ранней версией VS на некоторой версии XP.

ответ

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.

+0

Спасибо за указатель, но техника GetPrinter() работала не лучше для меня. –

+0

Большое спасибо. Это прибило его. –

2

Из документации Microsoft для DocumentProperties:

Чтобы внести изменения в параметрах печати, которые являются локальными для приложения, приложение должно выполнить следующие действия:

  1. Получить количество байтов, необходимых для полную структуру DEVMODE, вызывая DocumentProperties и указывая нуль в параметре fMode.
  2. Выделите память для полной структуры DEVMODE.
  3. Получить текущие настройки принтера, вызвав DocumentProperties. Передайте указатель на структуру DEVMODE, выделенную на шаге 2, в качестве параметра pDevModeOutput и укажите значение DM_OUT_BUFFER.
  4. Измените соответствующие элементы возвращенной структуры DEVMODE и укажите, какие члены были изменены, установив соответствующие биты в члене dmFields DEVMODE.
  5. Вызовите DocumentProperties и передайте модифицированную структуру DEVMODE как параметры pDevModeInput, так и pDevModeOutput и укажите значения DM_IN_BUFFER и DM_OUT_BUFFER (которые объединены с использованием оператора OR). Может быть использована структура DEVMODE, возвращенная третьим вызовом DocumentProperties как аргумент при вызове функции 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); 
+0

На самом деле, у меня есть шаг 1 (строка начинается «size_t devmode_size»), и проблема в том, что devmode_size (возвращаемое значение) неточно. Я был явно неясен. –

+0

Я слегка изменил вопрос, чтобы сделать его более понятным. Надеюсь это поможет. –

+0

Плохо, мне нужно немного почитать немного. –

Смежные вопросы