Работа с функцией PrintDlg
Перед вызовом функции PrintDlg следует проинициализировать нужные поля, записав в остальные поля нулевые значения:
memset(&pd, 0, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG); pd.hwndOwner = hwnd; pd.Flags = PD_RETURNDC; fResult = PrintDlg(&pd);
Если перед вызовом функции PrintDlg в полях hDevMode и hDevNames было значение NULL, функция заказывает глобальные блоки памяти для структур DEVMODE и DEVNAMES, заполняя их перед возвратом управления.
Структура DEVMODE определена в файле print.h, который находится в каталоге include системы разработки Borland Turbo C++ for Windows:
typedef struct tagDEVMODE { char dmDeviceName[CCHDEVICENAME]; UINT dmSpecVersion; UINT dmDriverVersion; UINT dmSize; UINT dmDriverExtra; DWORD dmFields; int dmOrientation; int dmPaperSize; int dmPaperLength; int dmPaperWidth; int dmScale; int dmCopies; int dmDefaultSource; int dmPrintQuality; int dmColor; int dmDuplex; int dmYResolution; int dmTTOption; } DEVMODE; typedef DEVMODE* PDEVMODE, NEAR* NPDEVMODE, FAR* LPDEVMODE;
Эта структура содержит разнообразную информацию о конфигурации и параметрах принтера. Она подробно описана в документации, которая поставляется вместе с SDK. Из за ограниченного объема книги мы приведем краткое описание полей этой структуры.
Поле | Описание |
dmDeviceName | Имя драйвера принтера |
dmSpecVersion | Номер версии структуры DEVMODE. Для Windows версии 3.1 это поле содержит значение 0x30a |
dmDriverVersion | Версия драйвера |
dmSize | Размер структуры DEVMODE в байтах |
dmDriverExtra | Размер в байтах дополнительной структуры данных, которая может находиться в памяти сразу за структурой DEVMODE |
dmFields | Набор флагов, каждый из которых отвечает за свое поле структуры DEVMODE. Если флаг установлен, соответствующее поле инициализируется. возможны следующие значения: DM_ORIENTATION , DM_PAPERSIZE , DM_PAPERLENGTH , DM_PAPERWIDTH , DM_SCALE , DM_COPIES , DM_DEFAULTSOURCE , DM_PRINTQUALITY , DM_COLOR , DM_DUPLEX , DM_YRESOLUTION , DM_TTOPTION |
dmOrientation | Ориентация бумаги. Возможные значения:DMORIENT_PORTRAIT , DMORIENT_LANDSCAPE |
dmPaperSize | Код размера бумаги. Например, для бумаги формата A4 используется константа DMPAPIER_A4 |
dmPaperLength | Длина листа бумаги в десятых долях миллиметра |
dmPaperWidth | Ширина листа бумаги в десятых долях миллиметра |
dmScale | Коэффициент масштабирования для печати |
dmCopies | Количество печатаемых копий |
dmDefaultSource | Код устройства подачи бумаги, используемого по умолчанию. |
dmPrintQuality | Код разрешения принтера: DMRES_HIGH , DMRES_LOW , DMRES_MEDIUM , DMRES_DRAFT или положительное число, равное количеству точек на дюйм |
dmColor | Режим печати для цветного принтера: DMCOLOR_COLOR - цветная печать, DMCOLOR_MONOCHROME - монохромная печать |
dmDuplex | Возможность печати с двух сторон бумажного листа |
dmYResolution | Разрешение принтера по вертикали в точках на дюйм |
dmTTOption | Способ печати шрифтов True Type:DMTT_BITMAP - печать в графическом режиме, обычно используется для матричных принтеров;DMTT_DOWNLOAD - загрузка шрифтов True Type в память принтера, используется для лазерных принтеров, совместимых с принтерами HP LaserJet;DMTT_SUBDEV - замена шрифтов на принтерные шрифты, используется для PostScript-принтеров |
Структура DEVNAMES , как мы уже говорили, содержит имя драйвера, имя принтера и имя порта вывода, к которому подключен принтер:
typedef struct tagDEVNAMES { UINT wDriverOffset; UINT wDeviceOffset; UINT wOutputOffset; UINT wDefault; } DEVNAMES; typedef DEVNAMES FAR* LPDEVNAMES;
Первые три слова структуры содержат смещения текстовых строк с именами, соответственно, драйвера, принтера и порта вывода. Строки расположены в памяти непосредственно за структурой DEVNAMES. Поле wDefault может содержать флаг DN_DEFAULTPRN , в этом случае все три строки описывают принтер, выбранный по умолчанию.
Вы можете подготовить свои значения для двух описанных выше структур, заказать глобальные блоки памяти и передать их идентификаторы функции PrintDlg, записав в соответствующие поля структуры PRINTDLG.
После возврата из функции PrintDlg необходимо освободить эти блоки памяти, взяв их идентификаторы из полей hDevMode и hDevNames структуры PRINTDLG. Учтите, что функция PrintDlg может изменить значения последних двух полей, поэтому надо освобождать блоки памяти с идентификаторами, взятыми из структуры PRINTDLG после возврата из функции PrintDlg:
if(pd.hDevMode != 0) GlobalFree (pd.hDevMode); if(pd.hDevNames != 0) GlobalFree (pd.hDevNames);
Если перед вызовом функции PrintDlg вы указали флаги PD_RETURNDC или PD_RETURNIC, после возврата поле hDC будет содержать, соответственно, идентификатор контекста устройства или идентификатор информационного контекста:
if(fResult) return pd.hDC; else return NULL;