Функции для печати
6.3. Функции для печати
В операционной системе Windows версии 3.0 и более ранних версий для печати использовалась одна функция Escape, которая имела множество подфункций (63 подфункции). Начиная с версии 3.1 вместо этой функции рекомендуется использовать несколько других.
Чаще всего используются семь функций.
StartDoc
Эта функция начинает печать нового документа (формирует задание на печать). Она должна вызываться один раз перед началом печати нового документа
StartPage
Эта функция подготавливает устройство вывода к печати новой страницы документа. После вызова этой функции приложение может начинать печать, используя контекст принтера.
EndPage
Функция EndPage завершает процесс печати страницы. Метафайл, созданный в процессе печати одной страницы, проигрывается на принтере.
EndDoc
Функция завершает процесс печати документа. Она вызывается один раз после завершения печати документа.
AbortDoc
Эта функция предназначена для аварийного завершения процесса печати документа.
SetAbortProc
Функция SetAbortProc используется для обеспечения возможности аварийного завершения процесса печати, а также для того чтобы другие приложения могли работать во время печати.
ResetDC
С помощью этой функции можно изменить параметры печати для отдельных листов документа.
Как пользоваться этими функциями?
После получения контекста устройства для принтера ваше приложения должно установить адрес функции отмены печати, вызвав функцию SetAbortProc, и вывести на экран диалоговую панель, позволяющую отменить печать. Диалоговая панель отмены печати должна быть немодальной.
Функция диалоговой панели обычно используется для установки глобального флага отмены печати, который периодически проверяется функцией, выполняющей печать.
Приведем прототип функции SetAbortProc : int SetAbortProc(HDC hdc, ABORTPROC abrtprc);
Первый параметр определяет контекст устройства, для которого устанавливается функция отмены печати, второй - адрес функции отмены печати, полученный при помощи функции MakeProcInstance .
Функция отмены печати может выглядеть, например, следующим образом: BOOL CALLBACK _export AbortFunc(HDC hdc, int nCode) { MSG msg; while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { if(!hdlgAbort || !IsDialogMessage(hdlgAbort, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return(!fAbort); }
В качестве первого параметра функции передается контекст устройства, в качестве второго - код ошибки. Однако обычно оба эти параметра игнорируются.
GDI в процессе печати периодически вызывает функцию отмены печати, которая действует аналогично обычному циклу обработки сообщений, выполняя выборку сообщений из очереди и их диспетчеризацию. Если в очереди больше нет сообщений, функция PeekMessage возвращает FALSE, при этом цикл обработки сообщений завершается.
После этого функция возвращает инвертированное значение флага отмены печати. Если печать должна быть продолжена, функция отмены должна вернуть значение FALSE, если отменена - TRUE.
В качестве функции диалога, предназначенного для отмены печати, можно использовать, например, такую функцию: BOOL CALLBACK _export AbortDlgFunc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_INITDIALOG: { fAbort = FALSE; hdlgAbort = hdlg; return TRUE; } case WM_COMMAND: { if (wParam == IDOK || wParam == IDCANCEL) { fAbort = TRUE; return TRUE; } return FALSE; } case WM_DESTROY: { hdlgAbort = 0; return FALSE; } } return FALSE; }
Основной задачей данной функции является установка глобального флага отмены печати fAbort: fAbort = TRUE;
Итак, мы получили контекст принтера, установили для этого контекста процедуру отмены печати, вывели на экран диалоговую панель с кнопкой "Cancel", позволяющую отменить печать. Теперь можно приступать к печати документа.
Прежде всего необходимо вызвать функцию StartDoc : int StartDoc( HDC hdc, // контекст принтера DOCINFO FAR* lpdi); // адрес структуры DOCINFO
Перед вызовом этой функции нужно подготовить структуру DOCINFO , адрес которой передается через параметр lpdi: typedef struct { int cbSize; LPCSTR lpszDocName; LPCSTR lpszOutput; } DOCINFO;
Поле cbSize должно содержать размер структуры в байтах.
Поле lpszDocName должно содержать указатель на текстовую строку, закрытую двоичным нулем, в которой записано название документа.
Через поле lpszOutput можно передать адрес строки, содержащей имя файла (если печать должна быть переназначена в файл). Поле может содержать NULL, в этом случае выполняется печать на принтере.
Далее можно начинать цикл печати страниц документа.
Печать страницы документа начинается с вызова функции StartPage : int StartPage(HDC hdc);
Эта функция подготавливает принтер для приема данных. При успешном завершении функция возвращает положительное значение, отличное от нуля, при ошибке - нуль или значение, меньшее нуля.
После вызова функции StartPage приложение может начинать печать страницы, вызывая обычные функции GDI, такие как TextOut, BitBlt, StretchBlt, Rectangle и т. п.
Завершив печать одной страницы, приложение должно вызвать функцию EndPage : int EndPage(HDC hdc);
Эта функция не только загружает в принтер новую страницу, и даже не столько загружает новую страницу, сколько проигрывает созданный на этапе рисования метафайл, т. е. выполняет процесс печати страницы.
При успешном завершении функция возвращает положительное значение, отличное от нуля, при ошибке - нуль или значение, меньшее нуля
В цикле печати необходимо проверять значение, возвращаемое функцией EndPage, а также глобальный флаг отмены печати, который устанавливается функцией диалоговой панели отмены печати.
После успешной печати всех страниц документа нужно вызвать функцию EndDoc : int EndDoc(HDC hdc);
Если печать была отменена, или произошла ошибка, вместо этой функции следует вызвать функцию AbortDoc : int AbortDoc(HDC hdc);
Если в процессе печати нужно изменить параметры принтера для отдельных страниц документа, вы можете вызвать до функции StartPage функцию ResetDC : HDC ResetDC( HDC hdc, // контекст печати const DEVMODE FAR* lpdm); // адрес структуры DEVMODE
Эта функция изменяет контекст печати на основе информации, представленной в структуре DEVMODE.
Приложение обычно вызывает эту функцию также в ответ на сообщение WM_DEVMODECHANGE, которое посылается приложению при изменении параметров принтера.
Учтите, что функция StartPage запрещает изменение контекста печати, поэтому вы не сможете изменить параметры печати в процессе печати страницы.