下面是Hook StartDocPort实现打印内容重定向的代码。BOOL WINAPI MyStartDocPort(
HANDLE hPort,
LPWSTR pPrinterName,
DWORD JobId,
DWORD Level,
LPBYTE pDocInfo)
{
EnterCritSection();
PORT *pPort=(PORT*)hPort;
if(pPort->dwStatus & PS_STARTDOC)
{
LeaveCritSection();
return FALSE;
} TCHAR filepath[MAX_PATH]; _tcscpy(filepath,pPort->sPath);
switch(Level)
{
case 1:
{
DOC_INFO_1 *pDoc=(DOC_INFO_1*)pDocInfo;
_tcscat(filepath,pDoc->pDocName);
break;
}
case 2:
{
DOC_INFO_2 *pDoc=(DOC_INFO_2*)pDocInfo;
_tcscat(filepath,pDoc->pDocName);
break;
}
} //filepath contains now the full path of output file
//change file extension to .prn
PathRenameExtension(filepath,_T(\".prn\")); ←这里重定向 //If output file exists: try to delete
if(FileExists(filepath))
DeleteFile(filepath); pPort->hFile=::CreateFile(
filepath,
GENERIC_WRITE,
0, //dont share the file
NULL, //SECURITY_ATTRIBUTES --> Handle cannot be inherited
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL); //no template file if(pPort->hFile==INVALID_HANDLE_VALUE)
{
//could not open file
pPort->hFile=0; HANDLE hPrinter;
if(OpenPrinter(pPrinterName,&hPrinter,NULL))
{
SetJob(
hPrinter,
JobId,
0,
NULL,
JOB_CONTROL_RESTART); SetJob(
hPrinter,
JobId,
0,
NULL,
JOB_CONTROL_PAUSE); CloseHandle(hPrinter); LeaveCritSection();
return FALSE;
}
}
else
{
//file successfully opened
_tcscpy(pPort->sCurDocument,filepath);
_tcscpy(pPort->sPrinter,pPrinterName);
pPort->dwStatus|=PS_STARTDOC;
pPort->dwJobID=JobId;
} LeaveCritSection(); return TRUE;
}
//*****************************************************************
这里重定向的.PRN文件是打印数据嘛?
是的话为什么不能输出打印机呢?因该如何获取.PRN数据然后输出到打印机呢?
我想截获到打印机的打印数据(.prn)然后保存备份后再发回给打印机打印!
但这里截获的prn数据的大小,要比打印输出到文件得到的prn文件小的多!
这是怎么回事呢??
疯了...望指教一二!
感激涕零!!
//*****************************************************************
HANDLE hPort,
LPWSTR pPrinterName,
DWORD JobId,
DWORD Level,
LPBYTE pDocInfo)
{
EnterCritSection();
PORT *pPort=(PORT*)hPort;
if(pPort->dwStatus & PS_STARTDOC)
{
LeaveCritSection();
return FALSE;
} TCHAR filepath[MAX_PATH]; _tcscpy(filepath,pPort->sPath);
switch(Level)
{
case 1:
{
DOC_INFO_1 *pDoc=(DOC_INFO_1*)pDocInfo;
_tcscat(filepath,pDoc->pDocName);
break;
}
case 2:
{
DOC_INFO_2 *pDoc=(DOC_INFO_2*)pDocInfo;
_tcscat(filepath,pDoc->pDocName);
break;
}
} //filepath contains now the full path of output file
//change file extension to .prn
PathRenameExtension(filepath,_T(\".prn\")); ←这里重定向 //If output file exists: try to delete
if(FileExists(filepath))
DeleteFile(filepath); pPort->hFile=::CreateFile(
filepath,
GENERIC_WRITE,
0, //dont share the file
NULL, //SECURITY_ATTRIBUTES --> Handle cannot be inherited
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL); //no template file if(pPort->hFile==INVALID_HANDLE_VALUE)
{
//could not open file
pPort->hFile=0; HANDLE hPrinter;
if(OpenPrinter(pPrinterName,&hPrinter,NULL))
{
SetJob(
hPrinter,
JobId,
0,
NULL,
JOB_CONTROL_RESTART); SetJob(
hPrinter,
JobId,
0,
NULL,
JOB_CONTROL_PAUSE); CloseHandle(hPrinter); LeaveCritSection();
return FALSE;
}
}
else
{
//file successfully opened
_tcscpy(pPort->sCurDocument,filepath);
_tcscpy(pPort->sPrinter,pPrinterName);
pPort->dwStatus|=PS_STARTDOC;
pPort->dwJobID=JobId;
} LeaveCritSection(); return TRUE;
}
//*****************************************************************
这里重定向的.PRN文件是打印数据嘛?
是的话为什么不能输出打印机呢?因该如何获取.PRN数据然后输出到打印机呢?
我想截获到打印机的打印数据(.prn)然后保存备份后再发回给打印机打印!
但这里截获的prn数据的大小,要比打印输出到文件得到的prn文件小的多!
这是怎么回事呢??
疯了...望指教一二!
感激涕零!!
//*****************************************************************
Print providers are responsible for directing print jobs to local or remote print devices. They are also responsible for print queue management operations, such as starting, stopping, and enumerating a server's print queues.
例子在C:\WinDDK\6001.18002\src\print\pp中。
重定向到打印机
你可以试试把这样得到的数据用OpenPrinter、StartDocPrinter、WritePrinter、EndDocPrinter、ClosePrinter输出到打印机。
当准备输出到打印机时,一般spool file已经根据打印机图形dll返回的DeviceCaps和GDIINFO结构,将GDI命令转换成了打印机语言,是百分百和设备相关的。
不同的打印机,其设备能力都不一样,即使重定向到其他的打印机,能正常输出的可能性很小。
要重定向,我认为还是应该在EMF spool file被printer graphic dll解释之前做,EMF是设备无关的,这样可以保证在任何物理打印机or虚拟打印机上都能正确被render。
果然不可以正常打印...
由此推断,我说获得的prn文件,并不是打印机需要的数据文件...
使之可以输出到打印机打印呢??
Hook打印的程序我也没做过,只是提点建议给你参考。
经过打印机图形dll翻译后,就已经是打印机作业语言了,如PCL,PostScript等。要取得设备无关的打印内容,要么在PrintProcessor中,用非正常方式拿到spool file,解析然后保存;
要么在打印机图形dll即打印机驱动中,使用设备管理的surface,hook住必需的ddi函数,然后记录成EMF。
经过打印机图形dll之后就是设备相关的数据了,拿到了,也没有用。