打印机学习笔记

1. 打印机处理器(PrintProcessor)

    BOOL bRet = TRUE;
    CHAR pDriverDirectory[MAX_PATH];
    DWORD pcbNeeded;
    //获取打印机驱动程序位置
    if(FALSE == GetPrintProcessorDirectory(NULL, "Windows x64", 1, (LPBYTE)&pDriverDirectory, MAX_PATH, &pcbNeeded)){
        //Error
        return -1;
    }
    //拷贝文件...
    //添加打印机处理器
    if(FALSE == AddPrintProcessor(NULL, NULL, "printProcessor.dll", "printProcessor")){
        //Error
        return -1;
    }

PrintProcessor最主要的是处理PrintDocumentOnPrintProcessor函数,修改EMF的处理方法,这里希望将读取的打印机中间文件spl转成jpg图片。

参考论文《EMF虚拟打印机实现》(李朝中)中的PrintDocumentOnPrintProcessor函数和SaveSplFile函数。

SPL文件保存后,接下来就是将SPL文件解析成EMF文件。

这里可以参考网上spltoemfex类的实现,调用SplToEmf函数转成MEF文件。

将EMF转JPG文件需要使用GDI+,参考https://blog.csdn.net/numen27/article/details/25642985(将EMF文件转换成JPG文件)

添加打印机需要管理器权限,因此最好将UAC,在“连接器”:“清单文件”中设置。

如果打印机驱动程序已经存在了,可能会出现“另一个程序正在使用此文件”的错误。因此需要先结束Print Spool服务,再在最后启动服务,启动和结束服务的例子可以参考网上博文:https://blog.csdn.net/njbling1/article/details/52662936?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7

如果打印机驱动程序已经存在,不会出现报错。

2. 添加端口监视器

    MONITOR_INFO_2 MonitorInfo = {0};
    MonitorInfo.pName = "monitor";
    MonitorInfo.pEnvironment = "Windows x64";
    MonitorInfo.pDLLName = "localmon.dll";//SYSTEM
    if(FALSE == AddMonitor(NULL, 2, (LPBYTE)&MonitorInfo)){
        return FALSE;
    }

添加打印机的dll需要放在SYSTEM32路径下,分别包括localmon、localui、pjlmon,具体代码参照dkk。

如果打印监视器已经安装,AddMonitor会返回False。

3. 添加端口

    if(FALSE == AddPort(NULL, NULL, "monitor"))
    {
        //Error
        return -1;
    }

调用此函数时,会弹出localui中的对话框,但正常的处理程序一般不应让用户手动输入端口名称,可以修改AddPortUI函数,同时需要注意的是:

  • ddklocalmon.dll中有ddklocalui.dll的引用,同样需要修改,才能保证ddklocalui.dll正确被引用。

  • AddPortUI赋值字符串使用AllocSplStr函数。

  • 前面说在替换文件前删除dll可能会删除失败,错误码5,需要如果检查到这种情况,需要多删除几次。

4. 添加驱动

DRIVER_INFO_4 DriverInfo = {0};
    DriverInfo.cVersion = 3;
    DriverInfo.pName = _T("driver");  
    DriverInfo.pEnvironment = _T("Windows x64"); // Win32 x86
    DriverInfo.pDriverPath = _T("unidrv.dll");
    DriverInfo.pDataFile = _T("emf.gpd");  
    DriverInfo.pConfigFile = _T("unidrvui.dll");  
    DriverInfo.pHelpFile = _T("unidrv.hlp");  
    DriverInfo.pDependentFiles = _T("UNIRES.DLL\0STDNAMES.GPD\0\0"); 
    DriverInfo.pMonitorName = NULL; // "PJL monitor"
    DriverInfo.pDefaultDataType = _T("EMF"); // "EMF"
    DriverInfo.pszzPreviousNames = _T("\0\0"); // "OldName1\0OldName2\0\0
​
    if(FALSE == AddPrinterDriver (NULL, 4, (LPBYTE)&DriverInfo)){
        showErrMsg("AddPort");
        return -1;
    }

驱动地址可以通过GetPrintProcessorDirectory函数获取。

BOOL bRet = TRUE;
    CHAR pPrintProcessorDirectory[MAX_PATH];
    DWORD pcbNeeded;
    //获取打印机驱动程序位置
    if(FALSE == GetPrintProcessorDirectory(NULL, "Windows x64", 1, (LPBYTE)&pPrintProcessorDirectory, MAX_PATH, &pcbNeeded)){
        showErrMsg("GetPrintProcessorDirectory");
        return -1;
    }

5. 添加打印机

    PRINTER_INFO_2 PrinterInfo = {0};
​
    PrinterInfo.pPrinterName =  _T("printer 1.0");
    PrinterInfo.pPortName = _T("port");
    PrinterInfo.pDriverName =  _T("driver");
    PrinterInfo.pComment = _T("printer 1.0");
    PrinterInfo.pLocation = _T("Anywhere");
    PrinterInfo.pPrintProcessor = _T("printProcessor");
    PrinterInfo.pDatatype = _TEXT("NT EMF 1.008");
    if(FALSE == AddPrinter (NULL, 2, (LPBYTE)&PrinterInfo)){
        showErrMsg("AddPrinterDriver");
        return FALSE;
    }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值