http://www.cnblogs.com/menlsh/p/4211988.html

  在上一篇博文中我主要介绍了如何获取以及设置系统的默认打印机,本文将介绍如何对打印机状态进行实时监控,记录下所打印的文档、打印的份数以及打印时间等打印信息。

1.打印机虚脱机技术

  在正式介绍如何对打印机状态进行实时监控之前,我们有必要先了解一下打印机虚脱机技术。

  独占设备是指在一个程序(作业、用户)的整个运行期间独占设备,直到该程序(作业、用户)完成。系统的独占设备是有限的(比如,一台计算机只能够连接一台打印机),往往不能够满足多进程的要求,会引起大量进程由于等待某些独占设备而阻塞。另一方面,申请到独立设备的进程在其整个运行期间占有设备,利用率却非常低,造成独占设备长时间处于空闲状态。

  为了解决这种矛盾,最常用的办法就是利用共享设备来模拟独占设备,从而提高系统效率和独占设备的利用率。该技术就是虚脱机技术(SPOOL:Simultaneous Peripaheral Operation On Line)。

  打印机是典型的独占设备,引入虚脱机技术后,用户的打印请求传递给SPOOL系统,而不是真正的把打印机分配给用户。SPOOL系统先在磁盘上申请一个空闲区域,把需要打印的数据传输到里面,再把用户的打印请求挂到打印机队列上。如果打印机空闲,就会从打印机队列中取出一个打印请求,再从磁盘的对应区域取出数据,执行打印操作。由于磁盘是共享的,SPOOL系统可以随时响应打印请求并把数据缓存起来,以此实现独占设备模拟共享设备,从而提高系统效率和独占设备的利用率。

2.枚举当前打印机的打印任务

  在Windows API中提供了如下一些打印相关枚举函数:

  EnumForms();         //枚举当前打印机支持的所有页型

  EnumJobs();           //枚举当前打印机的打印任务

  EnumMonitors();         //枚举可用监视器

  EnumPorts();          //枚举可用的打印端口

  EnumPrinterDrivers();     //枚举打印机驱动程序

  EnumPrinters();          //枚举打印机

  EnumPrinterProcessors();   //枚举打印进程

  我们要监控打印机状态,需要用到EnumJobs()函数,用来枚举当前打印机的打印任务。该函数的原型如下:

 1 BOOL
 2 WINAPI
 3 EnumJobs(
 4     HANDLE  hPrinter,
 5     DWORD   FirstJob,
 6     DWORD   NoJobs,
 7     DWORD   Level,
 8     LPBYTE  pJob,
 9     DWORD   cbBuf,
10     LPDWORD pcbNeeded,
11     LPDWORD pcReturned
12 );

  其中,参数hPrinter表示打印机对象句柄;参数FirstJob表示作业列表中要枚举的第一个作业的索引(索引号从0开始);参数NoJobs表示要枚举的作业数量;参数Level表示级别(取值可以是1或2);参数pJob表示JOB_INFO_x结构的缓冲区(x由参数Level决定);参数cbBuf表示JOB_INFO_x结构的缓冲区大小;参数pcbNeeded用于保存请求的缓冲区长度;参数pcReturned则表示了载入缓冲区的结构数量。

3.具体编程实现

  了解了EnumJobs()函数之后,我们就可以开始编写具体的代码了。

3.1获得打印机对象句柄

  我们知道,EnumJobs()函数的第一个参数是打印机对象句柄hPrinter,所以在调用EnumJobs()函数之前,我们需要获得打印机对象句柄,这可以通过调用OpenPrinter()函数来实现。该函数原型为:

1 BOOL
2 WINAPI
3 OpenPrinter(
4    LPSTR    pPrinterName,
5    LPHANDLE phPrinter,
6    LPPRINTER_DEFAULTS pDefault
7 );

  其中,参数pPrinterName是打印机的名称;参数phPrinter就是我们想要得到的打印机对象句柄。

3.2获取打印状态

  获取得到打印机对象句柄之后,我们便可以使用EnumJobs()函数来枚举打印任务,从而得到打印状态了。具体实现方法如下:

 1 /*
 2  * 函数功能 : 显示打印机状态
 3  * 备    注 :
 4  * 作    者 : 博客园 依旧淡然
 5  */
 6 void CPrintDemoDlg::ShowPrinterStatus()
 7 {
 8     HANDLE printerHandle;                //打印机设备句柄
 9
10     //检测打开打印机设备是否成功
11     if(!OpenPrinter(m_strPrinterName.GetBuffer(0), &printerHandle, NULL))
12         return;
13
14     DWORD nByteNeeded;
15     DWORD nReturned;
16     DWORD nByteUsed;
17
18     //通过调用GetPrinter()函数得到作业数量
19     PRINTER_INFO_2* pPrinterInfo = NULL;
20     GetPrinter(printerHandle, 2, NULL, 0, &nByteNeeded);
21     pPrinterInfo = (PRINTER_INFO_2*)malloc(nByteNeeded);
22     GetPrinter(printerHandle, 2, (LPBYTE)pPrinterInfo, nByteNeeded, &nByteUsed);
23
24     //通过调用EnumJobs()函数枚举打印任务
25     JOB_INFO_2* pJobInfo = NULL;
26     EnumJobs(printerHandle, 0, pPrinterInfo->cJobs, 2, NULL, 0,
27         (LPDWORD)&nByteNeeded, (LPDWORD)&nReturned);
28     pJobInfo = (JOB_INFO_2*)malloc(nByteNeeded);
29     ZeroMemory(pJobInfo, nByteNeeded);
30     EnumJobs(printerHandle, 0, pPrinterInfo->cJobs, 2, (LPBYTE)pJobInfo, nByteNeeded,
31         (LPDWORD)&nByteUsed, (LPDWORD)&nReturned);
32
33     //检测当前是否有打印任务
34     if(pPrinterInfo->cJobs == 0)
35         return;
36
37     //纸张类型
38     CString strPageSize = _T("");
39     if(pJobInfo[0].pDevMode->dmPaperSize == DMPAPER_A4)
40         strPageSize = _T("A4");
41     else if(pJobInfo[0].pDevMode->dmPaperSize == DMPAPER_B5)
42         strPageSize = _T("B5");
43
44     //打印份数
45     CString strPrintCopies = _T("");
46     strPrintCopies.Format("%d", pJobInfo[0].pDevMode->dmCopies);
47
48     //打印颜色
49     CString strPrintColor = _T("");
50     if(pJobInfo[0].pDevMode->dmColor == DMCOLOR_COLOR)
51         strPrintColor = _T("彩色");
52     else if(pJobInfo[0].pDevMode->dmColor == DMCOLOR_MONOCHROME)
53         strPrintColor = _T("黑白");
54
55     //打印时间
56     CString strSubmitted = _T("");
57     strSubmitted.Format("%d-%d-%d %d:%d:%d",
58         pJobInfo[0].Submitted.wYear, pJobInfo[0].Submitted.wMonth, pJobInfo[0].Submitted.wDay,
59         pJobInfo[0].Submitted.wHour+8, pJobInfo[0].Submitted.wMinute, pJobInfo[0].Submitted.wSecond);
60
61   //更新打印机状态列表控件
62     UpdateDataPrinterStatusListCtrl(pJobInfo[0].pDocument, strPageSize,
63         strPrintCopies, strPrintColor, strSubmitted);
64
65     free(pPrinterInfo);
66
67     //关闭打印机设备
68     ClosePrinter(printerHandle);
69 }

  可以看到,在上述代码中,我们首先调用OpenPrinter()函数得到了打印机设备句柄printerHandle,然后通过调用GetPrinter()函数来为PRINTER_INFO_2结构体对象pPrinterInfo赋值,从而进一步通过pPrinterInfo->cJobs得到打印机作业数量。随后,我们通过调用EnumJobs()函数枚举打印任务,为JOB_INFO_2结构体对象pJobInfo赋值。JOB_INFO_2结构体中便存储了我们需要得到的一系列打印机状态信息。最后,我们调用了UpdateDataPrinterStatusListCtrl()函数,将打印机状态信息显示在一个列表控件上。

  程序运行结果如图1所示。在打印机选择下拉列表中,会列出当前系统中的所有打印机,选择要监听的打印机之后,点击开始监听按钮,便会创建一个子线程,对打印机状态进行监听(我这里因为没有连接打印机,所以使用的是虚拟打印机Adobe PDF)。当有文档被打印时,打印状态便会实时的显示在列表中。

图1 打印机状态监控

  由图1可以看出,目前我们已经可以得到打印的文档名称、纸张类型、打印份数、打印颜色以及打印时间这些信息了。如何能够获取得到更多的打印信息呢?比如打印文档的路径、内容、大小、页数等信息,又比如在打印文档中加入自定义页眉、页脚或是水印等。这些功能我还在进一步研究学习,哪位博友若是有这方面的经验,还望指点,我将不胜感激。

打印技术之打印机状态监控相关推荐

  1. 【打印技术02】打印机状态监控

    在上一篇博文中我主要介绍了如何获取以及设置系统的默认打印机,本文将介绍如何对打印机状态进行实时监控,记录下所打印的文档.打印的份数以及打印时间等打印信息. 1.打印机虚脱机技术 在正式介绍如何对打印机 ...

  2. 佳能c3320如何u盘打印_佳能打印机脱机无法打印怎么办 佳能打印机脱机状态如何解除【详解】...

    打印机 是我们日常生活中必不可少的一种办公用具,佳能打印机就是在市场上销售的比较好的品牌之一,在使用过程中难免会遇到打印机出现问题的时候,那么 佳能打印机脱机无法打印怎么处理 呢? 佳能打印机脱机状态 ...

  3. dlp型3d打印机_【论文新萃】光聚合成型3D打印技术复制印章研究

    光聚合成型3D打印技术复制印章研究 冯明帅1  彭嘉俊2  马立2  (1.广东省公安厅刑事技术中心,广东广州,510050 2.广东警官学院刑事技术系,广东广州,510440) 摘  要:本项目研究 ...

  4. dlp型3d打印机_DLP与LCD光固化3D打印技术的对比

    DLP与LCD光固化3D打印技术的对比 3D打印技术发展至今各种新技术应运而生,可使用材料越来越多,应用领域也越来越广.时至今日,3D打印技术不再那么高高在上,已经深入大众的生活. 3D打印技术众多, ...

  5. 打印系统开发(39)——检查打印机状态

    public class Printer {/// <summary> /// 构造函数 /// </summary> /// <param name="nam ...

  6. 打印机打印文件时,状态为spooling而不打印任何东西

    打印文档时,进程条很长不前进.这时,进"控制面板(control panel)"中"硬件和声音(Hardware and Sound)"下,找"设备和 ...

  7. word连续打印连续编号_复合纤维共挤3D打印技术CFC,Anisoprint连续纤维3D打印机

    2019年11月19日,目前全球规模最大的3D打印专业展会FORMNEXT在德国法兰克福举行,全球超800家3D打印厂商参展,中国展商超70家.为了满足中国数十万熊友对全球3D打印发展最新情况的了解, ...

  8. 打印机无法打印显示服务器错误怎么办,打印机显示错误怎么办 打印机状态错误是怎么回事...

    1.首先要检查打印机是否处于联机状态,如果打印机没有联机是无法进行工作的,检查打印机与电脑之间的连线是否正确. 2.然后在开始中找到设备和打印机,在弹出窗口右键单击空白处,选择添加打印机,添加本地打印 ...

  9. win7 打印机状态正常无法打印的解决方法(更新补丁后打印机无法打印的解决方法)

    win7 打印机状态正常无法打印的解决方法(更新补丁后打印机无法打印的解决方法): 经过测试 打印机是日常办公过程中非常重要的设备.有些win7旗舰版用户在Windows Update更新补丁后,发现 ...

最新文章

  1. caffe安装_Ubuntu 16.04 下 Theano 安装,及配置多 GPU使用(Multiple GPUs)
  2. codeforces1485 F. Copy or Prefix Sum(dp)
  3. 搜索Maven依赖资源_搜索Maven工件_搜索Maven构件_搜索依赖_搜索构件_搜索工件
  4. java web聊天室私聊map_java websocket聊天室示例(springboot)
  5. Balder 3D开发系列之--给自定义基本体进行贴图操作
  6. xshell连接redhat注册显示中文乱码
  7. word太大怎么压缩变小,word压缩方法
  8. 基于uni-app手机端后台管理系统uni-uadmin
  9. Android persist类property 知识点
  10. java语句以什么结尾_Java程序语句结尾必须以英文字符(???? ?)结尾。
  11. 可以度量金融泡沫的对数周期幂律
  12. leetcode记录汇总
  13. 计算机组装pdf最新,新编计算机组装与维护.pdf
  14. float 或者 flex 换行(打工人的愤怒)
  15. Hyperledger Fabric 之Peers介绍
  16. 给VS2010安装 visual assistant X 1819
  17. 在react项目中配置alias-[webpack配置]
  18. android studio找不到X21,不必苦等Android P,这些“新”功能其实早在vivo X21就已实现...
  19. 自己常用的VScode snippet(持续更新)
  20. python 团体程序设计天梯赛L1合集(持续更新)

热门文章

  1. 苹果的AR真那么高科技?带你见识这些神奇AR应用
  2. linux x和wq的区别,:x和:wq的区别
  3. 途风大数据 2013北美旅游最IN盘点
  4. 一粒云盘v2.4版本更新
  5. java免费视频通话,GitHub标星3.2K
  6. 什么叫h5项目_对移动端h5项目的一点总结
  7. OpenCV分离图像通道
  8. Flash Timeout.Reset the Target and try it again 报错解决方案 STM32 ST-LINK Utility下载程序操作
  9. [ActionScript 3.0] AS3.0 调试出现安全沙箱冲突错误解决办法
  10. 趣图:六层网络协议的消息传递