限用在打印机上的函数(StartDoc、EndDoc、StartPage和EndPage)负责将打印机的输出组织打印到纸页上。而一个程序呼叫普通的GDI函数在一张纸上显示文字和图形和在屏幕上显示的方式一样。
打印入门
在Windows下使用打印机时,实际上启动了一个包含GDI32动态链接库模块、打印驱动程序动态连结模块(带.DRV扩展名) 、Windows后台打印程序,以及有用到的其它相关模块。
打印和背景处理
当应用程序要使用打印机时,它首先使用CreateDC或PrintDlg来取得指向打印机设备内容的句柄,于是使得打印机设备驱动程序动态链接库模块被加载到内存并自己进行初始化。然后,程序呼叫StartDoc函数,通知说一个新文件开始了。
打印一个文件的程序以StartDoc呼叫开始,以EndDoc呼叫结束。每页本身是这样来划清界限的:呼叫StartPage来开始一页,呼叫EndPage来结束该页。
如果要定义一个图形页,可能需要很多的数据。为此,打印机驱动程序经常使用一种称作「打印分带」的技术将一页分成若干称为「输出带」的矩形。对每个输出带,设备驱动程序将这些绘图函数转换为在打印机上打印这些图形所需要的输出数据。这种输出数据的格式是依照打印机的特性而异的。打印驱动程序将打印输出的每个输出带传送到GDI模块。
GDI模块将定义一页所需的所有函数存入一个增强型metafile中,然后替驱动程序定义的每个打印输出带输出一遍该metafile到打印驱动程序中。然而,如果打印驱动程序不需要打印分带的话,就不会建立这个metafile。
打印机设备内容
大多数应用程序经由呼叫PrintDlg函数打开一个标准的打印对话框。这个函数还为使用者提供了一个在打印之前改变打印机或者指定其它特性的机会。然后,它将打印机设备内容句柄交给应用程序。该函数能够省下应用程序的一些工作。
某些应用程序(例如Notepad)仅需要取得打印机设备内容,而不需要那个对话框。要做到这一点,需要呼叫CreateDC函数.pInitializationData参数一般被设为NULL。szDeviceName参数指向一个字符串,以告诉Windows打印机设备的名称。在设定设备名称之前,您必须知道有哪些打印机可用。
hdc = CreateDC(NULL,szDeviceName,NULL,pInitializationData);
取得内定打印机设备内容的方式不断在改变。目前,标准的方法是使用EnumPrinters函数来获得。该函数填入一个包含每个连结着的打印机信息的数组结构。这些结构的名称为PRINTER_INFO_x
#include <windows.h> HDC GetPrinterDC(void); //不管是什么操作系统,函数呼叫EnumPrinters两次 //一次取得它所需结构的大小,一次填入结构。 HDC GetPrinterDC(void) { DWORD dwNeeded, dwReturned; HDC hdc; PRINTER_INFO_4 * pinfo4; PRINTER_INFO_5 * pinfo5; if (GetVersion() & 0x80000000)// Windows 98 { EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 5, NULL, 0, &dwNeeded, &dwReturned); pinfo5 = (PRINTER_INFO_5*)malloc(dwNeeded); EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 5, (PBYTE)pinfo5, dwNeeded, &dwNeeded, &dwReturned) ; hdc = CreateDC(NULL, pinfo5->pPrinterName, NULL, NULL); free(pinfo5); } else //Windows NT { EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwNeeded, &dwReturned); pinfo4 = (PRINTER_INFO_4*)malloc(dwNeeded); EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, (PBYTE)pinfo4, dwNeeded, &dwNeeded, &dwReturned); hdc = CreateDC(NULL, pinfo4->pPrinterName, NULL, NULL); free(pinfo4); } return hdc; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int iCmdShow) { static DOCINFO di = { sizeof (DOCINFO), TEXT ("FormFeed") }; HDC hdcPrint; hdcPrint = GetPrinterDC(); if (hdcPrint != NULL) { if (StartDoc(hdcPrint, &di) > 0) if (StartPage(hdcPrint) > 0 && EndPage(hdcPrint) > 0) EndDoc(hdcPrint) ; DeleteDC (hdcPrint); } return 0; }
大多数点阵打印机、激光打印机和喷墨打印机都能进行位块传送,而大多数绘图机却不能。不能处理位块传送的设备不支持下列GDI函数:CreateCompatibleDC、CreateCompatibleBitmap、PatBlt、BitBlt、StretchBlt、GrayString、DrawIcon、SetPixel、GetPixel、FloodFill、ExtFloodFill、FillRgn、FrameRgn、InvertRgn、PaintRgn、FillRect、FrameRect和InvertRect。这是在视讯显示器上使用GDI函数与在打印机上使用它们的唯一重要区别。