很简单,重载OnBeginPrinting。
void CYourView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
    CView::OnBeginPrinting(pDC,pInfo);
// if your want to distinguish print and print preview, then unrecomment follow line
//  if (pInfo->m_bPreview)
    pInfo->SetMaxPage(1);
}
如果想在提问打印对话框前就设为单页,则重载OnPreparePrinting,在其中调SetMaxPage。

解决方案 »

  1.   

    horris(僧推月下门),你是不是做过打印和打印预览,可不可以给我发一份原代码,万分感谢!!!
    [email protected]
      

  2.   

    still can't not fix the print pre-view,horris.
    why?
      

  3.   

    Only modify OnBeginPrinting??thx
      

  4.   

    这个问题是得具体问题具体分析的,它与OnPrepareDC还有关,还有OnDraw有关。
    打印大致的执行顺序是:
    OnPreparePrinting用于显示打印设置对话框
    OnBeginPrinting时可以生成打印时专用的GDI对象等,如字体、画笔等。并且可以象我给出的那样指定页数。
    while (还有打印页)
    {
    OnPrepareDC(第n页的CDC,CPrintInfo);
    OnDraw(第n页);
    }
    OnEndPrinting用于删除OnBeginPrinting时生成的临时对象。
    如果在OnPrepareDC中使CPrintInfo::m_bContinuePrint(可能是这么写,现在身边没有资料)为FALSE,则打印立即终止。
    由上可以看出,打印多少页与OnBeginPrinting,OnPrepareDC都有关,而且,OnDraw要设计成能根据当前页绘制。要看你在OnDraw中具体绘制的是什么。比如,如果你在OnDraw中用的是硬编码的坐标,而不是根据GetClientRect给定的,虽然能指定打印页数,但打印内容会不对。CDC有个成员,可能是叫IsPrint,指出当然DC是否为打印。
      

  5.   

    看来你是在OnPrepareDC和OnDraw中有问题。CPrintInfo有m_nCurPage成员,指出当前是第几页,GetMaxPage,GetToPage可以知道一共有多少页,要求打到多少页等信息。在OnDraw中要读取这些信息,从当前页开始绘制,并通过这些信息决定绘制多少。
      

  6.   

    一位网友问我这样的问题。
    》》我现在在画曲线,画到内存里头,然后贴到客户区。现在客户区的显示已经没问题了,是用按键控制翻屏的。可是做到打印出问题了。我打印的除了客户区的之外,还有一个标题栏,所以只能把内存里头的打印出来,而且还要把纸张设为横向的。我估计这些问题可能有代表性,因此把我的经验提供出来,供大家参考。一、设置打印纸的方向:
    void CYourApp::SetPrnLandscape()
    {
     if (m_hDevMode==NULL)
     {
      PRINTDLG dlg;
      GetPrinterDeviceDefaults(&dlg);
     }
     DEVMODE *dm=(DEVMODE *)GlobalLock(m_hDevMode);
     PrinterOrientation=dm->dmOrientation;
     dm->dmOrientation=DMORIENT_LANDSCAPE;
     GlobalUnlock(m_hDevMode);
    }void CYourApp::RestorePrnOrient()
    {
     DEVMODE *dm=(DEVMODE *)GlobalLock(m_hDevMode);
     dm->dmOrientation=PrinterOrientation;
     GlobalUnlock(m_hDevMode);
    }
    你可以在视的OnPreparePrinting中,在调基类的OnPreparePrinting前调用SetPrnLandscape,在OnEndPrinting中调用RestorePrnOrient恢复原来的打印方向(如果你愿意)。不同的进程对打印机的设置是互不影响的。
    二、我在上面的回复中已讲了MFC在打印时对视的各成员函数的调用顺序,补充一点:
    OnPrepareDC->OnPrint->OnDraw
    屏幕显示和打印最终都调OnDraw。
    屏幕和打印纸的大小是不一样的,所以不能用同样的坐标。有两个解决方案:
    1。OnDraw中的绘画函数的坐标都乘一个因子,在屏幕显示时为1,打印时为打印纸大小除以屏幕大小。打印纸的大小最好在OnBeginPrinting中通过CDC::GetDeviceCaps(HORZRES)和CDC::GetDeviceCaps(VERTRES)获得,它们是设备坐标,在OnPrint中要用CDC::DPtoLP转换成逻辑坐标(在调基类OnPrint之前)
    2.打印时修改坐标影射,这要在OnPrepareDC中做:
     CView::OnPrepareDC(pDC, pInfo);
     if (pInfo==NULL) // Not printing
     {
        ...
     }
     else // Is Printing
     {
        SetMapMode(MM_ANISOTROPIC, etc.);
     }
    但这个方法在打印预览时可能会有问题,因为MFC的打印预览好象也设坐标影射的。
    三、标题的问题:
    在OnPrint中先画标题。
    然后用CDC::SetViewportOrg把坐标原点移到标题占用的区域外,也就是你要打印内容的左上角,然后,计算打印内容的大小,用<二>中的方法计算坐标因子或设置坐标影射。
    最后,调基类的OnPrint。这样在OnDraw可以象在屏幕上一样画。
    在OnPrint最后,最好用SetViewportOrg把坐标原点恢复为0,0。
      

  7.   

    这几天没有来这里up,Sorry!谢谢horris(僧推月下门)!!!
      

  8.   

    m_hDevMode是CWinApp的protected成员变量,MFC的afxwin.h的注释是:printer Dev Mode,它在GetPrinterDeviceDefaults中被初始化。