您的位置:首页 > 运维架构 > Linux

Windows 打印选项设置在 Linux 平台上的一种移植方法

2006-12-29 21:20 706 查看
级别: 初级

龚 奕平 (gongyp@cn.ibm.com), IBM 中国软件开发中心 WPLC 部,软件工程师

2006 年 12 月 21 日

移植是实现传统高层应用程序跨平台运行的一项核心技术。打印子系统移植是应用程序移植的重要组成部分。实现打印选项设置模块在不同平台上的用户接口UI(User Interface)转换是实现打印子系统移植过程中的一项核心技术。本文将重点阐述一种使用GNOME Print在Linux平台上实现Windows打印选项设置的移植方法。
本文第一节将简要介绍Windows平台上的打印设置和相关数据结构;第二节介绍Linux平台上GNOME Print的打印设置和相关数据结构;第三节介绍GNOME Print打印设置的移植架构;第四节介绍移植的细节;第五节则进一步讨论Linux平台上GNOME Print以外的打印设置方法;本文的简要总结在第六节中给出。

1. Windows打印选项设置

图1 Windows系统打印设置对话框



在Windows平台上,用户可以通过Windows系统打印设置对话框(如图1所示)来完成对打印选项的设置。程序员可以通过调用Windows API DocumentProperties() 来获得该系统打印设置对话框。图1为一款EPSON打印机的打印设置对话框,用户可以通过该对话框来设置打印属性,如打印纸张的大小和纸张的方向等等。该对话框是Windows为用户提供的一个友好的前台UI界面;与之相对应的后台核心数据则被存储在Windows标准数据结构DEVMODE中。DEVMODE结构的原形定义如下:

typedef struct _devicemode {
BCHAR  dmDeviceName[CCHDEVICENAME];
WORD   dmSpecVersion;
WORD   dmDriverVersion;
WORD   dmSize;
WORD   dmDriverExtra;
DWORD  dmFields;
union {
struct {
short dmOrientation; //打印纸张方向
short dmPaperSize;   //打印纸张名称
short dmPaperLength; //打印纸张长度
short dmPaperWidth;  //打印纸张宽度
short dmScale;
short dmCopies;
short dmDefaultSource;
short dmPrintQuality;
};
POINTL dmPosition;
DWORD  dmDisplayOrientation;
DWORD  dmDisplayFixedOutput;
};
…
}

在此简要介绍DEVMODE结构的三个重要参数:打印纸张名称,打印纸张方向,和打印纸张大小(长度和宽度)。其他参数由于篇幅限制,在此不作逐一解析,有兴趣的读者请参考MSDN。以下以n_DevMode为例进行说明:

DEVMODE n_DevMode;


(1) 打印纸张名称在Windows中被定义为:

n_DevMode.dmPaperSize


Windows将纸张名称预定义为一系列整数宏,如DMPAPER_LETTER,DMPAPER_A4等等。

(2) 打印纸张方向在Windows中被定义为:

n_DevMode.dmOrientation


该参数可以取如下两个值:DMORIENT_PORTRAIT表示纸张方向为纵向;DMORIENT_LANDSCAPE表示纸张方向为横向。

(3) 打印纸张的长度和宽度在Windows中被定义为:

n_DevMode.dmPaperLength
n_DevMode. dmPaperWidth


这两个参数的单位为0.1毫米。




2. Linux GNOME Print打印选项设置

在Linux平台上,可以使用GNOME Print来实现打印设置功能。GNOME Print是GNOME支持Linux打印的模块。GNMOE Print涵盖了打印实现的各个方面,比如设置打印功能,生成打印文档,设置打印字体等等。以下仅针对GNOME Print中和设置打印选项相关的功能进行阐述。

图2 Linux GNOME Print系统打印设置对话框



Linux GNOME Print系统打印设置对话框如图2所示。该对话框是GNOME Print打印设置的前台UI界面。在GNOME Print中,打印设置的后台数据被封装在结构GnomePrintConfig中。同时,GNOME Print还提供了一系列函数,如gnome_print_config_set()和gnome_print_config_get(),来访问该结构。详细内容请参考第四小节。

Linux GNOME Print系统打印设置和Windows系统打印设置在数据接口和定义上是完全不同的。必须通过数据转换才能实现他们之间的互操作。这就是移植的核心,也是本文重点阐述的内容。




3. GNOME Print打印选项设置移植结构

图3 GNMOE Print打印选项设置移植结构



图3展示了在Linux平台上实现Windows打印选项设置移植的基础结构。从图中可以看出,打印选项设置移植的核心就是实现不同平台数据接口的转换:即Windows平台打印选项设置结构DEVMODE和Linux GNOME Print打印选项设置结构GnomePrintConfig之间的转换。下一小节将详细阐述这些数据结构之间的转换细节。




4 GNOME Print打印设置移植细节

为了使用Linux GNOME Print实现打印设置,通常要引入下列头文件:

#include <libgnomeprintui/gnome-print-dialog.h>
#include <libgnomeprint/gnome-print.h>

在GNOME Print中,和前台UI对话框的相关的结构和接口被定义在第一个头文件中;而和后台数据处理相关的结构和接口则被定义在第二个头文件中。

使用GNMOE Print实现打印设置移植的流程如图4所示。以下将逐一讨论这个流程中的各个细节。

图4 GNMOE Print打印设置移植流程



4.1 设置GNOME Print打印作业

启动GNOME Print打印设置的第一步是使用gnome_print_job_new() 来创建一个打印作业,即GnomePrintJob。每一个GnomePrintJob都和一个打印作业设置,即GnomePrintConfig,相关联。事实上,使用GNOME Print设置打印选项就是通过设置GnomePrintConfig来完成的。将参数NULL传递给gnome_print_job_new() 意味着创建一个新的GnomePrintJob,并用默认值设置和它关联的GnomePrintConfig。

GnomePrintJob * pJob;
GnomePrintConfig *pConfig;
pJob = gnome_print_job_new(NULL);
if (!pJob)
return 0;

GnomePrintConfig的默认值可以通过接下来的调用gnome_print_job_get_config() 来获得:

pConfig = gnome_print_job_get_config(pJob);
if (!pConfig)
return 0;

4.2 设置GNOME Print打印参数

得到GnomePrintConfig后,用户可以根据需要修改打印作业设置。如下代码设置了三个重要的打印参数:

1. 打印纸张名称:A4。

2. 打印纸张方向:R0。在GNOME Print中,R0和R180表示打印纸张方向为纵向;R90和R270则表示打印纸张方向为横向。

3. 打印纸张长度单位表示:cm(厘米)。长度可以使用厘米或英寸(inch)等单位来表示。在此时使用cm以方便移植。

//设置参数变量
const char *pPaperName     = "A4";
const char *pPaperOrientation = "R0";
const char *pPreferedUnit   = "cm";
//设置纸张名称
gnome_print_config_set( pConfig,
(const guchar*)GNOME_PRINT_KEY_PAPER_SIZE,
(const guchar*)pPaperName );
//设置打印纸张方向
gnome_print_config_set( pConfig,
(const guchar*)GNOME_PRINT_KEY_PAPER_ORIENTATION,
(const guchar*)pPaperOrientation )
//设置纸张大小
gnome_print_config_set( pConfig,
(const guchar*)GNOME_PRINT_KEY_PREFERED_UNIT,
(const guchar*)pPreferedUnit) );

注意:以上代码是通过函数gnome_print_config_set()来改变GnomePrintConfig设置的。事实上,每个GNMOE Print系统打印设置对话框(图2)都会和一个GnomePrintConfig结构相关联。用户对该对话框选项的改变都有可能影响到后台GnomePrintConfig结构的相关数值。更为具体的说,当用户点击图2中"确定"按钮后,与之相连的GnomePrintConfig结构的相关数值就会根据用户的选择被自动更新。

4.3 获取GNOME Print打印参数和参数转换

在用户设置完打印参数之后,移植程序就需要读取这些参数的具体数值,并把这些数值转化成Windows的数据结构。GNOME Print提供了一系列函数,如gnome_print_config_get()和gnome_print_config_get_page_size(),来读取打印设置数值。

4.3.1 读取打印纸张名称

移植程序可以通过函数gnome_print_config_get() 来获取当前打印纸张的名称。

char *pPaperName;
pPaperName = (char*)gnome_print_config_get(
pConfig,
(const guchar*)GNOME_PRINT_KEY_PAPER_SIZE);
if (!pPaperName)
return 0;

在此,GNMOE Print返回的纸张名称被存储在字符串变量pPaperName中。当然,这里得到的打印纸张名称和Windows定义的打印纸张名称是不一致的:GNOME Print获得的打印纸张名称通常为"A4"或"B5"这样具有明显含义的字符串;而Windows则将纸张的名称定义为一系列宏存储在结构n_DevMode.dmPaperSize中。因此移植程序还需根据规范进行相应转换。

4.3.2 读取打印纸张尺寸

移植程序可以通过函数gnome_print_config_get_page_size()可以获取当前打印纸张的长度(PaperLength_pt)和宽度(PaperWidth_pt)。

gdouble PaperWidth_pt, PaperLength_pt;
gnome_print_config_get_page_size(
pConfig,
&PaperWidth_pt,
&PaperLength_pt);

从GNOME Print中获取的纸张尺寸是以1/72英寸为单位的;而Windows则把纸张尺寸以0.1毫米为单位存储在结构DEVMODE. dmPaperWidth和DEVMODE.dmPaperLength中。因此,移植程序需要进行如下转换:

n_DevMode.dmPaperWidth =(short)(PaperWidth_pt*2.54*100/72+0.5);
n_DevMode.dmPaperLength = (short)(PaperLength_pt*2.54*100/72+0.5);

在此,代码(short)(x+0.5)的含义是返回浮点数x的四舍五入整数值。

4.3.3 读取打印纸张方向

移植程序可以通过函数gnome_print_config_get()来获取当前的打印纸张的方向。在下面的代码中,打印纸张方向称被存储在字符串变量pPaperName中。

char *pPageOrientation = (char*)gnome_print_config_get(
pConfig,
(const guchar*)GNOME_PRINT_KEY_ORIENTATION);
if (!pPageOrientation)
return 0;

Windows将打印纸张方向存储在结构DEVMODE.dmOrientation中。移植程序需要进行如下转换:

if ((0 == strcmp(pPageOrientation, "R0"))||(0 == strcmp(pPageOrientation, "R180")))
n_DevMode.dmOrientation = DMORIENT_PORTRAIT;
else if ((0 == strcmp(pPageOrientation, "R90"))||(0 == strcmp(pPageOrientation, "R270")))
n_DevMode.dmOrientation = DMORIENT_LANDSCAPE;

4.4 GNOME Print清理工作

在使用完GNOME Print打印设置后,需要手动释放分配的内存。

gnome_print_config_unref(pConfig);
gnome_print_job_close(pJob);




5.GNOME Print打印设置方法与自定义打印设置方法

使用GNOME Print就要遵循GNOME Print的数据接口。当然使用GNOME Print并不是在Linux平台上完成打印选项设置的唯一选择。不少Linux应用程序,无论是移植应用程序还是在Linux平台上直接开发的应用程序,通过自定义打印前台(即打印设置对话框)和打印后台(即打印数据结构)来完成打印设置功能。在此将这种实现方式称为自定义打印设置方法。

自定义打印设置方法为应用程序的开发提供了很多灵活性。使用这种方式可以使开发者不必局限于GNOME Print的数据接口,而按照自己的意愿设计打印设置接口。然而这种自定义打印设置方法会大大增加开发的工作量,因为现代应用程序都要对多语言和国际化进行支持。在这种前提下,自定义打印设置方法就意味着开发者要自行支持各种语言环境(即locale)下的打印设置工作。

使用GNOME Print就可以避免这些工作。这是因为GNOME Print本身已经提供了对各种语言环境的支持。比如说,GNOME Print系统打印对话框会自动根据当前locale变换显示语言。图2中的对话框就是GNOME Print对话框在"zh_CN"(简体中文)locale下的显示效果。如果把Linux当前locale设置成"en_US"(美国英语),那么图2的对话框将会变成全英文的显示效果。




6.结束语

本文概述了一种使用GNOME Print实现Windows打印选项设置在Linux平台上的移植方法。本文以设置打印纸张名称、打印纸张方向和打印纸张大小为例阐述了该移植方法的实现细节。有了上述移植实现,Windows应用程序就可以无缝隙地在Linux平台上实现对打印选项的设置操作。此外,本文还对比分析了Gnome Print打印设置方法和自定义打印设置方法。读者可以通过这部分内容进一步了解不同移植方法的优势与局限。

参考资料

MSDN: Microsoft Developer Network, http://msdn2.microsoft.com/en-us/default.aspx

GNOME Print Reference Manual

关于作者



龚奕平,软件工程师,IBM 中国软件开发中心 WPLC 部。现主要从事 Notes Linux 产品的研究及开发。研究兴趣包括 Windows 应用程序跨平台移植、GDI 开发、网络设备开发和调度算法研究。联系方式:gongyp@cn.ibm.com.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: