用C++ Builder编程监控打印机队列状态

用C++ Builder编程监控打印机队列状态

摘要:

目前,关于API的应用的文章可以说是遍布各类期刊、杂志。但是多数实例与应用都是基于Visual Basic 的,多数人反映针对于C++ Builder的应用太少,而与打印相关的应用更是少之又少(即使是Visual Basic在这方面的应用可是很少),事实的确如此。这是一篇介绍应用C++ Builder结合Windows API来实现对打印机队列状态进行监控的文章。

一、API介绍:

API是Application Programming Interface的缩写,也就是应用程序调用系统功能的接口。Windows API主要包括系统定义的函数、消息及与之相关的数据类型。我们使用各种开发工具归根结底都是和API打交道。

二、与打印状态相关的API:

Api函数名函数说明W3.xW9xNT
EnumJobs获取打印作业信息
OpenPrinter获取指定打印机的句柄

在 Windows NT 版本以及 Windows 9x 中,增加了一批全新的、专门用来处理打印机及打印机队列状态的 API 函数。在这里,将通过 API 函数 OpenPrinter 与 EnumJobs,来确定打印机打印作业状态所需的信息。

OpenPrinter,用来获取给定打印机的句柄,通过该句柄可以实现对相应打印机的操作。

函数 EnumJobs,用来列出所指定打印机上正在打印的作业信息,这里给定打印机的引用就是通过使用上述OpenPrinter函数反馈回来的打印机句柄。


EnumJobs函数介绍:

EnumJobs (ByVal hPrinter As Long, ByVal FirstJob As Long, ByVal NoJobs As Long, ByVal Level As Long, pJob As Long, ByVal cbBuf As Long, pcbNeeded As Long, pcReturned As Long)

API函数EnumJobs用于列举给定打印机当前所有正在打印的任务状态信息,该函数可以列举给定打印机简要的或者详细的(Level决定)队列任务状态信息。在引用该函数时,通常先把cbBuf变量设置为0,以获得打印机队列任务的字节数,该字节数存储在pcbNeeded里以决定pJob变量大小,然后再次引用该函数,获得打印机队列任务的详细信息。

参数:

hPrinter

打印机句柄。

FirstJob

统计打印机队列任务数的起始点,0表示从第一个任务开始统计列举所有的打印任务。

NoJobs

需要列举的最大打印任务数。一般设为127。

Level

标示存储在pJob里的信息格式。如果该值为1,数据以JOB_INFO_1的格式存储;如果该值为2,数据以JOB_INFO_2的格式存储。

pJob

数组变量,保存打印任务的所有信息;cbBuf设为0时,该值也为0。Level变量的值决定pJob的数据格式(JOB_INFO_1 OR JOB_INFO_2)

cbBuf

该值通常为0。

pcbNeeded

存储打印机里打印任务的字节数。

pcReturned

用来存放打印任务数量的变量。

通过上表可以看出,这两个API函数只用使用在Windows 9x 以及 Windows NT环境中。

三、开发工具:

C++ Builder作为快速开发Windows平台下应用程序的工具,已经为越来越多的开发者采用。但是,如果要开发出专业的Windows应用软件,还需要使用大量的Windows API函数,以下是笔者应用C++ Builder以及Windows API函数来实现对打印机状态的时时监控。

选择C++ Builder的理由:

一:由于Windows API 都是用C或C++编写的,C++ Builder更易于底层应用。

二:C++ Builder对于Windows API的引用更加简单,这一点是Visual Basic所欠缺的。


四、程序实例:

1、启动C++ Builder程序,新创建一个工程;

2、进入工程,在当前窗体分别添加一个CheckListBox控件、一个Timer控件;

3、在CheckListBox控件的Item属性添加打印机名称列表(假设在网络中HostPrinter主机上有三台打印机Printer1、Printer2、Printer3),则Item项目里内容格式为:\\HostPrinter\Printer1\\HostPrinter\\Printer2\\HostPrinter\\Printer3 ;

4、Timer的Interval属性设置为60000(一分钟),在Timer的OnTimer事件加入如下代码:


{

HANDLE hPrinter; //打印机句柄

JOB_INFO_2 jobs[30]; //保留打印作业详细信息

DWORD size=sizeof(jobs);

JOB_INFO_2 *jobs1=NULL; //动态数组用于对大于size的任务进行操作

DWORD pcbNeeded=0; //所有打印字节数

int actNeed=0;

DWORD pcReturned=0; //打印任务数

char buf[19]; //指向打印机或机器名

int ret1; //获得打印机句柄返回值

int ret; //获得打印机任务返回值

TDateTime startTime;

Word Hour=0;

Word Hour1=0;

Word Min=0;

Word Min1=0;

Word Sec=0;

Word MSec=0;

int StartTime=0; //任务开始时间

int NowTime=0; //当前时间

int TotalTime=0; //任务停留时间

String str;

int length;

int PrintCount;

int InitCount=15; //设定的打印队列数量--------报警底线

int InitTime=10; //设定的打印队列事件--------报警底线(分钟)


PrintCount =CheckListBox1->Count ;

for (int i=0; i < PrintCount; i++)

{


//..............取得列表里的打印机

str=CheckListBox1->Items->Strings[i] ;

length=str.Length() ;


//................字符串到字符的转换,

StrPLCopy(buf,str,length);


//................获得打印机句柄

ret1= OpenPrinter(buf, &hPrinter, NULL);


//................获得打印任务数

ret= EnumJobs(hPrinter, 0, 127, 2,0, 0, &pcbNeeded, &pcReturned); //必要的一步,先取出打印机里任务的字节数,然后决定jobs1变量大小。//--------------------------①


//.................重定义Jobs1, 根据pcbNeeded决定使用哪个变量

if (pcbNeeded>size)

{

actNeed=pcbNeeded;

jobs1=new JOB_INFO_2[actNeed];

ret= EnumJobs(hPrinter, 0, 127, 2,(LPBYTE)jobs1, actNeed, &pcbNeeded, &pcReturned);

startTime=SystemTimeToDateTime(jobs1[0].Submitted); //------------------②

delete jobs1;

}

else

{

ret= EnumJobs(hPrinter, 0, 127, 2,(LPBYTE)jobs, size, &pcbNeeded, &pcReturned);//-----------------------------③

if (pcReturned>0)

startTime=SystemTimeToDateTime(jobs[0].Submitted);

}

//.................pcbNeeded>size结束


//................如果队列里有打印任务,比对数量与时间

if (pcReturned>0)

{


//.................时间转换,计算一天内的时间差

{

//............时间比较运算处理;

//............时间转换StartTime转换成分钟


}

DecodeTime(Now(),Hour1, Min1, Sec,MSec);

NowTime=Hour1*60+Min1;

TotalTime=NowTime-StartTime;

}


//依据条件判断是否报警

if ((pcReturned>InitCount) |(TotalTime >InitTime))

{


Beep();


}


pcReturned=0;

pcbNeeded=0;


}


//..........................pcReturned>0结束


}//....................................................for结束

 

5、编译并运行上述程序:

①程序中,此处的获得打印机任务的目的主要是获得打印机作业的字节数------ pcbNeeded,该变量里字节的大小,将决定进一步获得打印机里作业的状态时所用的变量是Jobs还是Jobs1。

②当pcbNeeded>size,给Jobs1分配空间,然后获得打印机当前作业的状态。

③当pcbNeeded<size,用Jobs作为变量,获得当前打印机作业状态。

注:②、③参数引用与①不同。

五、应用分析:

可以说IT技术在制造业得到了广泛的应用,而打印控制与监控则是制造业中众多应用中的较为典型的应用。通常,在生产制造过程中,都有很多打印机用于打印生产排序单、装配单、铭牌、标签等等。因此打印机的时时状态(缺纸、墨尽、卡纸)在这里就显得尤为重要了,如果不能及时的监控到打印机的状态势必会影响生产的正常持续运行。所以为了保证生产正常运行拥有一套用于监控打印机时时状态的程序是很有必要的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C Builder是一个功能强大的集成开发环境(IDE),用于开发Windows平台上的应用程序。在C Builder中,可以使用MSComm控件进行串口编程。 MSComm是一个串口通信控件,可以用于在Windows系统上通过串口与外部设备进行数据交互。使用C Builder进行MSComm串口编程可以实现以下功能: 1. 打开和关闭串口:通过设置MSComm控件的PortOpen属性为True或False,可以打开或关闭串口连接。在初始化时,可以设置串口的端口号、波特率、数据位、停止位和校验位等参数。 2. 发送和接收数据:通过设置MSComm控件的Output和Input属性,可以向串口发送数据和从串口接收数据。可以使用Write和InputLen方法来发送和接收字符串,也可以使用Output和Input属性来直接访问串口数据。 3. 事件处理:MSComm控件提供了多个事件(如OnComm、OnCommEvent、OnCommError),可以用于处理串口通信过程中的各种情况,如接收到数据、通信错误等。通过编写事件处理程序,可以在特定情况下执行相应的操作。 4. 控制流控制:MSComm控件支持软件流控制和硬件流控制,可以通过设置控件的HandShaking属性来选择使用哪种流控制方式。软件流控制包括Xon/Xoff协议,硬件流控制包括CTS/RTS和DSR/DTR信号线。 总的来说,C Builder提供了强大的工具和库来进行串口编程,而MSComm控件则是其中一个常用的工具,可以方便地实现串口通信功能。通过C Builder和MSComm串口编程,可以与外部设备进行数据交互,实现数据采集、控制和通信等应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值