下面是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文件小的多!
这是怎么回事呢??
疯了...望指教一二!
感激涕零!!
//*****************************************************************

解决方案 »

  1.   

    可能你需要添加一个PrintProvider。
    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中。
      

  2.   

    http://www.99inf.net/SoftwareDev/VC/28879.htm
    重定向到打印机
      

  3.   

    重定向是把输出到某一设备的内容改成输出到其它地方,不是从中间过程中把数据复制出来,这里的重定向是把输出到打印机的原始数据输出到文件中。当打印文档时,输出到打印机的数据是文字、字体、颜色格式等信息,所以内容较少,但如果是用虚拟打印的形式把打印的内容保存为图象文件,这样得到的文件就很大了。
    你可以试试把这样得到的数据用OpenPrinter、StartDocPrinter、WritePrinter、EndDocPrinter、ClosePrinter输出到打印机。
      

  4.   

    我比较怀疑在PORT上拿到的数据是否有用。
    当准备输出到打印机时,一般spool file已经根据打印机图形dll返回的DeviceCaps和GDIINFO结构,将GDI命令转换成了打印机语言,是百分百和设备相关的。
    不同的打印机,其设备能力都不一样,即使重定向到其他的打印机,能正常输出的可能性很小。
    要重定向,我认为还是应该在EMF spool file被printer graphic dll解释之前做,EMF是设备无关的,这样可以保证在任何物理打印机or虚拟打印机上都能正确被render。
      

  5.   

    我把截获到的PRN文件输出到了物理打印机上,
    果然不可以正常打印...
    由此推断,我说获得的prn文件,并不是打印机需要的数据文件...
      

  6.   

    用MyStartDocPort()获取不到prn的话~还有什么方法可以获得 原始的打印数据.prn呢?
    使之可以输出到打印机打印呢??
      

  7.   

    你改成Hook OpenPrinter、StartDocPrinter、WritePrinter、EndDocPrinter、ClosePrinter这些函数试试。
    Hook打印的程序我也没做过,只是提点建议给你参考。
      

  8.   

    要取得打印的内容,并且重定向到其他打印机,一定要是一种设备无关的格式,如EMF,XPS。
    经过打印机图形dll翻译后,就已经是打印机作业语言了,如PCL,PostScript等。要取得设备无关的打印内容,要么在PrintProcessor中,用非正常方式拿到spool file,解析然后保存;
    要么在打印机图形dll即打印机驱动中,使用设备管理的surface,hook住必需的ddi函数,然后记录成EMF。
    经过打印机图形dll之后就是设备相关的数据了,拿到了,也没有用。