虚拟打印的实现-DDK部分

简介:
今天在整理我以前开发的东西的时候,发现我3年前写的一个虚拟打印的产品代码。想想好久也没有碰过这一块了,今天就来写一写虚拟打印的实现吧。
虚拟打印主要用于将各种文档转换成为各种图形,例如将一个doc文件转换成一个BMP图。我在实现虚拟打印的时候,使用了DDKDELPHI的一些东西。它们的基本操作我在这里就不说了。
今天的部分我先写一下如何对打印机驱动中的DLL改造,让打印机打印的时候可以调用我们的设置界面,并且当系统生成一个SPL文件以后,我们如何调用我们自己编写的DLL来处理这个SPL文件。
DDK(WIN2000)里面有一个例子genprint,它是一个打印机驱动。只要我们在这个例子的代码中进行修改就可以实现我上面说的功能了。
首先打开genprint目录中的winprint.c文件。在这个文件中可以找到函数PrintDocumentOnPrintProcessor,这个函数的注释是“是一个打印任务从缓存池中发送到一个打印机中”也就是说调用这个函数,系统就可以将一个打印任务生成一个SPL文件。
现在我们对它进行改造。首先我们要达到的目的是:当打印的时候弹出一个设置对话框。假定我们已经使用DELPHI开发出了一个含有界面的DLL。这个时候我们加入如下代码:
// 调用设置传真信息的变量
         HINSTANCE hLibraryfax;
         FARPROC lpFunc_FAX;
         BOOL ReValues=FALSE;
        
                   if (pDocumentName!=NULL)
                   {
                            hLibraryfax=LoadLibrary(L"SetPrint.dll");
                            if (hLibraryfax)
                            {
                                     lpFunc_FAX=GetProcAddress(hLibraryfax,"SetFax");
                                     if (lpFunc_FAX!=(FARPROC)NULL)
                                      {
                                               FileDir=(char *)lpFunc_FAX();
                                               if (strcmp(FileDir,"")!=0)
                                               {
                                                        ODS(("FileDir %s\n",FileDir));
                                                        varJudge=TRUE;
                                               }
                                               else
                                               {
                                                        ODS(("ReValues 为假 \n"));
                                                        varJudge=FALSE;
                                               }
                                     }
                                     else
                                     {
                                               varJudge=FALSE;
                                     }
 
                            }
                            else
                            {
                                     varJudge=FALSE;
                            }
                   }
                   else
                   {
                            varJudge=FALSE;
                   }
                   FreeLibrary(hLibraryfax);
        
      
上面的代码会VC的朋友应该都可以看懂,它是将含有设置界面的DLL加载,并调用它来进行设置。
通过上面的代码我们在打印的时候就会发现当任务加载以后,会弹出我们编写的DLL界面。
第二:当我们设置好后,下来的工作就是将系统产生的SPL文件转换成一个BMP文件。
这个过程我们需要分成两步来做,
1:将SPL文件转换成一个EMF文件。
2:将EMF文件转换成一个BMP文件。
调用这个转换DLL的代码如下:
 
// 调用动态库使用的变量
HINSTANCE hLibrary;
FARPROC lpFunc_ONE,lpFunc_TWO;
BOOL SPLToEMF_J=FALSE;
BOOL EMFTOBMP_J=FALSE;
BOOL JUDGE=FALSE;
char *FileDir;
 
 
 
check:        
                   ODS((" 调用转换 \n"));
                   //if (pDocumentName!=NULL&&varJudge)
                   if (pDocumentName!=NULL)
                   {
                            ODS((" 开始调用 \n"));
                            hLibrary=LoadLibrary(L"Print_Dll.dll"); // 处理的 DLL
                            if (hLibrary)
                            {
                                     ODS((" 加载成功 \n"));
                                     lpFunc_ONE=GetProcAddress(hLibrary,"SPLToEMF");
                                     if((lpFunc_ONE!=(FARPROC)NULL))
                                     {
                                               ODS((" 加载函数成功 \n"));
                                               SPLToEMF_J=(*lpFunc_ONE)();
                                               if (SPLToEMF_J)
                                               {
                                                        lpFunc_TWO=GetProcAddress(hLibrary,"EMFTOBMP");
                                                        if (lpFunc_TWO!=(FARPROC)NULL)
                                                        {
                                                                 EMFTOBMP_J=(*lpFunc_TWO)();
                                                                 if (EMFTOBMP_J)
                                                                 {
                                                                           ODS((" 返回真 \n"));
                                                                           JUDGE=TRUE;
                                                                 }
                                                                 else
                                                                 {
                                                                           JUDGE=FALSE;
                                                                           ODS(("EMFToBMP 函数返回 FALSE\n"));
                                                                 }
                                                        }
                                                        else
                                                        {
                                                                 JUDGE=FALSE;
                                                                 ODS(("EMFToBMP 函数返回错误 \n"));
                                                        }
                                               }
                                               else
                                               {
                                                        JUDGE=FALSE;
                                                        ODS(("EMFToBMP 函数加载错误 \n"));
                                               }
                                     }
                                     else
                                     {
                                               JUDGE=FALSE;
                                               ODS((" 函数加载错误 \n"));
                                     }
                            }
                            else
                            {
                                     JUDGE=FALSE;
                                     ODS((" 加载错误 \n"));
                            }
                   }
                   else
                   {
                            JUDGE=FALSE;
                   }
                   FreeLibrary(hLibrary);
        
这样我们就实现了在打印的时候弹出一个设置界面,并将打印的任务转换成一个 BMP 文件的目的。
下面我把我写的这个函数的完整代码贴出,希望对大家有所帮助。
 
*******************************************************************
    P r i n t D o c u m e n t O n P r i n t P r o c e s s o r
 
    Routine Description: //是一个打印任务从缓存池中发送到一个打印机中
 
    Arguments:
        hPrintProcessor //打印机的句柄
        pDocumentName   //需要打印的文档的名称
 
    Return Value:
        TRUE  if successful
        FALSE if failed - GetLastError() will return reason
*******************************************************************
--*/
BOOL
PrintDocumentOnPrintProcessor(
    HANDLE  hPrintProcessor,
    LPWSTR  pDocumentName
)
{
    PPRINTPROCESSORDATA pData;
    DWORD   ProcessID;
    HANDLE  processhandle;
    HWND    hwnd;
   
    BOOL varJudge=FALSE;
    //调用动态库使用的变量
    //HANDLE hLibrary;
    HINSTANCE hLibrary;
    FARPROC lpFunc_ONE,lpFunc_TWO;
    BOOL SPLToEMF_J=FALSE;
    BOOL EMFTOBMP_J=FALSE;
    BOOL JUDGE=FALSE;
    char *FileDir;
   
 
    //调用设置传真信息的变量
    HINSTANCE hLibraryfax;
    FARPROC lpFunc_FAX;
    BOOL ReValues=FALSE;
    try
    {
        if (pDocumentName!=NULL)
        {
            hLibraryfax=LoadLibrary(L"SetPrint.dll");
            if (hLibraryfax)
            {
                lpFunc_FAX=GetProcAddress(hLibraryfax,"SetFax");
                if (lpFunc_FAX!=(FARPROC)NULL)
                {
                    //ReValues=(*lpFunc_FAX)();
                    //strcpy(FileDir,(*lpFunc_FAX)());
                    //FileDir=(*lpFunc_FAX)();
                    FileDir=(char *)lpFunc_FAX();
                    //if (ReValues)
                    if (strcmp(FileDir,"")!=0)
                    {
                        ODS(("FileDir %s\n",FileDir));
                        varJudge=TRUE;
                    }
                    else
                    {
                        ODS(("ReValues为假\n"));
                        varJudge=FALSE;
                    }
                }
                else
                {
                    varJudge=FALSE;
                }
 
            }
            else
            {
                varJudge=FALSE;
            }
        }
        else
        {
            varJudge=FALSE;
        }
        FreeLibrary(hLibraryfax);
    }
    except(1)
    {
        if (hLibraryfax!=NULL)
        {
            FreeLibrary(hLibraryfax);
        }
        varJudge=FALSE;
    }
   
    //varJudge=TRUE;
    ODS(("判断varJudge\n"));
    if (varJudge)
    {
        //ODS(("varJudge为真\n"));
        /**
            Make sure the handle is valid and pick up
            the Print Processors data area.
        **/
        //判断打印机的句柄是存在的并将句柄赋值给pData(同时给pData开辟内存空间)  将下面的函数
        if (!(pData = ValidateHandle(hPrintProcessor))) {
 
            ODS(("失败\n"));
            return FALSE;
        }
       
        /**
            Print the job based on its data type.
        **/
        //机遇它的数据类型打印一个任务
 
        switch (pData->uDatatype) {
 
        case PRINTPROCESSOR_TYPE_EMF_50_1:
        case PRINTPROCESSOR_TYPE_EMF_50_2:
        case PRINTPROCESSOR_TYPE_EMF_50_3:
            ODS(("调用PrintEMFJob函数\n"));
            //return PrintEMFJob( pData, pDocumentName ); //调用打印一个EMF任务的函数
            //return TRUE;
            goto check;
            break;
 
        case PRINTPROCESSOR_TYPE_RAW:
            ODS(("调用PrintRawJob函数\n"));
            return PrintRawJob(pData, pDocumentName, pData->uDatatype);//调用打印一个
            break;
 
        case PRINTPROCESSOR_TYPE_TEXT:
            ODS(("调用PrintTextJob函数\n"));
            return PrintTextJob(pData, pDocumentName);//调用打印一个文本任务的函数
            break;   
        } /* Case on data type */
    }
        /** Return success **/
check: 
    try
    {
        ODS(("调用转换\n"));
        if (pDocumentName!=NULL&&varJudge)
        //if (pDocumentName!=NULL)
        {
            ODS(("开始调用\n"));
            hLibrary=LoadLibrary(L"Print_Dll.dll");
            if (hLibrary)
            {
                ODS(("加载成功\n"));
                lpFunc_ONE=GetProcAddress(hLibrary,"SPLToEMF");
                if((lpFunc_ONE!=(FARPROC)NULL))
                {
                    ODS(("加载函数成功\n"));
                    SPLToEMF_J=(*lpFunc_ONE)();
                    if (SPLToEMF_J)
                    {
                        lpFunc_TWO=GetProcAddress(hLibrary,"EMFTOBMP");
                        if (lpFunc_TWO!=(FARPROC)NULL)
                        {
                            EMFTOBMP_J=(*lpFunc_TWO)();
                            if (EMFTOBMP_J)
                            {
                                ODS(("返回真\n"));
                                JUDGE=TRUE;
                            }
                            else
                            {
                                JUDGE=FALSE;
                                ODS(("EMFToBMP函数返回FALSE\n"));
                            }
                        }
                        else
                        {
                            JUDGE=FALSE;
                            ODS(("EMFToBMP函数返回错误\n"));
                        }
                    }
                    else
                    {
                        JUDGE=FALSE;
                        ODS(("EMFToBMP函数加载错误\n"));
                    }
                }
                else
                {
                    JUDGE=FALSE;
                    ODS(("函数加载错误\n"));
                }
            }
            else
            {
                JUDGE=FALSE;
                ODS(("加载错误\n"));
            }
        }
        else
        {
            JUDGE=FALSE;
        }
        FreeLibrary(hLibrary);
    }
    except(1)
    {
        if (hLibrary!=NULL)
        {
            FreeLibrary(hLibrary);
        }
    }
    return JUDGE;  //返回
}
 
 
下次我将写一下如何在Print_Dll.dll中实现将一个SPL文件转换成一个EMF文件。
本文转自狗窝博客51CTO博客,原文链接http://blog.51cto.com/fxh7622/47963如需转载请自行联系原作者

fxh7622
相关文章
音视频开发: ffmpeg采集桌面屏幕、摄像头保存为视频
音视频开发: ffmpeg采集桌面屏幕、摄像头保存为视频
1273 0
音视频开发: ffmpeg采集桌面屏幕、摄像头保存为视频
|
12月前
|
存储 监控 NoSQL
MongoDB的水平扩展能力
MongoDB的水平扩展能力
161 5
|
存储 弹性计算 监控
利用阿里云云产品进行项目成本节约的实践
本文分享了利用阿里云降低成本的实践经验,主要通过选择合适的计费模式(如按量付费、包年包月和抢占式实例)、优化资源配置(弹性伸缩、资源监控与调整、适配存储方案)、利用优惠和成本管理工具(预留实例券、成本预警、优惠活动)以及案例分析,实现云计算成本的有效控制。通过这些策略,企业在保证灵活性和扩展性的同时,能更好地管理云服务成本,提高项目经济效益。
810 4
|
Python
Python中使用`requests`库进行异常处理与调试
【4月更文挑战第12天】在Python的网络编程中,使用`requests`库发送HTTP请求时,经常会遇到各种异常情况,如网络连接错误、请求超时、服务器错误等。为了确保程序的健壮性和稳定性,我们需要对这些异常进行妥善处理,并进行必要的调试。本文将详细介绍如何在Python中使用`requests`库进行异常处理与调试。
1271 2
|
算法 程序员 C++
【Python 基础教程 运算符06】Python3运算符超详细解析:全面入门教程,初学者必读
【Python 基础教程 运算符06】Python3运算符超详细解析:全面入门教程,初学者必读
316 2
|
小程序 前端开发 数据安全/隐私保护
微信小程序开发笔记—设置页面密码
本文主要介绍了微信小程序实现设置页面密码的功能实现
481 0
|
缓存 Java 容器
九.Spring源码剖析-Autowired自动注入原理
这篇文章接上一篇文章属性注入讲一讲 @Autowired 注解的实现源码,这个也是面试被问的比较多的。
|
XML 存储 Java
Neo4j的springboot的简单实现
# 引言 今天带来通过springboot来操作neo4j的教程。 # pom.xml的依赖 ``` <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.
Neo4j的springboot的简单实现