读书人

打印的有关问题折磨人呐跪求指点

发布时间: 2013-08-06 16:47:25 作者: rapoo

打印的问题,折磨人呐,跪求指点~
问题背景:
正常的打印错误提示,如图:打印的有关问题,折磨人呐,跪求指点,出现这样的提示表示需要使用的打印机的人介入解决问题,正常情况下点击“确定”的时候打印机会默认问题已经得到处理,并继续打印。点击“取消打印”的时候就是取消打印咯。

通过调用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;
}


好了,问题来了:怎么样才能实现上面提到的点击“确定”的效果?
我试图通过下面的代码来解决,API调用成功,但是并没有解决问题(代码结构不咋的,不要拍我 ~_~ ):


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;
}



求指点!打印的有关问题,折磨人呐,跪求指点


打印错误提示 VC++?API编程
[解决办法]
引用:
Quote: 引用:

弹出这个的时候任务应该是暂停的吗? 你再继续打印任务就行了吧


我也是这样认为的,但是我试过很多次,API调用成功,但是打印机没有反应啊:
::SetJob(?hPrinter?,?jobId?,?0?,?NULL?, JOB_CONTROL_RESUME?);

MSDN上都找不到这个问题相关的说明。


那应该是那个弹出的框把打印机程序阻塞了吧 你试下弹出框来的时候 手动去打印其他文件能打印不?

实在不行 那只有枚举窗口 找到这个弹出框 然后模拟消息发送点击 确定 按钮了
[解决办法]
//可以这样试试看



// 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;
}


[解决办法]
引用:
Quote: 引用:

说个笨点的方法
下钩子钩窗口创建消息
发现这个窗口弹出了就找到找到确定按钮点击一下


窗口没有,上面有说到。关于钩子我了解得不多,用得也不熟,请问是否可以只钩打印机句柄相关的消息 ?如果可以的话,那我就可以通过钩子了解到在点击确定的时候具体发送了什么消息给打印机。
这个你可以用spy++看看
[解决办法]
引用:
Quote: 引用:

从spy++看没有消息可以追踪了
看来只能用钩子钩窗口了


PC和打印机之间的通信是需要的是打印机句柄,钩错误提示框窗口能钩到我需要的信息么 ?
你可以试着钩函数

读书人网 >VC/MFC

热点推荐