RTF技术扩展如何实现完美分页打印
RTF技术扩展-如何实现完美的分页打印
摘要:本⽂给出了⼀种完美实现RTF⽂件分页打印的⽅法,并根据此⽅法实现了RTF⽂件的打印预览及打印。通过本⽅法实现的RTF⽂件的WYSIWYG(所见即所得)显⽰、分页预览及分页打印三者在效果上完全⼀致,解决了以前预览与打印存在偏差的问题,⽆论在分页速度和效果上均取得了突破。同时,本⽅法还解决了分页效果与打印机相关的问题,做到了完全的设备⽆关。效果图如下:
关键字:RTF、Rich Text Format、分页、打印。
⼀、背景介绍
RTF⽂件的分页算法⼀致是困扰已久的话题,以前我的⽅法是采⽤逐⾏计算⾏⾼然后再⼿⼯分页的⽅法,该⽅法有很多不⾜之处:
1、正在计算的⾏必须在屏幕可视范围内;
2、每⾏的左缩进位置必须为正数;
3、逐⾏计算采⽤模拟键盘操作进⾏,速度很慢;
4、⼿⼯计算存在⼀些误差;
5、分页效果与打印机相关,导致不同打印机结果不⼀致。
综上⼏点原因,旧的分页算法存在稳定性差和计算不精确等问题,因此分页结果常常出现偏差。寻⼀种稳定可靠、⾼效率的分页算法迫在眉睫。
⼆、新的分页算法简介
新的分页算法其核⼼采⽤以前我翻译的《RichTextBox SDK 参考⼿册》⼀⽂中介绍的⽅法:主要⽅法是通过向Rich Edit控件发送EM_FORMATRANGE消息来将其输出重定向到指定设备,⽐如打印机。当然,也可以指定⼀个⽤于Rich Text⽂本格式化的输出设备,⽐如图⽚框。同时,可以使⽤EM_SETTARGETDEVICE消息来指定⼀个⽤于Rich Text⽂本格式化的⽬标设备。该消息⽤于实现
WYSIWYG(所见即所得)模式,即在该模式下应⽤程序采⽤默认打印机字体规格⽽⾮屏幕字体规格来定位⽂本。这样就实现了RTF⽂本的WYSIWYG(所见即所得)显⽰、打印预览与最终打印。
需要说明的是,如果要保持3种⽅法在结果上的⼀致性,那么采⽤的⽬标设备必须统⼀,这样才能保证
渲染结果的统⼀。我们采⽤屏幕Screen对象来作为⽬标设备,这样就实现了渲染结果与打印机⽆关,避免了不同打印机其分页效果不同的问题。
下⾯对这⼏个消息进⾏详细讲解:
三、相关Windows消息和函数详解
EM_FORMATRANGE 消息
EM_FORMATRANGE消息⽤于为指定设备格式化⼀定范围的⽂本,⽤于Rich Edit控件。
语法:
发送该消息,采⽤如下⽅法调⽤SendMessage 函数:
参数:
wParam
表⽰是否渲染⽂本。如果该参数为⾮0值,⽂本将被渲染;否则,⽂本仅仅被测量(不做实际渲染)。
lParam
指向⼀个FORMATRANGE结构体,该结构体包含输出设备相关信息,或者为NULL⽤于释放⽬标控件所绑定的信息。
该消息返回适合该区域的最后⼀个字符位置,加1。
注释:
该消息通常与EM_DISPLAYBAND消息搭配,⽤于为输出设备诸如打印机等格式化Rich Edit控件中的内容。
⾮常重要的是,在你最后⼀次使⽤该消息后需要为lParam参数指定NULL值来释放所绑定的信息。另外,⼀旦你在某个设备使⽤该消息后,如果需要在不同设备再使⽤该消息,同样你必须先释放所绑定的信息。
消息信息:
参见:
Rich Edit Controls, EM_DISPLAYBAND, FORMATRANGE
FORMATRANGE 结构体
FORMATRANGE结构体包含⽤于Rich Edit控件格式化其输出到指定设备的相关信息。该结构体⽤于EM_FORMATRANGE消息。
结构体信息:
参见:
Rich Edit Controls, EM_FORMATRANGE
EM_DISPLAYBAND 消息
EM_DISPLAYBAND消息⽤于显⽰Rich Edit控件的⼀部分内容,该⽂本采⽤前⾯EM_FORMATRANGE消息所指定的设备来格式化。
语法:
发送该消息,采⽤如下⽅法调⽤SendMessage 函数
lResult = SendMessage( // 返回结果值 LRESULT
(HWND) hWndControl, // ⽬标控件句柄
(UINT) EM_DISPLAYBAND, // 消息ID
(WPARAM) wParam, // = (WPARAM) () wParam;
(LPARAM) lParam // = (LPARAM) () lParam;
);
参数:
wParam
该参数不使⽤;必须等于0。
lParam
指向⼀个RECT结构体所表⽰的设备显⽰区域。
返回值:
如果操作成功,则返回True;否则返回False。
⽂本及组件对象模型(COM)对象将被该矩形所裁剪。程序不需要设置裁剪区域。消息信息:
参见:
Rich Edit Controls, EM_FORMATRANGE, RECT
GetDeviceCaps函数
GetDeviceCaps函数⽤于获取指定设备的设备描述信息。
int GetDeviceCaps(
HDC hdc, // DC句柄
int nIndex// 项⽬索引值
);
参数:
hdc
[in] DC句柄。
nIndex
[in] 指定需要返回的项⽬。可以取下⾯的值:
TECHNOLOGY 设备⼯艺。取值可以为:
DT_PLOTTER ⽮量绘图仪
DT_RASDISPLAY 光栅显⽰器
DT_RASPRINTER 光栅打印机
DT_RASCAMERA 光栅照相机
DT_CHARSTREAM 字符流
DT_METAFILE 图元⽂件
DT_DISPFILE 显⽰⽂件
如果hdc参数指向⼀个增强图元⽂件的DC句柄,设备⼯艺将参
照CreateEnhMetaFile函数所指定的设备。确定是否是增强
图元⽂件的DC,可以使⽤GetObjectType函数。
HORZSIZE 物理屏幕宽度,单位:毫⽶。
VERTSIZE 物理屏幕⾼度,单位:毫⽶。
HORZRES 屏幕宽度,单位:象素(pixels)。
VERTRES 屏幕⾼度,单位:(光栅)⾏。
LOGPIXELSX 沿屏幕宽度的每个逻辑英⼨的象素值。在多显⽰器系统中,所有
显⽰器的这个值均相同。
LOGPIXELSY 沿屏幕⾼度的每个逻辑英⼨的象素值。在多显⽰器系统中,所有
显⽰器的这个值均相同。
BITSPIXEL 每个象素点的相邻颜⾊位数。
PLANES 颜⾊平⾯数。
NUMBRUSHES 设备相关画刷(BRUSH)数⽬。
NUMPENS 设备相关画笔(PEN)数⽬。
NUMFONTS 设备相关字体数⽬。
NUMCOLORS 设备颜⾊表的⼊⼝总数,如果设备的颜⾊深度⼩于每象素8位时
可⽤。⼤于该⾊深时,返回-1。
ASPECTX 绘制线条时的相对象素宽度。
ASPECTY 绘制线条时的相对象素⾼度。
ASPECTXY 绘制线条时的相对对⾓线象素宽度。
PDEVICESIZE 保留。
CLIPCAPS 设备剪切性能标志,如果设备可以剪切为矩形,返回1;否则为
0。
SIZEPALETTE 设备调⾊板的⼊⼝总数。该索引值只能在设备驱动在
RASTERCAPS等于RC_PALETTE位并且在兼容16位
Windows时才可⽤。
NUMRESERVED 系统调⾊板的保留⼊⼝总数。该索引值只能在设备驱动在
RASTERCAPS等于RC_PALETTE位并且在兼容16位
Windows时才可⽤。
分页预览
COLORRES 设备的实际颜⾊分辨率,单位:BPP(位/象素)。该索引值只能
在设备驱动在RASTERCAPS等于RC_PALETTE位并且在兼容
16位Windows时才可⽤。
PHYSICALWIDTH 对于打印设备⽽⾔,表⽰物理页宽,采⽤设备单位。例如,打印
机设为600 dpi,8.5-x11-英⼨纸张,那么它的物理宽度值为
5100设备单位。
注:物理页总是⼤于页⾯的可打印区域,不会⼩于它。PHYSICALHEIGHT 对于打印设备⽽⾔,表⽰物理页⾼,采⽤设备单位。例如,打印
机设为600 dpi,8.5-x11-英⼨纸张,那么它的物理⾼度值为
6600设备单位。
注:物理页总是⼤于页⾯的可打印区域,不会⼩于它。PHYSICALOFFSETX 对于打印设备⽽⾔,表⽰从物理页的左边缘到可打印区域的左边
缘的距离,采⽤设备单位。例如,打印机设为600 dpi,8.5-x11-
英⼨纸张,那么它不能在左边距⼤于0.25英⼨的纸张上打印,
因为此时它的⽔平物理偏移量为150个设备单位。PHYSICALOFFSETY 对于打印设备⽽⾔,表⽰从物理页的上边缘到可打印区域的上边
缘的距离,采⽤设备单位。例如,打印机设为600 dpi,8.5-x11-
英⼨纸张,那么它不能在上边距⼤于0.5英⼨的纸张上打印,因
为此时它的垂直物理偏移量为300个设备单位。VREFRESH Windows NT/2000/XP:对显⽰设备⽽⾔,表⽰当前的垂直刷新率,单位:Hz。
垂直刷新率为0或者1,表⽰采⽤显⽰硬件的默认刷新率。
This default rate is typically set by switches on a display
card or computer motherboard, or by a configuration
program that does not use display functions such as
ChangeDisplaySettings.
SCALINGFACTORX 打印机的X-轴缩放⽐例。
SCALINGFACTORY 打印机的Y-轴缩放⽐例。
BLTALIGNMENT Windows NT/2000/XP: Preferred horizontal drawing
alignment, expressed as a multiple of pixels. For best
drawing performance, windows should be horizontally
aligned to a multiple of this value. A value of zero
indicates that the device is accelerated, and any
alignment may be used.
SHADEBLENDCAPS Windows 98/Me, Windows 2000/XP:表⽰设备的阴影
及混合特性。参见注释的说明。
SB_CONST_ALPHA Handles the
SourceConstantAlpha
member of the
BLENDFUNCTION structure,
which is referenced by the
blendFunction parameter of the
AlphaBlend function.
SB_GRAD_RECT Capable of doing GradientFill
rectangles.
SB_GRAD_TRI Capable of doing GradientFill
triangles.
SB_NONE Device does not support any of
these capabilities.
SB_PIXEL_ALPHA Capable of handling per-pixel
alpha in AlphaBlend.
SB_PREMULT_ALPHA Capable of handling