Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Графический интерфейс GDI в Microsoft Windows

© Александр Фролов, Григорий Фролов
Том 14, М.: Диалог-МИФИ, 1993, 288 стр.

[Назад] [Содеожание] [Дальше]

6.2. Функция PrintDlg

С помощью функции PrintDlg приложение может вывести на экран одну из двух диалоговых панелей, представленных на рис. 6.1 и 6.2, с помощью которых пользователь может напечатать документ, выбрать нужный принтер или изменить его параметры.

Рис. 6.1. Диалоговая панель "Print"

В верхней части диалоговой панели "Print" в поле "Printer" указано название принтера, который будет использован для печати. Вы можете выбрать другой принтер, если нажмете кнопку "Setup...".

С помощью группы органов управления "Print Range" вы можете выбрать диапазон страниц, которые должны быть распечатаны. Можно распечатать все или отдельные страницы, выделенный фрагмент текста или страницы в указанном диапазоне номеров страниц (поля "From" и "To").

Можно задать качество печати (поле "Print Quality"), указать количество копий (поле "Copies"), выполнить печать в файл (поле "Print to File").

С помощью переключателя "Collate Copies" можно выбрать порядок печати отдельных листов многостраничного документа, который должен быть напечатан в нескольких копиях. Если этот переключатель находится во включенном состоянии, вначале следует напечатать все страницы первой копии, затем - второй, и так далее. Если же этот переключатель выключен, вначале печатается несколько копий первой страницы, затем несколько копий второй страницы и так до конца документа. Последний режим печати удобен для лазерных принтеров, где время подготовки одной страницы для печати больше времени печати готовой страницы.

Если нажать на кнопку "Setup...", на экране появится диалоговая панель "Print Setup" (рис. 6.2).

Рис. 6.2. Диалоговая панель "Print Setup"

В группе органов управления "Printer" вы можете выбрать для печати либо принтер, принятый по умолчанию ("Default Printer"), либо выбрать другой принтер из списка "Specific Printer".

С помощью переключателей группы "Orientation" вы можете выбрать вертикальное ("Portrait") либо горизонтальное ("Landscape") расположение текста на листе бумаги.

Группа "Paper" содержит два списка, с помощью которых вы можете выбрать размер бумаги (список "Size") или устройство подачи бумаги ("Source").

Нажав в этой диалоговой панели кнопку "Options...", вы сможете выполнить настройку параметров принтера при помощи диалоговой панели "Options" (рис. 6.3).

Рис. 6.3. Диалоговая панель "Options" для лазерного принтера HP LaserJet III

Внешний вид диалоговой панели "Options" зависит от драйвера принтера, так как эта панель формируется функцией DeviceMode или ExtDeviceMode, расположенными в соответствующем драйвере принтера. Для сравнения на рис. 6.4 представлен внешний вид диалоговой панели "Options" для матричного принтера Epson FX-850.

Рис. 6.4. Диалоговая панель "Options" для матричного принтера Epson FX-850

Если вас не устраивает внешний вид диалоговых панелей "Print" и "Print Options", вы можете использовать вместе с функцией PrintDlg свои собственные шаблоны диалоговых панелей. Можно также подключить функцию фильтра для обеспечения дополнительной обработки сообщений.

Приведем прототип функции PrintDlg, описанный в файле commdlg.h:

BOOL PrintDlg(PRINTDLG FAR* lppd);

При успешном завершении функция возвращает значение TRUE. В случае ошибки, отмены печати или отмены выбора принтера (если функция PrintDlg используется только для выбора принтера) функция возвращает значение FALSE.

Структура PRINTDLG

В качестве параметра функции PrintDlg необходимо передать адрес предварительно подготовленной структуры типа PRINTDLG , описанной в файле commdlg.h:

typedef struct tagPD
{
  DWORD   lStructSize;
  HWND    hwndOwner;
  HGLOBAL hDevMode;
  HGLOBAL hDevNames;
  HDC     hDC;
  DWORD   Flags;
  UINT    nFromPage;
  UINT    nToPage;
  UINT    nMinPage;
  UINT    nMaxPage;
  UINT    nCopies;
  HINSTANCE hInstance;
  LPARAM  lCustData;
  UINT (CALLBACK* lpfnPrintHook)(HWND, UINT,WPARAM,LPARAM);
  UINT (CALLBACK* lpfnSetupHook)(HWND, UINT,WPARAM,LPARAM);
  LPCSTR  lpPrintTemplateName;
  LPCSTR  lpSetupTemplateName;
  HGLOBAL hPrintTemplate;
  HGLOBAL hSetupTemplate;
} PRINTDLG;
typedef PRINTDLG  FAR* LPPRINTDLG;

Рассмотрим назначение отдельных полей этой структуры.

lStructSize

Размер структуры PRINTDLG в байтах. Это поле следует заполнить перед вызовом функции PrintDlg.

hwndOwner

Идентификатор окна, создавшего диалоговую панель. Если в поле Flags не указано значение PD_SHOWHELP, в поле hwndOwner можно указать NULL.

hDevMode

Идентификатор глобального блока памяти, содержащего структуру типа DEVMODE, которая используется для инициализации параметров принтера.

Если содержимое этого поля указать как NULL, после возвращения из функции PrintDlg поле будет содержать идентификатор глобального блока памяти, заказанного функцией. В этом блоке памяти будет расположена структура DEVMODE, заполненная выбранными параметрами принтера. Структура DEVMODE будет описана позже.

hDevNames

Идентификатор глобального блока памяти, содержащего структуру типа DEVNAMES, содержащей три текстовые строки. Первая строка определяет имя драйвера принтера, вторая - имя принтера, и третья - имя порта вывода, к которому подключен принтер.

Если содержимое этого поля указать как NULL, после возвращения из функции PrintDlg поле будет содержать идентификатор глобального блока памяти, заказанного функцией для структуры DEVNAMES. В структуре будут находиться строки, соответствующие выбранному принтеру.

hDC

Контекст устройства или информационный контекст.

Это поле заполняется после возвращения из функции PrintDlg, если в поле Flags указано одно из значений: PD_RETURNDC или PD_RETURNIC. В первом случае возвращается контекст принтера, который можно использовать для печати, во втором - информационный контекст, который можно использовать для получения разнообразной информации о принтере.

Flags

Это поле должно содержать флаги инициализации:

PD_ALLPAGES

Переключатель "All" в диалоговой панели "Print" должен находиться во включенном состоянии, при этом предполагается что необходимо распечатать весь текст, а не отдельные страницы или выделенный фрагмент текста.

PD_SELECTION

Переключатель "Selection" в диалоговой панели "Print" должен находиться во включенном состоянии, при этом предполагается что необходимо распечатать выделенный фрагмент текста, но не весь текст или отдельные страницы.

PD_PAGENUMS

Переключатель "Page" в диалоговой панели "Print" должен находиться во включенном состоянии, при этом предполагается что необходимо распечатать отдельные страницы текста, но не выделенный фрагмент текста или весь текст.

PD_NOSELECTION

Переключатель "Selection" должен находиться в заблокированном состоянии.

PD_NOPAGENUMS

Переключатель "Pages" и связанные с ним органы управления должны находиться в заблокированном состоянии.

PD_COLLATE

Переключатель "Collate" должен находиться во включенном состоянии.

PD_PRINTTOFILE

Переключатель "Print to File" должен находиться во включенном состоянии.

PD_PRINTSETUP

При вызове функции PrintDlg вместо диалоговой панели "Print" отображается диалоговая панель "Print Setup".

PD_NOWARNING

Отмена вывода сообщения о том, что в системе не установлен принтер по умолчанию.

PD_RETURNDC

Функция PrintDlg должна вернуть в поле hDC идентификатор контекста устройства, который можно использовать для печати.

PD_RETURNIC

Функция PrintDlg должна вернуть в поле hDC идентификатор информационного контекста, который можно использовать для получения информации о принтере.

PD_RETURNDEFAULT

После возвращения из функции PrintDlg поля hDevMode и hDevNames будут содержать идентификаторы блоков памяти структур DEVMODE и DEVNAMES, заполненных параметрами принтера, выбранного по умолчанию. Если указан флаг PD_RETURNDEFAULT, перед вызовом функции PrintDlg поля hDevMode и hDevNames должны содержать значения NULL, в противном случае функция вернет признак ошибки.

PD_SHOWHELP

В диалоговой панели необходимо отобразить кнопку "Help".

PD_ENABLEPRINTHOOK

Разрешается использовать функцию фильтра для диалоговой панели "Print".

PD_ENABLESETUPHOOK

Разрешается использовать функцию фильтра для диалоговой панели "Print Setup".

PD_ENABLEPRINTTEMPLATE

Разрешается использовать шаблон диалоговой панели "Print", определяемой полями hInstance и lpPrintTemplateName.

PD_ENABLESETUPTEMPLATE

Разрешается использовать шаблон диалоговой панели "Print Setup", определяемой полями hInstance и lpSetupTemplateName.

PD_ENABLEPRINTTEMPLATEHANDLE

Поле hPrintTemplate содержит идентификатор блока памяти с загруженным шаблоном диалоговой панели "Print". Содержимое поля hInstance игнорируется.

PD_ENABLESETUPTEMPLATEHANDLE

Поле hSetupTemplate содержит идентификатор блока памяти с загруженным шаблоном диалоговой панели "Print Setup". Содержимое поля hInstance игнорируется.

PD_USEDEVMODECOPIES

Орган управления "Copies" блокируется, если принтерный драйвер не способен печатать несколько копий.

PD_DISABLEPRINTTOFILE

Блокируется переключатель "Print to File".

PD_HIDEPRINTTOFILE

Переключатель "Print to File" блокируется и удаляется из диалоговой панели.

nFromPage

Начальное значение для инициализации органа управления "From" диалоговой панели "Print". Используется только в том случае, если в поле Flags указан флаг PD_PAGENUMS. Максимальное значение для поля nFromPage составляет 0xfffe.

После возвращения из функции PrintDlg это поле содержит номер страницы документа, с которой должна начинаться печать.

nToPage

Начальное значение для инициализации органа управления "To" диалоговой панели "Print". Используется только в том случае, если в поле Flags указан флаг PD_PAGENUMS. Максимальное значение для поля nFromPage составляет 0xfffe.

После возвращения из функции PrintDlg это поле содержит номер страницы документа, до которой должна выполняться печать.

nMinPage

Минимальное количество страниц, которое можно задать при помощи органов управления "From" и "To".

nMaxPage

Максимальное количество страниц, которое можно задать при помощи органов управления "From" и "To".

nCopies

Значение для инициализации органа управления "Copies", если поле hDevMode содержит значение NULL.

hInstance

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

lCustData

Произвольные данные, которые приложение может передать функции фильтра.

lpfnPrintHook

Адрес функции фильтра для диалоговой панели "Print".

lpfnSetupHook

Адрес функции фильтра для диалоговой панели "Print Setup".

lpPrintTemplateName

Адрес текстовой строки, закрытой нулем, содержащей имя ресурса для шаблона диалоговой панели "Print". Для использования этого поля необходимо указать флаг PD_ENABLEPRINTTEMPLATE.

lpSetupTemplateName

Адрес текстовой строки, закрытой нулем, содержащей имя ресурса для шаблона диалоговой панели "Print Setup". Для использования этого поля необходимо указать флаг PD_ENABLESETUPTEMPLATE.

hPrintTemplate

Идентификатор блока памяти, содержащего предварительно загруженный шаблон диалоговой панели "Print". Для использования этого поля необходимо указать флаг PD_ENABLEPRINTTEMPLATEHANDLE.

hSetupTemplate

Идентификатор блока памяти, содержащего предварительно загруженный шаблон диалоговой панели "Print Setup". Для использования этого поля необходимо указать флаг PD_ENABLESETUPTEMPLATEHANDLE.

Работа с функцией 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;
[Назад] [Содеожание] [Дальше]