Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ch-15.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
676.86 Кб
Скачать

Реализация разбиения страницы на полосы

В программе PRINT4, представленной на рис. 15.13, к логике печати программы PRINT3 добавлено разбиение страницы на полосы. Для программы PRINT4 также необходим представленный на рис. 15.8 файл PRINT.RC, а так же, как и для всех программ серии PRINT, представленный на рис. 15.5 файл PRINT.С.

PRINT4.MAK

#----------------------

# PRINT4.MAK make file

#----------------------

print4.exe : print.obj print4.obj print.res

$(LINKER) $(GUIFLAGS) -OUT:print4.exe print.obj print4.obj \

print.res $(GUILIBS) winspool.lib

print.obj : print.c

$(CC) $(CFLAGS) print.c

print4.obj : print4.c

$(CC) $(CFLAGS) print4.c

print.res : print.rc

$(RC) $(RCVARS) print.rc

PRINT4.C

/*---------------------------------------

PRINT4.C -- Printing with Banding

(c) Charles Petzold, 1996

---------------------------------------*/

#include <windows.h>

HDC GetPrinterDC (void) ; // in PRINT.C

void PageGDICalls (HDC, int, int) ;

HINSTANCE hInst ;

char szAppName[] = "Print4" ;

char szCaption[] = "Print Program 4 (Banding)" ;

BOOL bUserAbort ;

HWND hDlgPrint ;

BOOL CALLBACK PrintDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)

{

switch (msg)

{

case WM_INITDIALOG :

SetWindowText (hDlg, szAppName) ;

EnableMenuItem (GetSystemMenu (hDlg, FALSE), SC_CLOSE,

MF_GRAYED) ;

return TRUE ;

case WM_COMMAND :

bUserAbort = TRUE ;

EnableWindow (GetParent (hDlg), TRUE) ;

DestroyWindow (hDlg) ;

hDlgPrint = 0 ;

return TRUE ;

}

return FALSE ;

}

BOOL CALLBACK AbortProc (HDC hdcPrn, int iCode)

{

MSG msg ;

while (!bUserAbort && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))

{

if (!hDlgPrint || !IsDialogMessage (hDlgPrint, &msg))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

}

return !bUserAbort ;

}

BOOL PrintMyPage (HWND hwnd)

{

static DOCINFO di = { sizeof (DOCINFO), "Print4: Printing", NULL } ;

BOOL bError = FALSE ;

HDC hdcPrn ;

RECT rect ;

int xPage, yPage ;

if (NULL == (hdcPrn = GetPrinterDC ()))

return TRUE ;

xPage = GetDeviceCaps (hdcPrn, HORZRES) ;

yPage = GetDeviceCaps (hdcPrn, VERTRES) ;

EnableWindow (hwnd, FALSE) ;

bUserAbort = FALSE ;

hDlgPrint = CreateDialog (hInst, "PrintDlgBox", hwnd, PrintDlgProc) ;

SetAbortProc (hdcPrn, AbortProc) ;

if (StartDoc (hdcPrn, &di) > 0 && StartPage (hdcPrn) > 0 &&

ExtEscape (hdcPrn, NEXTBAND, 0, NULL, sizeof (rect), (LPSTR) &rect) > 0)

{

while (!IsRectEmpty (&rect) && !bUserAbort)

{

Rectangle (hdcPrn, rect.left, rect.top, rect.right,

rect.bottom) ;

PageGDICalls (hdcPrn, xPage, yPage) ;

if (ExtEscape (hdcPrn, NEXTBAND, 0, NULL, sizeof (rect),

(LPSTR) &rect) < 0)

{

bError = TRUE ; // If error, set flag and

break ; // break out of loop

}

}

}

else

bError = TRUE ;

if (!bError)

{

if (bUserAbort)

AbortDoc (hdcPrn) ;

else

if (EndPage (hdcPrn))

EndDoc (hdcPrn) ;

}

if (!bUserAbort)

{

EnableWindow (hwnd, TRUE) ;

DestroyWindow (hDlgPrint) ;

}

DeleteDC (hdcPrn) ;

return bError || bUserAbort ;

}

Рис. 15.13. Программа PRINT4

Программа PRINT4 отличается от программы PRINT3 только несколькими особенностями. Обратите внимание, что вместо прямоугольника, проходящего по границе страницы в целом, функция Rectangle печатает его для каждой полосы. Это позволяет вам увидеть то, как для конкретного принтера реализуется разбиение на полосы. Структура кода, выполняющего печать, такова:

if (StartDoc (hdcPrn, &di) > 0 && StartPage (hdcPrn) > 0 &&

ExtEscape (hdcPrn, NEXTBAND, 0, NULL, sizeof (rect), (LPSTR) &rect) > 0)

{

while (!IsRectEmpty (&rect) && !UserAbort)

{

[вызовы функций GDI]

if (ExtEscape (hdcPrn, NEXTBAND, 0, NULL, sizeof (rect),

(LPSTR)&rect) < 0)

{

bError = TRUE ; // если ошибка, установить флаг и

break ; // выйти из цикла

}

}

}

else

bError = TRUE ;

Цикл while выполняется только в том случае, если прямоугольник не пуст и, если пользователь не отказался от печати в окне диалога. Программа PRINT4 должна проверять возвращаемое значение каждого вызова функции ExtEscape с параметром подфункции NEXTBAND и устанавливать флаг bError, если это возвращаемое значение отрицательно. Если ни один вызов функции ExtEscape не возвратит ошибки, то задание на печать должно быть закончено либо с помощью вызова функции EndDoc, либо прервано с помощью вызова функции AbortDoc. Этот код представлен ниже:

if (!bError)

{

if (bUserAbort)

AbortDoc (hdcPrn) ;

else

if (EndPage (hdcPrn))

EndDoc (hdcPrn) ;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]