mfc调用系统的打印预览总是出现英文菜单栏,很烦,而且可选用的打印机也不清楚,为了解决,觉得重绘一个打印预览界面,网上也查了很久,最后自己写了一个基本符合的预览界面。
首先,在要调用的窗口view下,CFrameWnd创建MainFF窗口,(class CMainFF : public CFrameWnd),用CFrameWnd是因为下面还要在该窗口下建立数据页(WrapperView类)。直接上代码
包含文件随自己而定
头文件.h
// MainFrm.h : interface of the CMainFrame class
//
/
#if !defined(AFX_MAINFF_H__5C3F89A6_932E_11D3_8420_FC56F1C91E86__INCLUDED_)
#define AFX_MAINFF_H__5C3F89A6_932E_11D3_8420_FC56F1C91E86__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//
//#include "stdafx.h"
#include "WrapperView.h"
class CMainFF : public CFrameWnd
{
public:
void tcdClose();
afx_msg LRESULT MYClose(WPARAM w, LPARAM l);
CMainFF(DRAWFUN pDraw, CWnd*pOldW, CWnd* pCallW, BOOL bDirect, LPCTSTR stTitle = NULL);
CWnd* pOldWnd;
CWnd* pCallWnd;
DRAWFUN Draw;
BOOL bDirectPrint;
protected:
DECLARE_DYNAMIC(CMainFF)
public:
bool open=false;
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
// Implementation
public:
CToolBarCtrl m_tool;
virtual ~CMainFF();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CWrapperView *m_pView;
// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnClose();
};
/
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRM_H__5C3F89A6_932E_11D3_8420_FC56F1C91E86__INCLUDED_)
.cpp文件
// MainFrm.cpp : implementation of the CMainFF class
//
//#include "tcdMultiView.h"
#include "stdafx.h"
#include "MainFF.h"
#include "msgdef.h"
#include "GlobalVar.h"
//#include "tcdMultiView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CMainFF
IMPLEMENT_DYNAMIC(CMainFF, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFF, CFrameWnd)
ON_WM_PAINT()
ON_WM_CREATE()
ON_WM_CLOSE()
ON_MESSAGE(WM_MYCLOSE, MYClose)//zzy
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/
// CMainFF construction/destruction
CMainFF::CMainFF(DRAWFUN pDraw, CWnd*pOldW, CWnd* pCallW, BOOL bDirect, LPCTSTR stTitle)
{
Draw = pDraw;
CString ss;
ss = _T("打印预览");
if (!Create(NULL, ss, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CRect(200, 200, 500, 500)))
TRACE0("Failed to create view window\n");
}
CMainFF::~CMainFF()
{
bDirectPrint = FALSE;
}
void CMainFF::tcdClose() {
this->CloseWindow();
}
LRESULT CMainFF::MYClose(WPARAM w, LPARAM l)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
open = true;
CFrameWnd::OnClose();
return 0;
}
int CMainFF::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
ModifyStyle(WS_MAXIMIZEBOX, 0);
ModifyStyle(WS_MINIMIZEBOX, 0);
//ModifyStyle(WS_SYSMENU, 0);
CCreateContext context;
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
context.m_pNewViewClass = RUNTIME_CLASS(CWrapperView);
context.m_pCurrentFrame = this;
context.m_pCurrentDoc = NULL;
context.m_pLastView = NULL;
m_pView = STATIC_DOWNCAST(CWrapperView, CreateView(&context)); //CreateView(&context);
if (NULL != m_pView) {
if (!bDirectPrint)
m_pView->ShowWindow(SW_SHOW);
SetActiveView(m_pView);
}
ShowWindow(SW_MAXIMIZE);
CWinApp *pApp = AfxGetApp();
pApp->m_pMainWnd = this;
if (bDirectPrint)
{
m_pView->SendMessage(WM_COMMAND, ID_FILE_PRINT);
}
else
{
m_pView->OnFilePrintPreview(this);
}
return 0;
}
BOOL CMainFF::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CFrameWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
cs.lpszClass = AfxRegisterWndClass(0);
return TRUE;
}
/
// CMainFF diagnostics
#ifdef _DEBUG
void CMainFF::AssertValid() const
{
CMainFF::AssertValid();
}
void CMainFF::Dump(CDumpContext& dc) const
{
CMainFF::Dump(dc);
}
#endif //_DEBUG
/
// CMainFF message handlers
BOOL CMainFF::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if (open)return TRUE;
// let the view have first crack at the command
if (m_pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
CWinApp* pApp = AfxGetApp();
if (pApp != NULL && pApp->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
//
// 源代码中使用的框架销毁函数有bug,这里暂时不使用正常销毁-AWEN
void CMainFF::OnClose()
{
CFrameWnd::OnClose();
}
数据类 WrapperView
.h
//WrapperView.h
#if !defined(AFX_WRAPPERVIEW_H__AC579D20_8E3D_11D3_8410_E1CD9A2C01DC__INCLUDED_)
#define AFX_WRAPPERVIEW_H__AC579D20_8E3D_11D3_8410_E1CD9A2C01DC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// WrapperView.h : header file
//
#include "MyPreviewView.h"
#include "scanwnd/PrintData.h"
/
// CWrapperView view
class CWrapperView : public CScrollView
{
protected:
DECLARE_DYNCREATE(CWrapperView)
CFrameWnd* m_pFrameWnd;
public:
CPrintData m_printdata1;
friend class CTcdMultiView;
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
CDialogBar dialogbar;
CToolBar m_toolbar;//工具栏
CWrapperView();
virtual ~CWrapperView();
afx_msg void OnPreviewPrint();
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
void OnFilePrintPreview(CFrameWnd *pFrame);
BOOL DoPrintPreview(UINT nIDResource, CView* pPrintView, CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState);
void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT, CMyPreviewView* pView);
// Overrides
// ClassWizard generated virtual function overrides
virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo); // overridden to draw this view
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnActivateView(BOOL bActivate, CView*, CView*);
// Implementation
protected:
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
protected:
// NOTE - the ClassWizard will add and remove member functions here.
afx_msg void OnFilePrint();
DECLARE_MESSAGE_MAP()
public:
CDialogBar *m_pToolBar;
};
/
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_WRAPPERVIEW_H__AC579D20_8E3D_11D3_8410_E1CD9A2C01DC__INCLUDED_)
.cpp
// WrapperView.cpp : implementation file
//
#include "stdafx.h"
#include "WrapperView.h"
#include "MyPreviewView.h"
#include "MainFF.h"
#include "const.h"
#include "GlobalVar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BOOL CALLBACK _AfxMyPreviewCloseProc(CFrameWnd* pFrameWnd);
/
// CWrapperView
IMPLEMENT_DYNCREATE(CWrapperView, CScrollView)
CWrapperView::CWrapperView()
{
m_pFrameWnd = NULL;
m_nMapMode = MM_TEXT; //default
}
CWrapperView::~CWrapperView()
{
delete m_pToolBar;
}
BEGIN_MESSAGE_MAP(CWrapperView, CScrollView)
// NOTE - the ClassWizard will add and remove mapping macros here.
ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
ON_COMMAND(AFX_ID_PREVIEW_PRINT, OnPreviewPrint)
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
END_MESSAGE_MAP()
void CWrapperView::OnDraw(CDC *pDC)
{
}
void CWrapperView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
if (pDC)
{
m_printdata1.Print(pDC, pInfo);//zzy 230821
}
}
void CWrapperView::OnPreviewPrint()
{
SendMessage(WM_COMMAND, ID_FILE_PRINT);
}
/
// CWrapperView diagnostics
#ifdef _DEBUG
void CWrapperView::AssertValid() const
{
CView::AssertValid();
}
void CWrapperView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif //_DEBUG
/
// CWrapperView message handlers
void CWrapperView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
// TODO: add extra initialization before printing
int nPageCount = 1;
if (dlogset1.ReportType != 0)
nPageCount = m_printdata1.GetPrintPageCount(pDC, pInfo);
else
nPageCount = m_printdata1.GetPrintPageCount2(pDC, pInfo);
pInfo->SetMaxPage(nPageCount);
}
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 CWrapperView::OnPreparePrinting(CPrintInfo* pInfo)
{
return DoPreparePrinting(pInfo);
}
void CWrapperView::OnActivateView(BOOL bActivate, CView*, CView*)
{
}
void CWrapperView::OnFilePrint()
{
CMainFF* pf = (CMainFF*)::AfxGetMainWnd();
if (pf->bDirectPrint)
pf->ShowWindow(SW_HIDE);
CView::OnFilePrint();
if (pf->bDirectPrint)
{
CWinApp *pApp = AfxGetApp();
pApp->m_pMainWnd = pf->pOldWnd;
pf->DestroyWindow();
}
}
void CWrapperView::OnFilePrintPreview(CFrameWnd *pFrame)
{
m_pFrameWnd = pFrame;
CPrintPreviewState* pState = new CPrintPreviewState;
pState->lpfnCloseProc = _AfxMyPreviewCloseProc;
if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this, RUNTIME_CLASS(CPreviewView), pState))
{
TRACE0("Error: DoPrintPreview failed.\n");
AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
delete pState;
}
}
BOOL CWrapperView::DoPrintPreview(UINT nIDResource, CView* pPrintView, CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
{
CToolBar newToolBar;
ASSERT_VALID_IDR(nIDResource);
ASSERT_VALID(pPrintView);
ASSERT(pPreviewViewClass != NULL);
ASSERT(pPreviewViewClass->IsDerivedFrom(RUNTIME_CLASS(CPreviewView)));
ASSERT(pState != NULL);
ASSERT(m_pFrameWnd != NULL);
CFrameWnd* pParent = m_pFrameWnd; //STATIC_DOWNCAST(CFrameWnd, AfxGetMainWnd()); //
ASSERT_VALID(pParent);
CCreateContext context;
context.m_pCurrentFrame = pParent;
context.m_pCurrentDoc = GetDocument();
context.m_pLastView = this;
// Create the preview view object
CMyPreviewView* pView = (CMyPreviewView*)pPreviewViewClass->CreateObject();
if (pView == NULL)
{
TRACE0("Error: Failed to create preview view.\n");
return FALSE;
}
ASSERT_KINDOF(CPreviewView, pView);
pView->m_pPreviewState = pState; // save pointer
pParent->OnSetPreviewMode(TRUE, pState); // Take over Frame Window
pView->m_pToolBar = new CDialogBar;
if (!pView->m_pToolBar->Create(pParent, MAKEINTRESOURCE(nIDResource),
CBRS_TOP, AFX_IDW_PREVIEW_BAR))
{
TRACE0("Error: Preview could not create toolbar dialog.\n");
pParent->OnSetPreviewMode(FALSE, pState); // restore Frame Window
delete pView->m_pToolBar; // not autodestruct yet
pView->m_pToolBar = NULL;
pView->m_pPreviewState = NULL; // do not delete state structure
delete pView;
return FALSE;
}
pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_PRINT, _T("打印(&P)"));
pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_NEXT, _T("下一页(&N)"));
pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_PREV, _T("上一页(&V)"));
pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_NUMPAGE, _T("分页(&T)"));
pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_ZOOMIN, _T("放大(&I)"));
pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_ZOOMOUT, _T("缩小(&O)"));
pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_CLOSE, _T("关闭(&C)"));
pView->m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_CLOSE)->ShowWindow(false);
//pView->m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_NUMPAGE)
pView->m_pToolBar->m_bAutoDelete = TRUE; // automatic cleanup
CString str;
pView->m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_NUMPAGE)->GetWindowTextA(str);
if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), pParent, AFX_IDW_PANE_FIRST, &context))
{
TRACE0("Error: couldn't create preview view for frame.\n");
pParent->OnSetPreviewMode(FALSE, pState); // restore Frame Window
pView->m_pPreviewState = NULL; // do not delete state structure
delete pView;
return FALSE;
}
pState->pViewActiveOld = pParent->GetActiveView();
CWrapperView* pActiveView = (CWrapperView*)pParent->GetActiveFrame()->GetActiveView();
if (pActiveView != NULL)
pActiveView->OnActivateView(FALSE, pActiveView, pActiveView);
if (!pView->SetPrintView(pPrintView))
{
pView->OnPreviewClose();
return TRUE; // signal that OnEndPrintPreview was called
}
pParent->SetActiveView(pView); // set active view - even for MDI
// update toolbar and redraw everything
pView->m_pToolBar->SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);
pParent->RecalcLayout(); // position and size everything
pParent->UpdateWindow();
return TRUE;
}
// OnEndPrintPreview is here for swap tuning reasons
// (see viewprev.cpp for complete preview mode implementation)
void CWrapperView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT, CMyPreviewView* pView)
{
ASSERT_VALID(pDC);
ASSERT_VALID(pView);
ASSERT(m_pFrameWnd != NULL);
if (pView->m_pPrintView != NULL)
OnEndPrinting(pDC, pInfo);
CFrameWnd *pParent = m_pFrameWnd;
ASSERT_VALID(pParent);
// restore the old main window
pParent->OnSetPreviewMode(FALSE, pView->m_pPreviewState);
// Force active view back to old one
pParent->SetActiveView(pView->m_pPreviewState->pViewActiveOld);
if (pParent != GetParentFrame())
OnActivateView(TRUE, this, this); // re-activate view in real frame
pView->DestroyWindow(); // destroy preview view
// C++ object will be deleted in PostNcDestroy
// restore main frame layout and idle message
pParent->RecalcLayout();
pParent->SendMessage(WM_SETMESSAGESTRING, (WPARAM)AFX_IDS_IDLEMESSAGE, 0L);
pParent->UpdateWindow();
}
void CWrapperView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
CView::OnEndPrinting(pDC, pInfo);
::SendMessage(::AfxGetMainWnd()->m_hWnd, WM_MYCLOSE, 0, 0);
return;
}
/
//zzy 230818
IMPLEMENT_DYNCREATE(CMyPreviewView, CPreviewView)
CMyPreviewView::CMyPreviewView()
{
}
CMyPreviewView::~CMyPreviewView()
{
}
BEGIN_MESSAGE_MAP(CMyPreviewView, CPreviewView)
ON_COMMAND(AFX_ID_PREVIEW_CLOSE, OnPreviewClose)
ON_COMMAND(AFX_ID_PREVIEW_PRINT, OnPreviewPrint)
END_MESSAGE_MAP()
/
// CMyPreviewView drawing
void CMyPreviewView::OnDraw(CDC* pDC)
{
CPreviewView::OnDraw(pDC);
}
/
// CMyPreviewView diagnostics
#ifdef _DEBUG
void CMyPreviewView::AssertValid() const
{
}
void CMyPreviewView::Dump(CDumpContext& dc) const
{
}
#endif //_DEBUG
/
// CMyPreviewView message handlers
void CMyPreviewView::OnActivateView(BOOL bActivate, CView* pView1, CView *pView2)
{
CPreviewView::OnActivateView(bActivate, pView1, pView2);
}
void CMyPreviewView::OnPreviewClose()
{
CMainFF* pf = (CMainFF*)::AfxGetMainWnd();
CWinApp *pApp = AfxGetApp();
pApp->m_pMainWnd = pf->pOldWnd;
//pf->OnClose();
pf->DestroyWindow();
}
void CMyPreviewView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView)
{
CPreviewView::OnEndPrintPreview(pDC, pInfo, point, pView);
}
void CMyPreviewView::OnPreviewPrint()
{
m_pPrintView->SendMessage(WM_COMMAND, ID_FILE_PRINT);
OnPreviewClose(); // force close of Preview
}
以及重写的·MyPreviewView.h
//MyPreviewView.h
#if !defined(AFX_MYPREVIEWVIEW_H__9FCA8680_907C_11D3_8412_9D0C7145F5C4__INCLUDED_)
#define AFX_MYPREVIEWVIEW_H__9FCA8680_907C_11D3_8412_9D0C7145F5C4__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MyPreviewView.h : header file
//
#include <afxpriv.h>
/
// CMyPreviewView view
class CMyPreviewView : public CPreviewView
{
protected:
CMyPreviewView(); // protected constructor used by dynamic creation
virtual ~CMyPreviewView();
DECLARE_DYNCREATE(CMyPreviewView)
public:
friend class CWrapperView;
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView);
// Implementation
protected:
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
virtual void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView);
// Generated message map functions
afx_msg void OnPreviewClose();
afx_msg void OnPreviewPrint();
friend BOOL CALLBACK _AfxMyPreviewCloseProc(CFrameWnd* pFrameWnd);
DECLARE_MESSAGE_MAP()
};
/
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MYPREVIEWVIEW_H__9FCA8680_907C_11D3_8412_9D0C7145F5C4__INCLUDED_)
最后需要调用打印预览界面地方加上
m_PreFrame = new CMainFF(DRWAPRINTER, 0, 0, FALSE);//zzy 230908 新打印预览的单文档创建
if (!m_PreFrame) return false;
m_PreFrame->ShowWindow(SW_SHOWNORMAL);//SW_SHOWNORMAL
DRWAPRINTER是导入数据的函数,放在调用打印预览函数的上方即可
void DRWAPRINTER(CDC* pDC, CPrintInfo* pInfo, void* pVoid)
{
CWrapperView wrapview;// 生成的打印预览数据读取
wrapview.OnPrint(pDC, pInfo);
}
这个方法其实是有一个问题,菜单栏的关闭按钮我给隐藏了,因为点击会崩,没找到好方法处理,所有我直接关闭MainFF界面一起关闭了,有大神知道怎么解决望告知谢谢啦。新人代码不太严谨!