您的位置:首页 > 编程语言 > C语言/C++

VC++对话框程序打印及打印预览的实现

2014-08-07 10:12 295 查看
原文来自:V​C​+​+​对​话​框​程​序​打​印​及​打​印​预​览​的​实​现

现在我直接进入代码,原理自己看原文,我这里不多介绍了。

一共需要新建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不适用于该方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐