很简单,重载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。
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。
[email protected]
why?
打印大致的执行顺序是:
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是否为打印。
》》我现在在画曲线,画到内存里头,然后贴到客户区。现在客户区的显示已经没问题了,是用按键控制翻屏的。可是做到打印出问题了。我打印的除了客户区的之外,还有一个标题栏,所以只能把内存里头的打印出来,而且还要把纸张设为横向的。我估计这些问题可能有代表性,因此把我的经验提供出来,供大家参考。一、设置打印纸的方向:
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。