zoukankan      html  css  js  c++  java
  • VC打印实践浅谈

    经常看到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;
     }

    唉!本人汉语能力有限,只能写成这样了,望各位朋友不要见怪!!! 

  • 相关阅读:
    Silverlight Quick Starts 翻译(一):目录
    CodeSmith实战(一):生成实体层
    Silverlight Quick Starts翻译(三) 已经有人翻译了
    ten sentences(110)
    SilverLight1.1 之旅(二):添加事件
    [Map 3D开发实战系列] Map Resource Explorer 之七 查看资源内容及资源引用
    欧特克AU中国“大师汇”在线会场 AU China Virtual上线
    Autodesk Topobase 2011 Update 1 – released!
    2010 Autodesk 开发者日即将召开,请速注册!
    云计算时代,你还在观望吗?亚马逊AWS和MapGuide
  • 原文地址:https://www.cnblogs.com/tyjsjl/p/2156107.html
Copyright © 2011-2022 走看看