原文来自:VC++对话框程序打印及打印预览的实现
现在我直接进入代码,原理自己看原文,我这里不多介绍了。
一共需要新建3个类,CMyView,CMyFrame,CMyPreviewView
CMyView
MyView.h
class CMyView : public CScrollView
{
DECLARE_DYNCREATE(CMyView)
protected:
CMyView(); // 动态创建所使用的受保护的构造函数
virtual ~CMyView();
public:
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif
protected:
virtual void OnDraw(CDC* pDC); // 重写以绘制该视图
virtual void OnInitialUpdate(); // 构造后的第一次
DECLARE_MESSAGE_MAP()
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
public:
virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);
void OnFilePrintPreview(void);
void DrawPic(CDC* pdc);//自定义画图函数
};
MyView.cpp
CMyView::CMyView()
{
m_nMapMode = MM_TEXT;
}
void CMyView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
// TODO: 在此添加专用代码和/或调用基类
pDC->SetMapMode(MM_ANISOTROPIC);
//转换坐标映射方式
CSize size=CSize(800, 560);
pDC->SetWindowExt(size); //确定窗口大小
//得到实际设备每逻辑英寸的像素数量
int xLogPixPerInch=pDC->GetDeviceCaps(LOGPIXELSX);
int yLogPixPerInch=pDC->GetDeviceCaps(LOGPIXELSY);
//得到设备坐标和逻辑坐标的比例
long xExt=(long)size.cx*xLogPixPerInch/96;
long yExt=(long)size.cy*yLogPixPerInch/96;
pDC->SetViewportExt(xExt,yExt);
CScrollView::OnPrepareDC(pDC, pInfo);
}
void CMyView::OnFilePrintPreview(void)
{
CPrintPreviewState* pState = new CPrintPreviewState;
pState->lpfnCloseProc =_AfxMyPreviewCloseProc;//设置打印预览窗口关闭时的调用函数;
if(!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this,RUNTIME_CLASS(CMyPreviewView), pState))
{
TRACE0("Error: DoPrintPreview failed.\n");
AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
delete pState;
}
}
BOOL CALLBACK _AfxMyPreviewCloseProc(CFrameWnd* pFrameWnd)
{
ASSERT_VALID(pFrameWnd);
CMyPreviewView* pView = (CMyPreviewView*) pFrameWnd->GetDlgItem(AFX_IDW_PANE_FIRST);
ASSERT_KINDOF(CPreviewView, pView);
pView->OnPreviewClose();
return FALSE;
}
BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
{
// TODO: 调用 DoPreparePrinting 以调用“打印”对话框
// return CScrollView::OnPreparePrinting(pInfo);
return DoPreparePrinting(pInfo);
}这里需要注意,调用的是
DoPreparePrinting(pInfo); 不是
OnPreparePrinting(pInfo);
最后在OnDraw中调用自己的画图函数
void CMyView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: 在此添加绘制代码
DrawPic(pDC);
}
CMyFrame
MyFrame.h
#include "PdfDemoDlg.h"
// CMyFrame 框架
#include "MyView.h"
class CMyFrame : public CFrameWnd
{
DECLARE_DYNCREATE(CMyFrame)
public:
CMyFrame(); // 动态创建所使用的受保护的构造函数
virtual ~CMyFrame();
CMyFrame(CPdfDemoDlg* pWnd);
CPdfDemoDlg *m_pOldWnd;//主对话框
CMyView* m_pView;
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};
MyFrame.cpp
int CMyFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
CCreateContext context;
context.m_pNewViewClass = RUNTIME_CLASS(CMyView);
context.m_pCurrentFrame = this;
context.m_pCurrentDoc = NULL;
context.m_pLastView = NULL;
m_pView = STATIC_DOWNCAST(CMyView, CreateView(&context));
if(m_pView != NULL)
{
m_pView->ShowWindow(SW_SHOW);
SetActiveView(m_pView);
}
SetIcon(m_pOldWnd->GetIcon(FALSE),FALSE);
SetIcon(m_pOldWnd->GetIcon(TRUE),TRUE);
ShowWindow(SW_MAXIMIZE);
CWinApp *pApp=AfxGetApp();
pApp->m_pMainWnd=this;
m_pView->OnFilePrintPreview();
//m_pView->SendMessage(WM_COMMAND, ID_FILE_PRINT);//直接打印
m_pOldWnd->ShowWindow(SW_HIDE);
return 0;
}
CMyFrame::CMyFrame(CPdfDemoDlg* pWnd)
{
m_pOldWnd= pWnd;
CString str;
str=_T("Print Preview");
if(!Create(NULL,str,WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,CRect(200,200,500,500)))
TRACE0("Failed to create view window\n");
}
CMyFrame::~CMyFrame()
{
m_pOldWnd->ShowWindow(SW_SHOW);
}
CMyPreviewView
MyPreviewView.h
#include <afxpriv.h>
// CMyPreviewView 视图
class CMyPreviewView : public CPreviewView
{
DECLARE_DYNCREATE(CMyPreviewView)
protected:
CMyPreviewView(); // 动态创建所使用的受保护的构造函数
virtual ~CMyPreviewView();
public:
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPreviewClose();
afx_msg void OnPreviewPrint();
virtual void OnDraw(CDC* /*pDC*/);
};
这里需要注意,VS2010自动继承的是CPreviewViewEx,需要自己修改。CPreviewViewEx不适用于该方式。
MyPreviewView.cpp
void CMyPreviewView::OnPreviewPrint()
{
// TODO: 在此添加命令处理程序代码
m_pPrintView->SendMessage(WM_COMMAND, ID_FILE_PRINT);
}
void CMyPreviewView::OnPreviewClose()
{
// TODO: 在此添加命令处理程序代码
CMyFrame* pf=(CMyFrame*)::AfxGetMainWnd();
CWinApp *pApp=AfxGetApp();
pApp->m_pMainWnd=pf->m_pOldWnd;
pf->DestroyWindow();
}
void CMyPreviewView::OnDraw(CDC* pDC)
{
CPreviewView::OnDraw(pDC);
// TODO: 在此添加专用代码和/或调用基类
m_pToolBar->PostMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);// 控制条的命令状态更新
}
BEGIN_MESSAGE_MAP(CMyPreviewView, CPreviewView)
ON_COMMAND(AFX_ID_PREVIEW_CLOSE, &CMyPreviewView::OnPreviewClose)
ON_COMMAND(AFX_ID_PREVIEW_PRINT, &CMyPreviewView::OnPreviewPrint)
END_MESSAGE_MAP()
最后响应按钮调用
#include "MyFrame.h"
void CPdfDemoDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
this->SendMessage(WM_WSPPRINTPREVIEW,NULL,NULL);
}
主对话框中响应自定义消息WM_WSPPRINTPREVIEW
#define WM_WSPPRINTPREVIEW WM_USER+13
LRESULT CPdfDemoDlg::OnWSPPrintPreview(WPARAM wParam, LPARAM lParam)
{
CMyFrame* pFrame = new CMyFrame(this);
return 0;
}
VC6和VS2010都是同样使用,只不过VS2010中自动继承的是CPreviewViewEx,需要自己修改。CPreviewViewEx不适用于该方式。

本文详细介绍了如何在对话框程序中实现打印预览功能,包括新建三个类:CMyView、CMyFrame 和 CMyPreviewView。通过自定义画图函数和调整设备上下文设置,实现预览和打印效果。此外,文章还展示了如何响应按钮事件触发打印预览,并通过主对话框和框架窗口的交互来完成整个流程。

6556

被折叠的 条评论
为什么被折叠?



