文档的真正打印不是应用程序的责任,是后台打印处理程序的责任
一、打印机专用函数
1、StartDoc,
2、EndDoc
3、,StartPage;
4、EndPage
它们负责把打印机的输出组织成不同打印页。GDI函数把文字和图形输出现在在这些页面上,如同显示在屏幕一样。
二、打印相关模块:GDI模块,打印机设备驱动程序库模块,Windows后台打印处理程序(print spooler)。
三、获取打印机设备环境句柄:CreateDC,PrintDlg,这使得打印机设备驱动程序库模块被加载到内存,并初始化。
四、开始打印:StartDc(GDI)->Control函数(打印机设备驱动程序),通知设备驱动程序做好准备,N次(StartPage,GDI,EndPage),EndDoc。
打印其中一页过程:GDI负责把所有的GDI函数保存在硬盘的图元文件里(以~EMF开头,后缀是.TMP)。打印机驱动程序必须把存储在图元文件里面的各个绘图命令转化成适用于打印机的输出。打印机把页面分带,并把每一条带的打印机输出传给GDI模块,而GDI模块则把这些输入保存到另外一个临时文件夹,文件以~SPL开口,以.TMP作为后缀。
打印一页完成后:GDI模块采用进程间调用(inter-process call)告诉后台打印处理程序新的打印作业已经就绪。
五、Windows后台打印处理程序组成
1、打印请求程序
2、本地打印机提供程序
3、网络打印提供程序
4、打印处理器
5、端口监控程序
6、语言监控程序
打印后台程序把应用程序从一些涉及打印的工作中解脱出来
六、打印机工作模式变体:禁用打印后台程序,那么,不会保存临时文件~EMF,~SPL到本地,而是GDI直接将打印输出直接输出到打印机。
七:枚举打印机
EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4,NULL,0,&dwNeeded,&dwReturned);
prntInfo4 = (PRINTER_INFO_4*)malloc(dwNeeded);
EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4,(PBYTE)prntInfo4,dwNeeded,&dwNeeded,&dwReturned);
HDC hdc = CreateDC(NULL,prntInfo4->pPrinterName,NULL,NULL);
HANDLE hPrint;
for (int i= 0; i<dwReturned;i++)
{
if(_tcsicmp(TEXT("Canon iR3225 UFR II"),prntInfo4[i].pPrinterName) == 0) {
if(OpenPrinter(prntInfo4[i].pPrinterName,&hPrint,NULL)) {
PrinterProperties(NULL, hPrint); //打开属性页面
ClosePrinter(hPrint);
}
}
}
八、几个显示打印机属性对话框的函数
1、ExtDeviceMode
2、ExtDeviceModePropSheet
3、PrinterProperties ---- 推荐
九、获取页面可打印区域的尺寸和分辨率:GetDeviceCaps
十、用异常中断过程取消打印,但是为了防止异常中断的消息循环分发消息,所以在StartDoc之前EnabledWindow(hWnd,FALSE),然后SetAbortProc;
注意:
1、无论是CreateDC,还是PrintDLG获取到打印机设备环境句柄,都必须使用DeleteDC进行释放