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




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

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

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

Flags – это поле должно содержать флаги инициализации. Тут с помощью логической операции или можно указать начальное положение переключателей, отключить некоторые пункты диалога (например, печать выделенного фрагмента, если такая возможность отсутствует в программе и т.п.)

 

Рисунок 2.2.2 – Настройка печати

 

Перед вызовом функции PrintDlg() следует проинициализировать нужные поля, остальные установить в ноль:

BOOL fResult;PRINTDLG pd; ... ZeroMemory(&pd, 0, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG);pd.hwndOwner = hWnd;pd.Flags = PD_RETURNDC; fResult = PrintDlg(&pd); if (pd.hDevMode) GlobalFree(pd.hDevMode); if (pd.hDevNames) GlobalFree(pd.hDevNames);

 

Необходимо обратить внимание на необходимость освобождения глобальных блоков памяти (функцией GlobalFree()), а после завершения печати и контекста принтера функцией DeleteDC(HDC hDC).

Внесем в демонстрационную программу следующие изменения:

1. Добавим прототип функции печати после прототипа функции ShadyDiagram:
void Print(HWND hWnd);

2. В оконную процедуру добавим обработчик отпускания левой кнопки мыши после обработчика функции WM_CREATE:
case WM_LBUTTONUP:
Print(hWnd);
break;

3. В конец файла добавим описание функции Print().

 

Void Print(HWND hWnd)

{

DOCINFO docinfo;

PRINTDLG pd;

 

ZeroMemory(&pd, sizeof(pd));

 

pd.lStructSize = sizeof(PRINTDLG);

pd.hwndOwner = hWnd;

pd.Flags = PD_RETURNDC;

 

if (PrintDlg(&pd))

{

ZeroMemory(&docinfo, sizeof(docinfo));

 

docinfo.cbSize = sizeof(docinfo);

 

if (StartDoc(pd.hDC, &docinfo) > 0)

{

StartPage(pd.hDC);

ShadyDiagram(pd.hDC, 1600, 1300, 1000, 50, g_data, g_pBrushes, g_iNumOfPies);

EndPage(pd.hDC);

EndDoc(pd.hDC);

}

}

 

if(pd.hDevMode)

GlobalFree(pd.hDevMode);

 

if(pd.hDevNames)

GlobalFree(pd.hDevNames);

 

if (pd.hDC)

DeleteDC(pd.hDC);

 

return;

}

 

По щелчку в окне левой кнопкой мыши появляется диалоговое окно печати, в котором можно выбрать принтер и нажать «Печать». Результат печати показан на рисунке 2.2.3.

Функция Print() работает следующим образом:

Обнуляется память, занимаемая структурой PRINTDLG:

ZeroMemory(&pd, sizeof(pd));

Затем некоторым полям присваиваются значения:

pd.lStructSize = sizeof(PRINTDLG);

pd.hwndOwner = hWnd;

pd.Flags = PD_RETURNDC;

Важным является установка флага PD_RETURNDC.

Следующим шагом вызывается функция PrintDlg() и, если она возвращает истинный результат, что соответствует нажатию кнопки «Печать» (а не «Отмена»), выполняется тело условного оператора if:

if (PrintDlg(&pd))

При печати заполняется единственное требуемое поле структуры DOCINFO. В целом структура содержит информацию для очереди печати, например, количество страниц, которое программа собирается напечатать, название документа. Подробнее можно узнать, обратившись к справке по данной структуре.

Далее вызывается функция начала печати нового документа:

if (StartDoc(pd.hDC, &docinfo) > 0)

И если не произошло ошибок (результат положительный), начинается печатать первая и единственная страница:

StartPage(pd.hDC);

Все графические построения на принтере осуществляет такая же функция, что и на экране:

ShadyDiagram(pd.hDC, 1600, 1300, 1000, 50, g_data, g_pBrushes, g_iNumOfPies);

Следует обратить внимание на увеличенный в пять раз масштаб (значения координат). Дело в том, что по умолчанию применяются единицы измерения конкретного устройства. Для монитора – это пиксели, для принтера – точки. И если 600 пикселей на экране часто занимают половину монитора, то на принтере это чуть больше 2,5 см (при разрешении 600 точек на дюйм). При печати удобно применять системы координат в мм или дюймах, что задается функцией SetMapMode().

После вывода изображения, сообщаем принтеру о завершении печати страницы и документа в целом:

EndPage(pd.hDC);

EndDoc(pd.hDC);

Последним шагом освобождаем используемые ресурсы (которых может быть не быть, если пользователь отменил печать):

if(pd.hDevMode)

GlobalFree(pd.hDevMode);

 

if(pd.hDevNames)

GlobalFree(pd.hDevNames);

 

if (pd.hDC)

DeleteDC(pd.hDC);

Результат работы программы показан на рисунке 2.2.3.

 

Рисунок 2.2.3 – Распечатка на бумаге диаграммы демонстрационной программой

 

Контрольные вопросы

 

  1. Какую функцию выполняет драйвер видеокарты при выполнении в программе команды построения графического примитива, например, эллипса?
  2. Что такое контекст устройства? Какое его назначение?
  3. Можно ли просто изменить байты информации в видеопамяти и сразу увидеть результат на экране монитора в рамках ОС Windows?
  4. Последние версии ОС Windows часто используют DirectX с целью вывода информации на экран, например, в браузере, а не универсальные функции GDI? С чем это связано?
  5. Что такое перо, что такое кисть в терминах GDI?
  6. Как в приведенном примере построения круговой диаграммы реализуется эффект «тени»?
  7. Где по умолчанию находится центр координат при выводе информации на экран? Какое направление осей координат? В каких единицах измеряются координаты?
  8. Зачем при выборе цвета кисти заливки замкнутой фигуры необходимо сохранять идентификатор предыдущей используемой кисти?
  9. Существуют ли отличия в программном выводе информации на экран монитора или на принтер? Почему?
  10. Как получить контекст принтера для печати на нем?

 




Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-13 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: