dedecms织梦内容管理系统    
首页 | java | C/C++ | PHP | 操作系统 | ajax | 脚本编程 | 安全技术 | 本站下载页 | flex | CRM | 专题 | QQ群 | 测试中心 | 会员中心 | 积分规则
  当前位置:主页>C/C++>C/C++技术资料>文章内容
Windows下实时行式打印系统设计
来源:编程爱好者     作者:    

众所周知,Windows系统的页式打印系统有许多好的特性,比如所见即所得、设备无关等等。但是,在一些实时性要求很高的工业控制系统中,需要将系统随机出现的信息实时地打印出来,要求来一行打一行,而不能来一行打一页,而Windows系统的页式打印系统却很难满足这样的应用需求。鉴于这个原因,为了满足实时系统的打印要求,有必要设计一个新的实时行式打印系统。下面详细介绍如何在Windows 2000/NT上实现这样一个系统。

总体设计

实时系统的基本要求是实时性。本文采用以共享内存为中转的打印假脱机技术,所有的打印操作在内存中提交完成,保证了应用系统对打印操作的及时响应。



另一要求是设备无关性,使提交打印的操作尽可能地做到与设备无关。程序不会因为打印机设备的不同,导致程序有较大的修改。如果打印机不同,只需加载相应的打印驱动程序即可。

总体上实时行式打印系统的设计分为两个部分,一个是以内存为基础的打印假脱机部分的设计;另一个是实时打印驱动层部分的设计。系统的概要设计图如下:

实时行打印假脱机部分

这个部分的基本原理是使用一个基于共享内存技术的先入先出队列,用来存储其他应用程序提交的实时打印请求。打印进程从先入先出的环形队列取出打印请求,经过必要的处理之后,提交给打印驱动部分,由打印驱动部分负责驱动相应的打印机输出。

为满足其他应用程序提交打印请求的需要,在此使用了Windows操作系统提供的共享内存技术。共享内存是进程之间通信时用的一种技术,是一种更为标准、更为核心的技术,而且它在不同操作系统平台之间的移植性也比较好(Unix系列也有这种技术)。另一个好处是提高了实时性能,因为避免了多次内存复制的系统空间和时间上的开销。

Windows系统中与创建共享内存相关的系统有CreateFileMapping和MapViewOfFile。

第一个用来在系统中创建一块共享内存,并返回共享内存的句柄。其参数说明如下:

HANDLE WINAPI CreateFileMapping (

HANDLE hFile,

LPSECURITY _ATTRIBUTES lpsa,

DWORD dwPROTECT,

DWORD dwMaxSizeHigh,

DWORD dwMaxSizeLow,

LPCSTR lpszMapName);

hFile为文件句柄,要创建共享内存,该参数必须为0xffffffff; lpsa为安全结构; dwPROTECT是页保护标识,如PAGE_READONLY,PAGE_READWRITE等; dwMaxSizeHigh和dwMaxSizeLow共同定义了共享内存的尺寸,分别为共享内存大小的高32位和低32位; lpszMapName定义了共享内存的名字,必须确保其在系统范围内的惟一性。

第二个用来将创建的共享内存映射到调用进程的地址空间,并返回该地址空间的首地址。其参数说明如下:

MapViewOfFile(

HANDLE hFileMappingObject,

DWORD dwDesired,

DWORD dwFileOffsetHigh,

DWORD dwFileOffsetLow,

DWORD dwNumberOfBytesToMap);

hFileMappingObject定义了CreateFileMapping

返回的共享内存句柄; dwDesiredAccess定义了共享内存的访问模式,如:FILE_MAP_ALL_

等; dwFileOffsetHigh和dwFileOffsetLow共同定义了共享内存起始位置的偏移量,分别为该偏移量的高32位和低32位,通常情况下二者都为零值; dwNumberOfBytesToMap定义了映射到本进程地址空间的共享内存的字节数,如果该值为零,则映射所有的共享内存。

这里定义实时打印系统所用共享内存的名字为g_szRealTimePrintSystemShareMemName。REALTIMEPRINT_DB是一个结构类型,定义了共享内存的内部结构,它是实时打印系统的数据核心,包括了要打印的信息、写入指针、读出等信息。 具体步骤如下(示意性代码):

REALTIMEPRINT_DB *g_pRealTimePrint-

SystemDb ;

HANDLE hShareMemHandle = NULL;

DWORD dwRTPSShmLen = sizeof(REALTIMEPRINT_DB);

//REALTIMEPRINT_DB 结构的长度

hShareMemHandle =

//生成共享内存,并返回其句柄

CreateFileMapping((HANDLE)0xffffffff,NULL,PAGE_READWRITE,0,

dwRTPSShmLen, //共享内存的大小 “g_szRealTimePrintSystemShareMemName”);

g_pRealTimePrintSystemDb =

//将共享内存映射到本进程的地址空间

(REALTIMEPRINT_DB *)MapViewOfFile(hShareMemHandle,FILE_MAP_ALL_,0,0,0);

在获得了共享内存的地址后,任何调用进程都可以将要打印的信息写到该共享内存中,供打印服务进程打印输出。基于系统实时性和效率方面的考虑,使用环形先入先出队列(FIFO),在此不再详述。

通常情况下,将上述功能封装成两个类,生成动态连接库供程序调用。一个类提供给需要提交打印信息请求的应用程序使用; 另一个类提供给响应打印请求的实时打印服务进程使用。在类中屏蔽以上算法细节和数据细节。

供提交打印信息请求的应用程序调用的类至少要提供如下操作:

class RealTimePrintSystemClnt

{//其他的数据和方法声明

public:

BOOL IsWorking();

//打印机是否正在工作?

/*实时打印系统的FIFO队列是否已满?如果返回为TRUE,表示实时打印系统已经没有空闲响应程序的打印请求,应用程序要等到该返回值为FALSE时,重发打印请求。*/

BOOL IsFull();

/*程序请求实时打印操作。pData 表示要打印的实时信息,由ASCII字符或者汉字字符组成的字符串。dwDataLen 是要打印的实时信息的字符长度。crColor 表示使用什么颜色打印,如果使用彩色喷墨打印机将可以打印彩色,默认值为0,表示黑色。pPrinterName 表示该打印请求将在哪一个打印机上打印输出,默认值为NULL,表示实时打印系统的默认打印机。返回值是实际提交给实时打印系统的信息长度,该值如果等于dwDataLen 则表示该请求已经完全提交成功,如果等于零值则表示该请求没有被完整提交,应用程序要再次提交该请求。*/

DWORD Request(LPCSTR pData,DWORD dwDataLen,COLORREF crColor=0,LPCSTR pPrinterName=NULL);

//其他的数据和方法声明

};

供响应打印请求的服务进程使用的类至少要提供如下操作:

class RealTimePrintSystemServ

{//其他的数据和方法声明

//UnionPrintSystem是打印驱动层的封装类,实时打印系统使用它来打印实时信息

UnionPrintSystem *m_pUnionPrintSystem;

public:

/*获得当前FIFO队列中的打印请求个数*/

DWORD GetRequstNum();

/*获得一个打印请求的数据,pData得到数据的首地址,dwDataLen得到数据的长度,crColor 得到打印颜色,pPrinterName 得到执行请求打印机的名字。返回值为TRUE,表示成功,为FALSE表示失败。*/

BOOL GetRequest(unsigned char ** pData,DWORD &dwDataLen,COLORREF &crColor,LPSTR pPrinterName);

/*实时打印系统的打印线程。在该打印线程中,要不断检测是否有打印请求,如果有打印请求,则取出打印请求,提交给打印驱动层,然后由打印驱动层驱动不同的打印机将请求在纸上打印出来。关于打印驱动层下面讲述。*/

static DWORD WINAPI rtPrintThread(LPVOID lpParameter);

};

打印驱动部分

为了实现系统设备无关性的要求,设计了打印统一驱动层部分。这样一旦打印机设备更改,应用程序只需加载新的打印机设备驱动即可,不会导致打印机系统程序和用户程序的修改,使系统具有较好的稳定性、兼容性和可扩充性。

[1]  

 

 

上一篇:利用WebBrowser控件创建自己的浏览器   下一篇:VC下打印机的使用
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
用户名: 新注册) 密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论
  热点文章
·C语言数组排序小结
·Python 与 C++ 程序的简单实例对
·c++ 数组与指针
·C++中的内存管理(new、delete、
·如何用C语言开发DSP嵌入式系统
·如何用C语言开发DSP嵌入式系统
·Linux下C语言编程
·学习arm的话先看哪本书?
·C++初学者应该关心的优秀图书一
·利用C语言小程序来解决大问题
·用C语言写PHP扩展的步骤
·用C语言扩展PHP功能
  相关文章
·利用WebBrowser控件创建自己的浏
·VC下打印机的使用
·VC编程实现文本语音转换
·获取有关显示器、鼠标及系统的配
·用VC存取数据库中的大对象
·如何模拟《WORD》的窗口形式
·用Sockets接收和转换数字和字符
·OICQ登录号码清除器实现原理
·利用模板技术简化VC中的代码
·用VC 6.0实现串行通信的三种方法
·如何自动截获输出到打印机的文本
·FMD开发文集 -- CArchive原理
  相关信息
copy right @ 百家拳软件项目研究室 2007 辽ICP备07011763