Qt/Windows 获取 MITSUBISHI P95DW 打印机状态信息

背景:
采用Qt的QPrinterInfo可获取到可用的打印机,同时使用QPrinter设置打印的纸张,单位,方向等信息,在正常连接打印机和纸张正确放置的情况下可以实现打印功能,开发所用的打印机为MITSUBISHI P95DW,当打印机无纸,离线或者关闭等其他异常情况下,Qt所获取到的打印机依然是IDLE状态了,无法获取到打印机真实的异常状态。
调试思考:

1.所用打印机弹出了Paper Empty的窗口,所以就想到用钩子获取到该窗口,并根据内容得到具体的异常内容,钩子的方法参见

https://blog.csdn.net/fzuim/article/details/53692135icon-default.png?t=M276https://blog.csdn.net/fzuim/article/details/53692135

,但是遗憾的是,当Windows桌面系统没有启用时,打印机的异常弹出窗口并没有产生。所以此方案行不通。
2.按照一般思路,Windows系统应该是捕捉了打印机通过驱动上发的异常消息,所以应该有API能够有这些功能。通过网络查找发现了EnumPrinters的函数,通过函数名可知是枚举打印机的,那么自然而然就能够有其他的函数能够找到获取打印机状态的函数了。
https://docs.microsoft.com/en-us/windows/win32/printdocs/enumprinters
结果:

通过查找和阅读文档中相对应的函数,找到了获取当前打印机状态的函数如:
OpenPrinter
GetPrinter
参数设置不同可以获取到不同级别的打印机当时的状态内容,本文使用的级别是2,对应到的结构体为
PRINTER_INFO_2;利用获取到的结构体的字段就可以知道对应的打印机状态
typedef struct _PRINTER_INFO_2 {
  LPTSTR               pServerName;
  LPTSTR               pPrinterName;
  LPTSTR               pShareName;
  LPTSTR               pPortName;
  LPTSTR               pDriverName;
  LPTSTR               pComment;
  LPTSTR               pLocation;
  LPDEVMODE            pDevMode;
  LPTSTR               pSepFile;
  LPTSTR               pPrintProcessor;
  LPTSTR               pDatatype;
  LPTSTR               pParameters;
  PSECURITY_DESCRIPTOR pSecurityDescriptor;
  DWORD                Attributes;
  DWORD                Priority;
  DWORD                DefaultPriority;
  DWORD                StartTime;
  DWORD                UntilTime;
  DWORD                Status;
  DWORD                cJobs;
  DWORD                AveragePPM;
} PRINTER_INFO_2, *PPRINTER_INFO_2;

代码如下,可用作参考

    HANDLE hPrinter;
	DWORD dwNeeded, dwReturne;

	wchar_t wBuffer[256] = { 0 };
	std::wstring wStr = m_pQPrinter->printerName().toStdWString();
	wmemcpy_s(wBuffer, 256, wStr.c_str(), wStr.size());
	LPWSTR lpw = wBuffer;

	if (!OpenPrinter(lpw, &hPrinter, NULL))
	{
		return;
	}

	if (!GetPrinter(hPrinter, 2, NULL, 0, &dwNeeded))
	{
		if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
		{
			ClosePrinter(hPrinter);

			return;
		}
	}
	
	PRINTER_INFO_2  * pPrinterInfo = (PRINTER_INFO_2  *)GlobalAlloc(GPTR, dwNeeded);
	if (!pPrinterInfo)
	{
		//分配内存失败
		ClosePrinter(hPrinter);


		return;
	}

	if (!GetPrinter(hPrinter, 2, (LPBYTE)pPrinterInfo, dwNeeded, &dwReturne))
	{
		ClosePrinter(hPrinter);
		//delete pJobInfo;
		GlobalFree((HGLOBAL)pPrinterInfo);

		return;
	}
	QString printStatus;

	switch (pPrinterInfo->Status)
	{
	case PRINTER_STATUS_PAPER_OUT: {printStatus = QString(QObject::tr("Printer paper out")); }break;
	case PRINTER_STATUS_OFFLINE:{printStatus = QString(QObject::tr("Printer offline"));}break;
	case PRINTER_STATUS_PAUSED: {printStatus = QString(QObject::tr("Printer paused")); }break;
	case PRINTER_STATUS_ERROR: {printStatus = QString(QObject::tr("Printer error")); }break;
	case PRINTER_STATUS_PENDING_DELETION:break;
	case PRINTER_STATUS_PAPER_JAM: {printStatus = QString(QObject::tr("Printer pager jam")); }break;
	case PRINTER_STATUS_PAPER_PROBLEM: {printStatus = QString(QObject::tr("Printer pager problem")); }break;
	case PRINTER_STATUS_BUSY: {printStatus = QString(QObject::tr("Printer busy")); }break;
	case PRINTER_STATUS_PRINTING: {printStatus = QString(QObject::tr("Do printing")); }break;
	case PRINTER_STATUS_OUTPUT_BIN_FULL:break;
	case PRINTER_STATUS_NOT_AVAILABLE: {printStatus = QString(QObject::tr("Printer not available")); }break;
	case PRINTER_STATUS_WAITING: {printStatus = QString(QObject::tr("Printer waiting")); }break;
	case PRINTER_STATUS_OUT_OF_MEMORY: {printStatus = QString(QObject::tr("Printer out of memory")); }break;
	case PRINTER_STATUS_DOOR_OPEN: {printStatus = QString(QObject::tr("Printer door open")); }break;
	default: {ClosePrinter(hPrinter); return; }
		break;
	}
	
	ClosePrinter(hPrinter);
	

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值