vc++列印及列印預覽功能的實現
VC++對話方塊程式列印及列印預覽的實現
釋出單位:湖北三峽職業技術學院本站原創 提交日期:2006-8-1 16:43:32 閱讀次數:4840
摘要: MFC文件/檢視的應用程式,嚮導給了列印及列印預覽的標準支援。使這類應用程式列印及列印預覽工作得以簡化。另一類對話方塊程式卻沒有相應支援,從MFC列印及列印預覽的標準支援入手,可以在對話方塊程式中,增加三個類以支援列印及列印預覽,本文介紹了這三個類的實現。
關鍵詞: 列印;列印預覽;虛擬函式;過載
中圖分類號: TP312文獻標識碼: A文章編號: 2027/YC-(2006)01-0060-05
列印及列印預覽是編寫應用程式經常要解決的問題,為了理解VC++
一、基於文件/檢視的應用程式的列印及列印預覽原理
VC++基於文件/檢視的應用程式中用MFC應用程式嚮導在步驟4對話方塊中選中Print and Print Preview選項,可以包含基本列印及列印預覽的支援,應用程式檔案選單中會生成兩個選單項分別是列印(識別符號ID_FILE_PRINT)和列印預覽(識別符號:ID_FILE_PRINT_PREVIEW),展開程式原始碼,可以發現,是CVIEW類提供標準列印和列印預覽選單命令的訊息處理函式:
設應用程式檢視類為CMyView,展開MyView.cpp,
ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview)
CView::OnFilePrint 和CView::OnFilePrintPreview函式都進行列印操作,但View::OnFilePrint將實際傳送到印表機,而CView::OnFilePrintPreview則將輸出傳送到程式視窗上方顯示的預覽視窗顯示一個或兩個列印頁面的複製外觀。利用上面加入的預設列印支援,只能列印或預覽圖形的一個列印頁面,一個頁中放不下的部分則放棄,為了加強程式,使它列印整個圖形,一頁中放不下的部分放在另一頁,可以通過覆蓋幾個列印期間呼叫的虛擬函式來完成。下圖說明了整個列印和列印預覽的過程,顯示了每個虛擬函式在程式中哪個部分呼叫。注意每列印一個頁面就要經歷圖中的一個迴圈。
下表列出了虛擬函式並介紹了各自完成的任務,由於MFC列印或列印預覽文件時都呼叫虛擬函式,所以定義的覆蓋函式既影響列印也影響列印預覽。
二、對話方塊程式列印及列印預覽的實現
以上是基於文件/檢視的應用程式的列印原理,可以根據需要從CView類派生出檢視類覆蓋列印及列印預覽過程中的CView類的虛擬函式來定製文件/檢視應用程式的列印及列印預覽。在實際中,有很多基於對話方塊的應用程式,也需要提供列印及列印預覽。但嚮導沒有給基於對話方塊應用程式的基本支援。有了以上知識,可以構造出無文件的檢視類,具體的實現時,增加三個類,用以支援列印及列印預覽。以下用一具體例項說明。
函式名[]覆蓋函式可能完成的任務CView::OnPreparePrinting[]呼叫CprintInfo成員函式(如CprintInfo::SetMaxPage設定文件長度)或設定CprintInfo資料成員以影響Print對話方塊或列印預覽操作,然後呼叫DoPreparePrinting生成用於列印或列印預覽的裝置描述表(注意必須覆蓋OnPreparePrinting並呼叫DoPreparePrinting)CView::OnBeginPrinting[]分配專門用於列印的字型,畫筆、畫刷和其它物件,根據裝置描述表計算並設定文件長,在裝置描述表上存放所需的訊息(這是第一個訪問裝置描述表的的虛擬函式)CView::OnPrepareDC[]設定列印當前頁面的文字或圖形屬性,修改檢視原點,以列印當前頁面,如果沒有設定文件長度,在文件末尾終止列印迴圈(CprintInfo::m_bContinuePrinting賦值FALSE)CView::OnPrint[]呼叫OnDraw進行輸出;呼叫OnDraw前選擇OnBeginPrinting分配的字型,呼叫OnDraw後取消物件,列印只出現在文件列印版中的頁頭和頁尾,如果列印輸出與螢幕輸出的外觀不同, 在這裡列印,而不是呼叫OnDrawCView::OnEndPrinting[]呼叫Cgdi::DeleteObject刪除OnBeginPrinting分配的物件1.用MFC應用嚮導建立對話方塊應用程式,設主對話方塊類為CMyPrintPreviewDlg,在主對話方塊上放一按鈕,(標題:列印預覽,ID:IDC_BUTTON1),用類嚮導增加其BN_CLICKED的訊息響應函式OnButton1生成列印預覽介面
void CMyPrintPreviewDlg::OnButton1()
{
CMyFrame* pf=new CMyFrame(this);// TODO: Add your control notification handler code here
}
2、增加新類:
用ClassWizard新建CMyFrame類(基類CFrameWnd),功能上相當於文件/檢視的應用程式的框架視窗類
用ClassWizard新建CMyView類(基類CScrollView),功能上相當於文件/檢視的應用程式的檢視類。
增加CMyPreviewView類(基類CPreviewView,注意在頭其定義標頭檔案中加入包含afxpriv.h),用於列印預覽介面的檢視類。
3、對新生成的各類修改如下:
CMyFrame類:
①增加公有資料成員
CMyPrintPreviewDlg*m_pOldWnd:用於儲存主對話方塊物件;
CMyView* m_pView:用於儲存檢視類物件;
②過載建構函式,儲存對主對話方塊物件指標,建立視窗
CMyFrame::CMyFrame(CMyPrintPreviewDlg* pOld)
{
m_pOldWnd= pOld;
if(!Create(NULL,“列印預覽”, WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,CRect(200,200,500,500)))
TRACE0(“Failed to create view window\n”);
}
③修改解構函式,讓主對話方塊顯示
CMyFrame::~CMyFrame()
{m_pOldWnd->ShowWindow(SW_SHOW);
}
④用ClassWizard增加WM_Create訊息處理函式,關聯CMyView檢視物件;呼叫其OnFilePrintPreview函式進行列印預覽(若要直接列印,可直接向其傳送訊息);隱藏主對話方塊。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
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;
}
修改CMyView類
①修改建構函式:將座標射模式置為預設模式。
CMyView::CMyView()
{
m_nMapMode = MM_TEXT;
}
②增加訊息對映實現列印。
ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint)
③過載虛擬函式OnPreparePrinting,呼叫DoPreparePrinting生成用於列印或列印預覽的裝置描述表。
BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
{
returnDoPreparePrinting(pInfo);
}
④增加公有函式OnFilePrintPreview,呼叫DoPrintPreview實現列印預覽,該函式需要傳入四個引數:列印預覽工具條資源ID,執行列印及列印預覽的檢視物件指標,列印預覽介面檢視類的 CRuntimeClass指標,列印預覽狀態類CPrintPreviewState物件指標。
void CMyView::OnFilePrintPreview( )
{
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;
}
}
⑤在Myview.cpp檔案中增加全域性函式,_AfxMyPreviewCloseProc,當單擊列印預覽視窗關閉按鈕時被呼叫。
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;
}
4、修改CMyPreviewView類,增加工具欄按鈕的訊息響應函式OnPreviewClose(),OnPreviewPrint(),由於此類較簡單,列出該類程式碼如下(注意粗體部分):
MyPreviewView.h
// MyPreviewView.h: interface for the CMyPreviewView class.
//
////////////////////////////////////////
#if !defined(AFX_MYPREVIEWVIEW_H__0AE8B670_B1AE_11DA_812E_00E04C39032F__INCLUDED_)
#define AFX_MYPREVIEWVIEW_H__0AE8B670_B1AE_11DA_812E_00E04C39032F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <afxpriv.h>
class CMyPreviewView : public CPreviewView
{
DECLARE_DYNCREATE(CMyPreviewView)
public:
afx_msg void OnPreviewClose();
protected:
CMyPreviewView();
virtual ~CMyPreviewView();
void OnDraw(CDC* pDC);
void CMyPreviewView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView);
afx_msg void OnPreviewPrint( );
DECLARE_MESSAGE_MAP( )
};
#endif // !defined(AFX_MYPREVIEWVIEW_H__0AE8B670_B1AE_11DA_812E_00E04C39032F__INCLUDED_)
MyPreviewView.cpp
// MyPreviewView.cpp: implementation of the CMyPreviewView class.
#include “stdafx.h”
#include “MyPrintPreviewDlg.h”
#include “MyPreviewView.h”
#include “MyFrame.h”
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////
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()
void CMyPreviewView::OnDraw(CDC *pDC)
{
CPreviewView::OnDraw(pDC);
m_pToolBar->PostMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);// 控制條的命令狀態更新
}
void CMyPreviewView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView)
{
CPreviewView::OnEndPrintPreview(pDC, pInfo, point, pView);
}
void CMyPreviewView::OnPreviewClose()
{
CMyFrame* pf=(CMyFrame*)::AfxGetMainWnd();
CWinApp *pApp=AfxGetApp();
pApp->m_pMainWnd=pf->m_pOldW;
pf->DestroyWindow();
}
void CMyPreviewView::OnPreviewPrint()
{
m_pPrintView->SendMessage(WM_COMMAND, ID_FILE_PRINT);
}
至此,基於對話方塊應用程式的具有列印及列印預覽的基本支援已經生成,完全由新生成的三個類來支援。正如上一部分介紹的,可以在CMyView類中定義CView類的幾個在列印過程中虛擬函式(CView::OnPreparePrinting,CView::OnBeginPrinting,CView::OnPrepareDC,CView::OnPrint,CView::OnEndPrinting,具體內容可參見前一部分)來定製其列印或列印預覽的內容。也可以將實現列印或列印預覽新增的三個類,生成MFC擴充套件動態連結庫,以方便加入到程式中。
參考文獻:
[1][美]Michael J. Young.Visual C++6從入門到精通[M].美國:電子工業出版社.
[2]
[3]MSDNLibrary Visual Studio 6.0 / VC++TNO30:Customizing printing and print preview
[責任編輯:楊子紅]
Realization of Printing and Print Preview in a Dialogue Program in vc++
YANG Wen- xue
(Information Engineering Department, Hubei Three Gorges Vocational and Technical College,Yichang 443000,Hubei,China )
Abstract: The application procedure and guide of MFC text or view provide standard support for printing and print preview,which makes printing and print preview of this kind of application procedure simplify ,but another kind of dialogue program doesn't get the corresponding support. Beginning with the standard support of printing and print preview of MFC,we can add three classifications to support the printing and print preview in a dialogue program. This article introduces the realization of these three classifications.
Key Words: printing and print preview;virtual function;recarrying