调试时,不知道为什么调用EndPage()返回都是-1(按照MSDN是失败),但是预览结果实际上是换了新页的。
这又是为什么?

解决方案 »

  1.   

    另外,看到一个帖子中的函数
      //换页   
      OnPrepareDC(CDC*   pDC,   CPrintInfo*   pInfo)     
      {   
              if(pDC->IsPrinting())   
            {   
                int   originy=...   
      //当前页的原点y值它通常=每页高度*(pInfo->m_nCurPage-1);   
      //然后再设置当前页原点   
                pDC->SetViewportOrg(0,originy);   
      //在此你也可以是别的处理换页的方式   
              }   
      ...   
      }   
    红色这句是不是说,虽然打印御览是分页显示的,但实际上VC的处理却是连续的页面,因此如果在需要分页的地方将y值修改为下一页的值,即不会再被最后页的内容覆盖了?
    如:
    第一页打印开始Y=100;
    第二页打印开始Y=100+页面高度;
    第N页打印开始Y=100+(N-1)*页面高度;

    对吗?
      

  2.   

    我们以前打印报表数据都是用excel的模版实现的,还没有遇到类似的问题。帮你顶。
      

  3.   

    附上你的OnPreparePrinting(),OnBeginPrinting(),OnPrint()完整代码啊,你这样说得太模糊了,都不知道你要表达什么意思。OnPrint()是根据你前面设置的页数来打印的,重复调用至打印完毕。打印预览就是你OnDraw()所画的情况,所以每次都画到最后,在OnPrint里一般是要根据你打印的页的高度来重绘的。
      

  4.   

    BOOL CXXView::OnPreparePrinting(CPrintInfo* pInfo)
    {
    if(pInfo){
    if( pInfo->m_bPreview == TRUE ) {
    //Preview
    CWnd *pWnd = GetParentFrame();
    if( pWnd != NULL ){
    //make resize possible
    LONG lResult = ::GetWindowLong(pWnd->GetSafeHwnd(), GWL_STYLE);
    lResult |= (WS_THICKFRAME | WS_MAXIMIZEBOX);
    ::SetWindowLong(pWnd->GetSafeHwnd(), GWL_STYLE, lResult); //Max window
    pWnd->ShowWindow(SW_SHOWMAXIMIZED);
    }
    }
    }
    // default preparation
    return DoPreparePrinting(pInfo);
    }void CXXView::OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo)
    {
       //创建字体
       //创建pen用来画表格的线
    }
    void CXXView::OnEndPrinting(CDC * /*pDC*/, CPrintInfo * /*pInfo*/)
    {
    m_PrintFont.DeleteObject();
    m_PrintPen.DeleteObject();
    }
    void CXXView::OnPrint(CDC *pDC, CPrintInfo *pInfo)
    {
    static i = 0;
    if(pDC && pInfo)
    {
    //Set the new font
    CFont *pOriginalFont = pDC->SelectObject(&m_PrintFont);
    CPen *pOriginalPen = pDC->SelectObject(&m_PrintPen); PrintDispatch(pDC, pInfo); //Set the original font
    pDC->SelectObject(pOriginalFont);
    pDC->SelectObject(pOriginalPen);
    }
    }
    void PrintDispatch(CDC *pDC, CPrintInfo *pInfo)
    {
    // start printing position
    UINT x = pageInfo.xStart;
    UINT y = pageInfo.yStart; for(int i = 0; i < prtTableSize; i++)
    {
    printTable[i]->PrintTable(&x, &y, pDC, pInfo);
    }
    }
    其中printTable是我定义的一个类的数组,他的成员函数PrintTable负责打印这个类所封装的数据,并且判断需要换页时就换页操作
    也就是说,由于很难算出总共能打印多少页
    所以,我想只调用OnPrint/PrintDispatch一次,即能打印出所有可能的分页(包括header/footer)
    而不是先安排好每页都打什么,算出总页数,在循环调用多次OnPrint
      

  5.   

        在OnBeginPrinting 统计出你的页数
        int nTotalRowHeight = 0;
        int nNumPages = 1;
        for (int row = 0; row < RowCount; row++)
        {
            nTotalRowHeight += RowHeight(row);//每行的高度
            if (nTotalRowHeight > m_nPageHeight) {
                nNumPages++;
                nTotalRowHeight = RowHeight(row);
            }
        }
        // Set up the print info
        pInfo->SetMaxPage(nNumPages);
        pInfo->m_nCurPage = 1;  
    在OnPrint打印的时候
     // Set the page map mode to use GridCtrl units, and setup margin
        pDC->SetMapMode(MM_ANISOTROPIC);
        pDC->SetWindowExt(m_LogicalPageSize);
        pDC->SetViewportExt(m_PaperSize);
        pDC->SetWindowOrg(-LEFT_MARGIN*m_CharSize.cx, 0);
    //
        int nTotalRowHeight = 0;
        UINT nNumPages = 1;
        int nCurrPrintRow = 1;//
    //找到本页的行号
        while (nCurrPrintRow < RowCount && nNumPages < pInfo->m_nCurPage)
        {
            nTotalRowHeight += RowHeight(nCurrPrintRow);
            if (nTotalRowHeight > m_nPageHeight) {
                nNumPages++;
                if (nNumPages == pInfo->m_nCurPage) break;
                nTotalRowHeight = RowHeight(nCurrPrintRow);
            }
            nCurrPrintRow++;
        }
        if (nCurrPrintRow >= RowCount) return;    BOOL bFirstPrintedRow = TRUE;
        CRect rect;
        rect.bottom = -1;
        while (nCurrPrintRow < RowCount)
        {
            rect.top = rect.bottom+1;
            rect.bottom = rect.top + RowHeight(nCurrPrintRow) - 1;        if (rect.bottom > m_nPageHeight) break;            // 跳出循环        rect.right = -1;
            ///打印的内容
         
            nCurrPrintRow++;
            bFirstPrintedRow = FALSE;
        }    // 设置下一页
        pDC->SetWindowOrg(0,0);
        
      

  6.   

    是的,你需要先統計出你要打印的頁數啊。在OnPreparePrinting()中調用pInfo->SetMaxPage(nMaxPage)設置打印頁數。DoPreparePrinting(pInfo)后出現預覽對話框,你可以看到你設置的打印頁數。你可以選擇打印多少頁到多少頁。然后在OnBeginPrinting()中可以得到真實打印的頁數,pInfo->SetMaxPage(pInfo->GetToPage()-pInfo->GetFromPage() + 1)。OnPrint()根據你設置的頁數會自動調用多少次以打印各頁,在OnPrint()中你只需繪制當前頁就好了啊。自定義繪制當前頁PrintDispatch(pDC, pInfo->m_nCurPage - 1)。
      

  7.   

    嗯,看来我对OnPrint函数理解错误了,开始因为觉得针对自己的项目如果在打印前算出总共能打印多少页,很麻烦,就想着如果能够实现每个打印子任务可以根据当前打印的状态来判断是否该换页等操作就好了,就想当然的以为只要调用OnPrint一次,其他交给下面处理,当时还尝试着修改pInfo-> m_nCurPage等参数来控制换页,呵呵。看来是我调查出了大问题,没有好好理解这种机制。不过我还是有点不甘心,虽然按照MFC的这种打印机制我前面的做法是错误的,但是对于我这种懒人,我觉得应该还是会有些情况下,先算出MaxPage很麻烦(如规则太多,行列变化情况很多——〉打印页统计复杂),因此要是能将打印任务交给下面自行处理,就方便多了,呵呵,当然那时可能就不用MFC的这种规则了。
    不知道有没有我说的这种实现方法,大家知道的话,麻烦给指个方向:)