经常看到vc论坛中一些朋友问关于打印的问题,好多是问过好多遍的,其实搜索一下原来的帖子可以找到好多,而且都是给了正确的解决方法的。但我搜了一下文档中心,发现好象关于一下我要讲的内容的还没有。所以我决定把自己在做程序时遇到的问题,及实现方法和心得体会写下来,重在交流。文中如有疏漏之处,请各位朋友及时指出,以免我落个误人误己的下场。
在做打印模块时,经常会出于不同的目的改变打印机的默认配置。对于打印机配置最重要的一个结构就是devmode结构(结构的具体构成请msdn),该结构中几乎包含了打印机的所有配置信息。下面将给出几个经常要用到的配置项的实现。
printdlg pd; //该结构包含打印对话框中的所有信息
lpdevmode lpdevmode;
if(afxgetapp()->getprinterdevicedefaults(&pd)) //获得默认的打印机的信息
{
lpdevmode=(lpdevmode)globallock(pd.hdevmode);
if(lpdevmode)
{
lpdevmode->dmpapersize=dmpaper_a4; //将打印纸设置为a4
lpdevmode->dmorientation=dmorient_landscape; //将打印机设置为横向打印。
lpdevmode->dmprintquality=600 //打印分辨率为600dpi
}
globalunlock(pd.hdevmode);
}
其实,看看msdn中devmode结构的文档,套用上面这个模式,你就可以随便配置你的打印机了。如果你想配置完成后,还为用户显示打印对话框的话。可以将pd替换为printdlg.m_pd,当然你要事先定义printdlg。实现语言为“cprintdialog printdlg(false);”。
下面要讲的内容才是我要写本文的初衷,这是我刚刚解决的问题,在网上贴帖子没有人能回答的出,所以将它写出来同各位朋友共享。
我写的打印程序,在我的机器上打印正常,可是到了某些机器上打印就不正常了,打印的字体比我的大,整个版面都乱了。这下我可给搞糊涂了,同是一台打印机,程序中我也设置了映射模式为mm_text,怎么可能出现这种情况呢?后来同事发现了问题的所在,因为打印时采用的分辨率不同。由于我们不同的机器上装的是不同版本的打印驱动程序,他们默认的打印分辨率也不相同。我的机器上的打印驱动默认的是1200dpi的分辨率,而出问题的打印机的分辨率为600dpi。所以打出来的字体比原来大了两倍。下面我来分析一下原因:
windows中的字体的高度,宽度是用逻辑单元(logical units)来表示的,逻辑单元本身并不是一种长度单位。但字体可以通过它按照一定的映射模式,经过计算后显示在不同的设备终端上。比如:有一个高为240个逻辑单元的字体,系统的映射模式为mm_text(即一个逻辑单元对应一个设备像素),那么字体在屏幕的输出为240个像素高,如果换为其他的映射模式那么它就会在屏幕输出不同的大小。如果我们改变了显示器的分辨率,将它的分辨率调高,相应的每个像素大小就会变小。那么再按照mm_text映射模式,将字体显示在显示器上,那么此时字体也会比刚才看着小。
同样,这中情况也适于打印机,打印机的设备像素是点。1200dpi表示打印机每英寸可以打1200个点。600dpi表示每英寸可以打600个点。显然对于任何字体,在分辨率为600dpi的打印机上打印的大小是在1200dpi分辨率打印机上打印大小的两倍。所以为了处理这个问题我设置了一个打印系数,对于所有的打印排版所用的
参数都乘以这个系数,这样问题就迎刃而解了。下面是得到打印系数的实现:
#define print_dpi_default 1200 //我调好的程序分辨率为1200dpi
m_fxcoefficient=1;//初始化打印系数
printdlg pd;
lpdevmode lpdevmode;
double fxdpi=print_dpi_default; //
cprintdialog printdlg(false);
if(afxgetapp()->getprinterdevicedefaults(&pd))
{
lpdevmode=(lpdevmode)globallock(pd.hdevmode);
if(lpdevmode)
{
lpdevmode->dmpapersize=dmpaper_a4;
}
globalunlock(pd.hdevmode);
}
printdlg.m_pd.hdevmode=pd.hdevmode;
if (printdlg.domodal() == idcancel)
return;
fxdpi=(double)lpdevmode->dmprintquality;
if(fxdpi>0)
{
m_fxcoefficient=fxdpi/print_dpi_default;
}
唉!本人汉语能力有限,只能写成这样了,望各位朋友不要见怪!!!
