打印的问题,折磨人呐,跪求指点~
问题背景:
正常的打印错误提示,如图:,出现这样的提示表示需要使用的打印机的人介入解决问题,正常情况下点击“确定”的时候打印机会默认问题已经得到处理,并继续打印。点击“取消打印”的时候就是取消打印咯。
通过调用Windows API SetJob可以实现“取消打印“的效果,下面是代码:
// jobId打印机ID,nJobControl 命令类型(有暂停、继续、取消之类的)
// 当nJobControl 等于 JOB_CONTROL_CANCEL 时表示取消打印
BOOL SetJob(DWORD jobId ,int nJobControl)
{
HANDLE hPrinter;
if(!OpenPrinter(_T("HP Deskjet 1000 J110 series"),&hPrinter,NULL))// 取句柄
{
ClosePrinter(hPrinter);
return FALSE;
}
if (!::SetJob( hPrinter , jobId , 0 , NULL , nJobControl ))// 调用API
{
DbgPrint("SetJob Fail ! GetLastError() : %ld \n " , GetLastError());
ClosePrinter(hPrinter);
return FALSE;
}
ClosePrinter(hPrinter);// 关闭打印机
return TRUE;
}
BOOL SetPrinter()
{
HANDLE hPrinter;
if(!OpenPrinter(_T("HP Deskjet 1000 J110 series"),&hPrinter,NULL))
{
ClosePrinter( hPrinter );
return FALSE;
}
DWORD cByteNeeded,/*nReturned,*/cByteUsed;
PRINTER_INFO_2 *pPrinterInfo = NULL;
if (!GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
ClosePrinter( hPrinter );
return FALSE;
}
}
pPrinterInfo = (PRINTER_INFO_2 *)malloc(cByteNeeded);
if (!(pPrinterInfo)) /* Failure to allocate memory. */
{
ClosePrinter( hPrinter );
return FALSE;
}
/* Get the printer information. */
if (!GetPrinter(hPrinter,2,(LPBYTE)pPrinterInfo,cByteNeeded,&cByteUsed))
{ /* Failure to access the printer. 访问打印机错误*/
free(pPrinterInfo);
pPrinterInfo = NULL;
ClosePrinter( hPrinter );
return FALSE;
}
PRINTER_DEFAULTS *pDefault= NULL;
pDefault = new PRINTER_DEFAULTS;
if ( NULL == pDefault )
{
free(pPrinterInfo);
pPrinterInfo = NULL;
ClosePrinter( hPrinter );
return FALSE;
}
// 前面的代码都是为了取到下面这两个值,然后再次调用OpenPrinter提升访问权限
pDefault->pDevMode = pPrinterInfo->pDevMode ;
pDefault->pDatatype = pPrinterInfo->pDatatype ;
pDefault->DesiredAccess = PRINTER_ACCESS_ADMINISTER;//提升打印机访问权限
ClosePrinter( hPrinter );
if(!OpenPrinter(_T("HP Deskjet 1000 J110 series"),&hPrinter,pDefault ))//
{
delete pDefault;
free(pPrinterInfo);
pPrinterInfo = NULL;
delete pDefault;
ClosePrinter( hPrinter );
return FALSE;
}
if( !::SetPrinter( hPrinter , 0x0 , NULL , PRINTER_CONTROL_PURGE ) )
{
DbgPrint("PRINTER_CONTROL_RESUME ::SetPrinter Fail ! GetLastError=%d \n " , GetLastError() );
}else
{
DbgPrint("SetPrinter PRINTER_CONTROL_RESUME Success! \n ");
}
ClosePrinter(hPrinter);
free(pPrinterInfo);
pPrinterInfo = NULL;
delete pDefault;
ClosePrinter( hPrinter );
return TRUE;
}
// jobId打印机ID,nJobControl 命令类型(有暂停、继续、取消之类的)
// 当nJobControl 等于 JOB_CONTROL_CANCEL 时表示取消打印
BOOL SetJob(DWORD jobId ,int nJobControl)
{
BOOL bDone = FALSE;
HANDLE hPrinter;
if(OpenPrinter(_T("HP Deskjet 1000 J110 series"),&hPrinter,NULL)// 取句柄
{
BOOL iRetry = FALSE;
do
{
if (::SetJob( hPrinter , jobId , 0 , NULL , nJobControl ))// 调用API
{
bDone = TRUE;
break; //成功
}
else
{
CString szMsg;
szMsg.Format(_T("打印错误:代码(%ld)\n需要重试一次吗?"),
GetLastError());
if(AfxMessageBox(szMsg, MB_YESNO
[解决办法]
MB_ICONQUESTION) == IDYES)
iRetry = TRUE; //选择重试
else //取消
break;
}
}while(iRetry);
ClosePrinter(hPrinter);// 关闭打印机
}
return bDone;
}
说个笨点的方法
下钩子钩窗口创建消息
发现这个窗口弹出了就找到找到确定按钮点击一下
窗口没有,上面有说到。关于钩子我了解得不多,用得也不熟,请问是否可以只钩打印机句柄相关的消息 ?如果可以的话,那我就可以通过钩子了解到在点击确定的时候具体发送了什么消息给打印机。
从spy++看没有消息可以追踪了
看来只能用钩子钩窗口了
PC和打印机之间的通信是需要的是打印机句柄,钩错误提示框窗口能钩到我需要的信息么 ?