您的位置:软件 > 开发者网络 > 正文
VC数据库编程中的打印控制
[文章信息]
作者:李佑民
时间:2003-05-19
出处:天极论坛
责任编辑:方舟
[文章导读]
在数据库应用中,一般把纸式报表的打印输出放在比较重要的位置......
advertisement
热点推荐
· 11.15软件精选 制作MSI文件
· 闪客五周年之闪客光荣榜
· 用Winamp“品尝”无限音乐
· 网络加、解密的技术应用
· 闪客五周年之闪客光荣榜:zoron
[正文]

  在数据库应用中,一般把纸式报表的打印输出放在比较重要的位置,特别是在银行、保险等金融部门,打印出来的纸式硬拷贝一般都要永久保存,因此程序的打印输出结果是否美观、输出方式是否灵活是衡量程序优劣的重要标志。比起其他编程语言来说,VC编程中的打印控制比较复杂,但它也给程序员最大的灵活性,而这种灵活性正是我们需要的,因为金融部门的报表一般都不太规整,特别是表头部分,二、三重嵌套的情况很常见。下面我们就开发中碰到的一些问题与同行们探讨。

  一、 Document/View框架之外的打印

  熟悉VC的程序员都知道Microsoft的AppWizard生成的应用程序框架中,可以选择免费的打印及打印预览功能,但是前提是必须选择Document/View结构,然而我们 廯 应用中一般都不需要一个文档类来保存文档,因为数据库(源)就是我们的文档,数据一般是在一个对话框或视中与用户交互,编辑或修改结果直接通过数据库引擎写回数据库中。我们的程序主框架要么是基于对话框的、要么是基于无文档类的单视(或多视)结构,在这种情况下,AppWizard在打印控制部分并不能给我们任何帮助,只能自己负责完成打印控制。

  分析MFC提供的打印功能,在一个视中实现定制的打印,需要分别重载视的以下函数:

  OnPreparePrinting():在开始打印文档之前,定制或初始化打印对话框;
  OnPrepareDC():准备设备场景,分别打印或预览准备PrintDC和ScreenDC;
  OnBeginPrinting():开始一次新的打印作业,并分配图形设备接口;
  OnEndPrinting(),OnEndPrintPreview():终止打印作业,释放图形设备接口:

  OnPrint():完成打印或预览每页文档的输出。
  总结起来:一次打印操作要遵循以下步骤:

  1.得到或生成打印设备场景,可通过显示打印对话框让用户选择打印机与纸张等设置,也可在程序中直接取系统缺省打印机设置,然后根据报表格式设置纸张大小和打印方向;

  2.开始在该设备场景中的一次打印作业,实际打印报表内容,终止打印作业;

  3.清除打印设备场景,完成本次打印操作。

  在下面的例子中,我们在一个对话框中让用户选择打印某个报表,没有显示打印设置对话框,而是直接取系统缺省打印机设置,然后根据报表格式设置纸张大小和打印方向,之所以这样做是因为金融系统的报表格式一般都是至上而下的统一格式。函数DoPreparePrintDC(),DoPrint()和DoC1earPrintDC()分别对应上述的三个步骤:

  BOOL CMyDialog::DoPreparePrintDC() //准备打印场景
  {
  #define FONTSIZE 14
  //获取打印机的设备属性
  CPrintDialog dlgPrint(FALSE);
  //得到当前系统缺省打印机设置
  if(!dlgprint.GetDefau1ts() )return FALSE;
  LPDEVMODE pDM=dlgPrint.GetDevMode();
  if (pDM==NULL)return FALSE;
  //调整打印方向
  //pDM->dm0rientation=DMORIENT_LANDSCAPE(横向)‖
  DMORIENT_PORTRAIT(纵向);
  //调整纸张大小
  //制式纸张:pDM->dmPaperSize=DMPAPER_A3等;
  //或自定义大小:单位:1/10毫米
  //pDM->dmPaperSize=DMPAPER_USER;
  //pDM->dmPaperLength=纸张高度;
  //pDM->dmPaperWidth=纸张宽度;
  //解锁由CPrintDialog::GetDevMode()封锁的内存
  ::GlobalUn1ock(pDM);
  //联结打印DC,m_hDC是定义为HDC m_hDC的类成员变量
  m_hDC=dlgPrint.CreatePrinterDC();
  //m_DC是定义为CDC m_DC的类成员变量
  if (!m_DC.Attach(m_hDC)return FALSE;
  //设置打印廯 标志
  m_DC.m_bPrinting=TRUE;
  //根据打印机分辨率建立打印字体
  //得到每英寸点数
  short cxInch=m_DC.GetDeviceCaps(LOGPIXELSX);
  short cyInch=m_DC.GetDeviceCaps(LOGPIXELSY);
  //建立打印字体,m_fontPrint是定义为CFont m_fontPrint的类成员变量
  if (!m_fontPrint.CreateFont(MulDiv(FONTSIZE,-cyInch,
72),
  0,0,0,FW_NORMAL,0,0,0,
  GB2312_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHA
RACTER_PRECIS,
  DEFAULT_QUALITY,DEFAULT_PITCH|FF—DONTCARE,HFONTNAME)
  return FALSE;
  return TRUE;
  }
  void CDlgDataPrint::DoClearPrintDC()//清除打印场景
  {
   m_fontPrint,Delete0bject();
   m_DC.Detach();
   ::DeleteDC( m_hDC);
  }
  void CDlgDataPrint::DoPrint()    //实际打印输出
  {
  //准备打印场景,横纵向居中
  if (DoPreparePrintDC()==FALSE)return;
  //开始一次打印作业
  CString str;
  str.LoadString(AFX_IDS_APP_TITLE);
  DOCINFO di;
  ::ZeroMemory(&di,sizeof (DOCINFO));
  di.cbSize=sizeof (DOCINFO);
  di.lpszDocName=str;
  m_DC.StartDoc(&di);
  m_DC.StartPage();
  //将打印字体选进设备场景
  CFont* p0ldFont=m_DC.Select0bject(&m_fontPrint);
  //输出报表,建议用CDC::DrawText()函数便于控制打印范围……
  //终止打印作业
  m_DC,EndPage();
  m_DC.EndDoc();
  m_DC.Select0bject(p0ldFont);
  //清除打印场景
  DoClearPrintDC();
  }

  二、 表格问题

  人们常用的报表格式几乎都是封闭式的,要实现这种报表不外乎两种方法:一是在进行打印输出时直接绘制横线和竖线,这种方法适用于报表格式不固定或格式较简单的情况,对那种格式固定或表头和表体比较复杂的情况,特别是有嵌套表格的情况下,我们认为先将打印结果以文本形式写入一个临时文件,然后再对文件进行打印输出的方法要使事情简单一些,因为这样的程序就可以只关心数据(表体)的输出,而表头则可以固定格式存入数据库。但是,我们在对文本形式的报表进行打印输出时却发现一个有趣的现象,有时输出结果的相邻两行表格竖线不能对齐,而有时又可以。原来是Windows图形输出的结果,只要我们在建立打印字体时,字体的高度是偶数就可保证竖线对齐,如果是奇数则不能对齐。知道了原因,在建立打印字体时只需:

  ……
  #define FONTSIZE 14
  //建立打印字体,m_fontPrint是定义为CFont m_fontPrint的类成员变量
  int nFontHeight=MulDiv(FONTSIZE,-cyInch,72);
  if (nFontHeight % 2)nFontHeight++;
  if (!m_fontPrint.CreateFont(nFontHeight,0,0,0, FW_NORM
AL,0,0,0,
  GB2312_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHA
RACTER_PRECIS,
  DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,HFONTNAME)
  return FALSE;
  ……

  还有一点小技巧,输出文本形式的报表时,对报表的横线只需要输出其正常高度的二分之一或三分之一,这样报表看起来更紧凑美观。这也是我们在前面建议用CDC::DrawText()进行绘制输出的原因。


·"WAP天极之IT新闻资讯,50万元等你拿"    ·天极WAP之游戏狂图,50万元等你下载


发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容阅读排行榜
  • 用VC++6.0编写Proxy服务器
  • 如何在VC++中使用API直接打印
  • VC中基于CEditView的打印和打印预览设计
  • VC6.0映射模式转换及如何消除坐标误差
  • 11.15软件精选 制作MSI文件
  • 闪客五周年之闪客光荣榜
  • 兰欣推出我国第一款网络游戏专用音箱
  • 玩家发现117亡灵种族Bug
  • [配置推荐]极品HIFI配置
  • 东瀛美少女COSPLAY(55)
  • 用Winamp“品尝”无限音乐
  • 迷你型PStwo全面透析专题
  • Advertisement

    天极无线
    待机彩图    >>更多
    多彩动画    >>更多
    美妙和弦    >>更多
    天使在唱歌
    壁虎漫步
    PrettyBoy
    LoveLoveLove
    我是你的小小狗
    单身情歌
    十面埋伏
    祝酒歌
    回心转意
    波斯猫
    太委屈
    S.H.E
    潘玮柏
    M2M
    蔡依林
    阿牛
    林志炫
    陈弈迅
    刀郎
    黑龙
    S.H.E
    陶晶莹
    情人玫瑰坊
    音乐风云
    新片速递
    神秘测试
    都市约会
    ·天极彩信天天精彩
    ·图铃梦工厂下载无限!
    ·找寻童真,卡通专题
    ·夏日激情交友社区!
    ·星座运程,预测人生

    CSEEK搜索