zoukankan      html  css  js  c++  java
  • VC视图的多页打印(转)

    原文链接:http://www.cnblogs.com/xianyunhe/archive/2011/12/18/2292043.html

    MFC框架中内置了打印框架,已实现单页的打印,如果视图中只有一页图形,并依据像素打印视图,不需要添加任何代码就可直接使用,非常方便。侯捷的《深入浅出MFC》中对MFC的打印框架进行了剖析,详细讲解各函数之间的调用关系,但对多页打印,却并未讲解。下面研究如何实现多页打印。

    1、页面布局

    在界面区域较大时,我们需要多页打印,如Excel表的打印。当横向和纵向都无法打印在一页时,页面的布局可逐行排列,也可以逐列排列。页面布局的两种示意图如下所示。

    1)逐行排列页面布局示意如下:

    1

    2

    3

    4

    5

    6

    2)逐列排列页面布局示意如下:

    1

    3

    5

    2

    4

    6

    2、设定页数

    在打印前,需要先设定打印的页数,即根据整个视图的大小和页面的大小来计算页数。只要才打印前设置即可。下面是在子类中重载CView类的OnBeginPrinting函数,用于实现页数的计算,实现代码如下:

    复制代码
     1 void CMultiPagePrintView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
    2 {
    3 // TODO: add extra initialization before printing
    4
    5 /*得到打印纸的像素大小*/
    6 int iPageWidth = pDC->GetDeviceCaps(HORZRES);
    7 int iPageHeight = pDC->GetDeviceCaps(VERTRES);
    8
    9 /*得到窗口的大小*/
    10 CSize szTotalWnd = GetTotalSize();
    11
    12 /*得到行和列的数量*/
    13 int iRowCnt = szTotalWnd.cy / iPageHeight;
    14 if (szTotalWnd.cy % iPageHeight > 0)
    15 {
    16 iRowCnt++;
    17 }
    18 int iColCnt = szTotalWnd.cx / iPageWidth;
    19 if (szTotalWnd.cx % iPageWidth > 0)
    20 {
    21 iColCnt++;
    22 }
    23
    24 /*得到要打印的页数*/
    25 int iPageCnt = iRowCnt * iColCnt;
    26 pInfo->SetMaxPage(iPageCnt);
    27 }
    复制代码

    3、设置页面原点

    在打印每一页的过程中,只需得到当前打印页面的页码,并计算出该页面原点对应的视图中的位置,然后调用CView::OnPrint即可完成打印。由于页面采用逐行排列和逐页排列时,页面对应的视图位置并不相同,因此,需要根据页面的排列模式分开计算。实现代码如下:

    复制代码
     1 void CMultiPagePrintView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
    2 {
    3 // TODO: Add your specialized code here and/or call the base class
    4
    5 /*得到打印纸的像素大小*/
    6 int iPageWidth = pDC->GetDeviceCaps(HORZRES);
    7 int iPageHeight = pDC->GetDeviceCaps(VERTRES);
    8
    9 /*得到窗口的大小*/
    10 CSize szTotalWnd = GetTotalSize();
    11
    12 /*得到行和列的数量*/
    13 int iRowCnt = szTotalWnd.cy / iPageHeight;
    14 if (szTotalWnd.cy % iPageHeight > 0)
    15 {
    16 iRowCnt++;
    17 }
    18 int iColCnt = szTotalWnd.cx / iPageWidth;
    19 if (szTotalWnd.cx % iPageWidth > 0)
    20 {
    21 iColCnt++;
    22 }
    23
    24 /*得到当前页的行和列编号,起始编号均为0*/
    25 int iPageRowIdx = 0;
    26 int iPageColIdx = 0;
    27
    28 if (LAYOUT_BY_ROW == m_iPageLayout)
    29 {
    30 iPageRowIdx = (pInfo->m_nCurPage-1) / iColCnt;
    31 iPageColIdx = (pInfo->m_nCurPage-1) % iColCnt;
    32 }
    33 else
    34 {
    35 iPageRowIdx = (pInfo->m_nCurPage-1) % iRowCnt;
    36 iPageColIdx = (pInfo->m_nCurPage-1) / iRowCnt;
    37 }
    38
    39
    40 /*得到当前页的原点*/
    41 CPoint ptOrgin(0,0);
    42 ptOrgin.x = iPageColIdx * iPageWidth;
    43 ptOrgin.y = iPageRowIdx * iPageHeight;
    44 pDC->SetWindowOrg(ptOrgin);
    45
    46 CScrollView::OnPrint(pDC, pInfo);
    47 }
    复制代码

    4、示例程序

    本文以像素分辨率为2480*3507A4打印纸为例,分别实现了逐行排列和逐列排列的打印。为了方便检验打印是否正确,在页面中标注了页码和当前页所在的界面的行和列,其中页面的起始值为1,而行和列的起始值为0

    工程文件下载:

    PUDN:http://www.pudn.com/downloads407/sourcecode/windows/control/detail1735047.html

    CSDN:http://download.csdn.net/detail/xianyunhe1234/3937881

  • 相关阅读:
    Struts1、Struts2的线程安全问题
    java基础系列——线程池
    Memcached基础
    Git基本应用
    Angular UI框架 Ng-alain @delon的脚手架的生成开发模板
    .NET CORE 框架ABP的代码生成器(ABP Code Power Tools )使用说明文档
    角落的开发工具集之Vs(Visual Studio)2017插件推荐
    【52ABP实战教程】0.3-- 从github推送代码回vsts实现双向同步
    【52ABP实战教程】0.1-- Devops如何用VSTS持续集成到Github仓库!
    【52ABP实战教程】0.2-- VSTS中的账号迁移到东亚
  • 原文地址:https://www.cnblogs.com/luleigreat/p/2669918.html
Copyright © 2011-2022 走看看