Печать Win32 - невозможно установить альбомный режим - PullRequest
0 голосов
/ 24 марта 2009

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

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

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

Ответы [ 2 ]

2 голосов
/ 24 марта 2009

Из документации 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);
2 голосов
/ 24 марта 2009

Вы разместили реальный код?

Кроме того, взгляните на сигнатуру функции 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);

Взгляните на этот пример кода для изменения Devmode с использованием функции DocumentProperties.

Обычно я использую GetPrinterW, чтобы получить структуру PRINTER_INFO_2W. pDevMode участник возвращает вам devmode. Мне повезло, используя этот девмод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...