精华内容
下载资源
问答
  • vfp打印预览表单 vfp打印工具 直接调用
  • MFC文档/视图的应用程序,向导给了打印及打印预览的标准支持。使这类应用程序打印及打印预览工作得以简化。另一类对话框程序却没有相应支持,从MFC打印及打印预览的标准支持入手,可以在对话框程序中,增加三个类以...

    VS2017 MFC对话框程序打印及打印预览的实现


    花了一个星期,研究了网上大量的MFC对话框打印及打印预览功能的demo之后,网上现有的版本都比较旧,所以选中了几个版本,合并修改,得到这个比较完美的最新版本,编译无错,成功运行。
    MFC文档/视图的应用程序,向导给了打印及打印预览的标准支持。使这类应用程序打印及打印预览工作得以简化。另一类对话框程序却没有相应支持,从MFC打印及打印预览的标准支持入手,可以在对话框程序中,增加三个类以支持打印及打印预览,本文介绍了这三个类的实现。
    打印及打印预览是编写应用程序经常要解决的问题,为了理解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则将输出发送到程序窗口上方显示的预览窗口显示一个或两个打印页面的复制外观。利用上面加入的缺省打印支持,只能打印或预览图形的一个打印页面,一个页中放不下的部分则放弃,为了加强程序,使它打印整个图形,一页中放不下的部分放在另一页,可以通过覆盖几个打印期间调用的虚拟函数来完成。下图说明了整个打印和打印预览的过程,显示了每个虚拟函数在程序中哪个部分调用。注意每打印一个页面就要经历图中的一个循环。
    在这里插入图片描述

    二、对话框程序打印及打印预览的实现
    以上是基于文档/视图的应用程序的打印原理,可以根据需要从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后取消对象,打印只出现在文档打印版中的页头和页脚,如果打印输出与屏幕输出的外观不同, 在这里打印,而不是调用OnDraw
    CView::OnEndPrinting()调用Cgdi::DeleteObject删除OnBeginPrinting分配的对象

    1.用MFC应用向导创建对话框应用程序,设主对话框类为CPrintPreviewDlg,在主对话框上放一按钮,(标题:打印预览,ID:IDC_PRINTPREVIEW_BUTTON),用类向导增加其BN_CLICKED的消息响应函数OnPrintPreviewButton生成打印预览界面

    void CPrintPreviewDlg::OnPrintPreviewButton()
    {
        CPrintFrame* pf = new CPrintFrame(this);
    }
    

    2、增加新类:
    增加新类步骤:项目->增加新项->MFC->MFC类
    用ClassWizard新建CPrintFrame类(基类CFrameWnd),功能上相当于文档/视图的应用程序的框架窗口类。
    用ClassWizard新建CPrintView类(基类CScrollView),功能上相当于文档/视图的应用程序的视图类。
    增加CPrintPreviewView类(基类CPreviewView,注意在头其定义头文件中加入包含afxpriv.h),用于打印预览界面的视图类。(如果没有基类CPreviewView,只有CPreviewViewEx基类,手动将CPreviewViewEx类改成基类CPreviewView)

    3、对新生成的各类修改如下:
    CPrintFrame类:

    CPrintFrame.h:
    #define WM_BEGIN_PRINTING (WM_USER+1004)

    1、增加公有数据成员

    CPrintPreviewDlg*    m_pOldWnd;        // 用于保存主对话框对象;
    CPrintView*              m_pView;              // 用于保存视图类对象;
    

    2、重载构造函数,保存对主对话框对象指针,创建窗口
    CPrintFrame.h:

    CPrintFrame();           // 动态创建所使用的受保护的构造函数
    CPrintFrame(CPrintPreviewDlg* pOld);
    virtual ~CPrintFrame();
    

    CPrintFrame.cpp:

    
    CPrintFrame::CPrintFrame(CPrintPreviewDlg* pOld)
    {
        m_pOldWnd = pOld;
        if ( !Create(NULL, "打印预览", WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CRect(200, 200, 500, 500)))
            TRACE0("Failed to create view window! \n");
    }
    

    3、修改析构函数,让主对话框显示

    CPrintFrame::~CPrintFrame()
    {
        m_pOldWnd->ShowWindow(SW_SHOW);
    }
    

    4、添加打印模式函数,设置A4纸纵向打印或横向打印(可以选择使用)

    #define   DMORIENT_PORTRAIT                           1       //纵向  
    #define   DMORIENT_LANDSCAPE                        2       //横向
     
    void SetLandscapeMode(int   PrintMode)  
    {   
        PRINTDLG   pd;   
        pd.lStructSize=(DWORD)sizeof(PRINTDLG);   
        BOOL   bRet=AfxGetApp()->GetPrinterDeviceDefaults(&pd);   
        if(bRet)   
        {   
            //   protect   memory   handle   with   ::GlobalLock   and   ::GlobalUnlock  
            DEVMODE   FAR   *pDevMode=(DEVMODE   FAR   *)::GlobalLock(pd.hDevMode);
            pDevMode->dmPaperSize=DMPAPER_A4;   //将打印纸设置为A4   
            //   set   orientation   to   landscape   
            if(PrintMode==1)     //纵向打印   
                pDevMode->dmOrientation = DMORIENT_PORTRAIT;   
            else   if(PrintMode==2)    //横向打印   
                pDevMode->dmOrientation = DMORIENT_LANDSCAPE;       
            ::GlobalUnlock(pd.hDevMode);   
        }   
    }
    

    5、用类向导增加WM_Create消息处理函数(关联CPrintView视图对象;调用其OnFilePrintPreview函数进行打印预览(若要直接打印,可直接向其发送消息);隐藏主对话框。)

    int CPrintFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
    		return -1;
    	// TODO:  在此添加您专用的创建代码
    	CCreateContext context;
    	context.m_pNewViewClass = RUNTIME_CLASS(CPrintView);
    	context.m_pCurrentFrame = this;
    	context.m_pCurrentDoc = NULL;
    	context.m_pLastView = NULL;
    	m_pView = STATIC_DOWNCAST(CPrintView, CreateView(&context));
    
    	if (m_pView != NULL)
    	{
    		m_pView->ShowWindow(SW_SHOW);
    		SetActiveView(m_pView);
    		// SetLandscapeMode(DMORIENT_LANDSCAPE);
    	}
    
    	SetIcon(m_pOldWnd->GetIcon(FALSE), FALSE);
    	SetIcon(m_pOldWnd->GetIcon(TRUE), TRUE);
    	ShowWindow(SW_RESTORE);
    	CWinApp *pApp = AfxGetApp();
    	pApp->m_pMainWnd = this;
    	m_pView->OnFilePrintPreview();//打印预览
    	m_pView->SendMessageW(WM_COMMAND, ID_FILE_PRINT);  // 直接打印
    	m_pOldWnd->ShowWindow(SW_SHOW);
    	return 0;
    }
    

    6、添加WM_Close消息处理函数`

    void CPrintFrame::OnClose()
    {
        // TODO: Add your message handler code here and/or call default
        CPrintFrame* pf=(CPrintFrame*)::AfxGetMainWnd(); 
        CWinApp *pApp=AfxGetApp();
        pApp->m_pMainWnd = pf->m_pOldWnd; 
        pf->DestroyWindow();
        // CFrameWnd::OnClose();
    }
    

    7、添加WM_DESTROY消息处理函数

    {
    	if (m_pView != NULL)
    		m_pView->DestroyWindow();
    
    	CFrameWnd::OnDestroy();
    	CFrameWnd::OnDestroy();
    }
    

    CPrintView类:

    ①修改构造函数:将坐标射模式置为缺省模式。

    CPrintView::CPrintView()
     
    {
        m_nMapMode = MM_TEXT;
    }
    

    ②增加消息映射实现打印。

    BEGIN_MESSAGE_MAP(CPrintView, CScrollView)
    	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
    END_MESSAGE_MAP()
    
    

    ③重载虚函数OnPreparePrinting,调用DoPreparePrinting生成用于打印或打印预览的设备描述表。

    BOOL CPrintView::OnPreparePrinting(CPrintInfo* pInfo)
    {
    	return DoPreparePrinting(pInfo);
    }
    

    ④增加公有函数OnFilePrintPreview,调用DoPrintPreview实现打印预览,该函数需要传入四个参数:打印预览工具条资源ID,执行打印及打印预览的视图对象指针,打印预览界面视图类的 CRuntimeClass指针,打印预览状态类CPrintPreviewState对象指针。

    void CPrintView::OnFilePrintPreview()
    {
    	// TODO: 在此处添加实现代码.
    	CPrintPreviewState* pState = new CPrintPreviewState;
    	pState->lpfnCloseProc = _AfxPrintPreviewCloseProc; //设置打印预览窗口关闭时的调用函数
    	if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this, RUNTIME_CLASS(CPrintPreviewView), pState))
    	{
    		TRACE0("Error, DoPrintPreview failed. \n");
    		AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
    		delete pState;
    	}
    	
    }
    

    ⑤一些其他函数的实现

    void CPrintView::OnInitialUpdate()
    {
     
     CScrollView::OnInitialUpdate();
     CSize sizeTotal;
     // TODO: 计算此视图的合计大小
     sizeTotal.cx = sizeTotal.cy = 100;
     SetScrollSizes(MM_TEXT, sizeTotal);
     
    }
     
    void CPrintView::OnDraw(CDC* pDC)
    {
        CDocument* pDoc = GetDocument();
    }
     
    void CPrintView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
    {
    	// TODO: 在此添加专用代码和/或调用基类
    
    	CView::OnBeginPrinting(pDC, pInfo);
    	CPrintFrame *pFrame = (CPrintFrame *)GetParent();
    	pFrame->m_pOldWnd->SendMessage(WM_BEGIN_PRINTING, (WPARAM)pDC, (LPARAM)pInfo);
    }
    
    void CPrintView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
    {
    	// TODO: 在此添加专用代码和/或调用基类
    
    	CScrollView::OnEndPrinting(pDC, pInfo);
    	if (m_fontPrinter.m_hObject != NULL)
    		m_fontPrinter.DeleteObject();
    	return;
    }
    

    ⑥在PrintView.cpp文件中增加全局函数,_AfxMyPreviewCloseProc,当单击打印预览窗口关闭按钮时被调用。

    BOOL CPrintView::_AfxPrintPreviewCloseProc(CFrameWnd * pFrameWnd)
    {
    	ASSERT_VALID(pFrameWnd);
    	CPrintPreviewView* pView = (CPrintPreviewView*)pFrameWnd->GetDlgItem(AFX_IDW_PANE_FIRST);
    	ASSERT_KINDOF(CPreviewView, pView);
    	pView->OnPreviewClose();
    	return FALSE;
    }
    

    7、增加公有函数OnPrint(CDC* pDC, CPrintInfo* pInfo),添加自己需要打印的文字和图片。
    CPrintView.h:

    CDC* m_dc;
    	int m_page_v_margin;	//纵向边距
    	int m_page_h_margin;	//横向边距
    	int m_page_height;		//页高,包括margin
    	int m_page_width;		//页宽,包括margin
    	int m_current_y_pos;	//纵向当前打印到哪个位置了,如果到了页底部要调用EndPage重新开一页
    	int m_line_height;		//行高,包括字体高度和行间距
    	int m_v_dist;			//行间距
    	BOOL m_is_printing_page;//正在打印页
    	BOOL m_mission_started;	//打印任务已经开始
    	BOOL m_need_start_new_page;//需要开始新的一页
    	int m_max_page;			//总页码
    	int m_page_number;		//当前页码
    	int m_total_line_number; //要打印的内容的总行数,不包括页脚页眉,只包括数据行
    	int m_max_line_count_one_page;
    	CString m_doc_name;		//页眉文字
    

    CPrintView.cpp:

    void CPrintView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
    {
    	// TODO: 在此添加专用代码和/或调用基类
    
    	CScrollView::OnPrint(pDC, pInfo);
    	m_dc = pDC;
    	m_page_v_margin = 0;
    	m_page_h_margin = 0;
    	m_page_height = 0;
    	m_current_y_pos = 0;
    	m_line_height = 0;
    	m_is_printing_page = FALSE;
    	m_mission_started = FALSE;
    	m_page_number = 0;
    	m_max_page = 0;
    	m_total_line_number = 0;
    	m_v_dist = 2;
    	m_max_line_count_one_page = 0;
    	m_doc_name = AfxGetAppName();
    	m_need_start_new_page = TRUE;
    
    	TEXTMETRIC tm;
    	m_dc->GetTextMetrics(&tm);
    	m_line_height = tm.tmHeight + tm.tmInternalLeading;
    	m_page_v_margin = m_dc->GetDeviceCaps(LOGPIXELSY) / 2;
    	m_page_h_margin = m_dc->GetDeviceCaps(LOGPIXELSX) / 2;
    	m_page_height = m_dc->GetDeviceCaps(VERTRES);
    	m_page_width = m_dc->GetDeviceCaps(HORZRES);
    	m_current_y_pos = m_page_v_margin;
    	//求出页数
    	m_max_line_count_one_page = (int)((m_page_height - m_page_v_margin * 2 - 50) / (m_line_height + 50));
    	m_max_page = (int)(m_total_line_number / m_max_line_count_one_page);
    	if (m_max_page*m_max_line_count_one_page < m_total_line_number) m_max_page++;
    	//UINT gl_uNumOfPoints = 52;
    	//CDC* pDC   = (CDC*)wParam;
    	//CPrintInfo* pInfo = (CPrintInfo *)lParam;
    	int nPageNumber = pInfo->m_nCurPage;
    	int i, j;
    	CFont *pOldFont;
    	CFont DataFont;
    	DataFont.CreatePointFont(120, _T("宋体"), m_dc);
    	pOldFont = m_dc->SelectObject(&DataFont);
    	if (1)
    	{
    		TCHAR *pszTitle[200] = { _T("编号"),_T("数值1"),_T("数值2"),_T("数值3"),_T("数值4"),_T("数值5"),_T("数值6") };
    		pOldFont = m_dc->SelectObject(&DataFont);
    
    		//画矩形
    		m_dc->Rectangle(m_page_h_margin, m_page_v_margin, m_page_width - m_page_h_margin, m_page_height - m_page_v_margin);//bottom
    
    		for (int i = 0; i<7; i++)
    		{
    			m_dc->TextOut(
    				m_page_h_margin + 50 + i * (m_page_width - m_page_h_margin * 2) / 7,
    				4 * m_line_height,
    				CString(pszTitle[i]));
    		}
    		m_dc->SelectObject(pOldFont);
    	}
    }
    
    

    CPrintPreviewView类:

    手动修改添加类CPrintPreviewView继承CPreviewView类

    CPrintPreviewView.h:

    #pragma once
    #include "afxpriv.h"
    #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>
    // CPrintPreviewView 视图
    
    class CPrintPreviewView : public CPreviewView
    {
    	DECLARE_DYNCREATE(CPrintPreviewView)
    
    protected:
    	CPrintPreviewView();           // 动态创建所使用的受保护的构造函数
    	virtual ~CPrintPreviewView();
    public:
    #ifdef _DEBUG
    	virtual void AssertValid() const;
    #ifndef _WIN32_WCE
    	virtual void Dump(CDumpContext& dc) const;
    #endif
    #endif
    public:
    	afx_msg void OnPreviewClose();
    protected:
    	afx_msg void OnPreviewPrint();
    	DECLARE_MESSAGE_MAP()
    	virtual void OnDraw(CDC* pDC);
    	virtual void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView);
    };
    
    

    增加工具栏按钮的消息响应函数OnPreviewClose(),OnPreviewPrint() .cpp如下详尽代码

    #include "stdafx.h"
    #include "PrintPreview.h"
    #include "CPrintPreviewView.h"
    #include "CPrintFrame.h"
    
    
    // CPrintPreviewView
    
    IMPLEMENT_DYNCREATE(CPrintPreviewView, CPreviewView)
    
    CPrintPreviewView::CPrintPreviewView()
    {
    
    }
    
    CPrintPreviewView::~CPrintPreviewView()
    {
    }
    
    BEGIN_MESSAGE_MAP(CPrintPreviewView, CPreviewView)
    	ON_COMMAND(AFX_ID_PREVIEW_CLOSE, OnPreviewClose)
    	ON_COMMAND(AFX_ID_PREVIEW_PRINT, OnPreviewPrint)
    END_MESSAGE_MAP()
    
    
    // CPrintPreviewView 诊断
    
    #ifdef _DEBUG
    void CPrintPreviewView::AssertValid() const
    {
    	CPreviewView::AssertValid();
    }
    
    #ifndef _WIN32_WCE
    void CPrintPreviewView::Dump(CDumpContext& dc) const
    {
    	CPreviewView::Dump(dc);
    }
    void CPrintPreviewView::OnPreviewClose()
    {
    	CPrintFrame* pf = (CPrintFrame*)::AfxGetMainWnd();
    	CWinApp *pApp = AfxGetApp();
    	pApp->m_pMainWnd = pf->m_pOldWnd;
    	pf->DestroyWindow();
    }
    void CPrintPreviewView::OnPreviewPrint()
    {
    	m_pPrintView->SendMessage(WM_COMMAND, ID_FILE_PRINT);
    }
    #endif
    #endif //_DEBUG
    
    
    // CPrintPreviewView 消息处理程序
    
    
    void CPrintPreviewView::OnDraw(CDC* pDC)
    {
    	// TODO: 在此添加专用代码和/或调用基类
    	CPreviewView::OnDraw(pDC);
    
    	m_pToolBar->PostMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);// 控制条的命令状态更新
    }
    
    
    void CPrintPreviewView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView)
    {
    	// TODO: 在此添加专用代码和/或调用基类
    
    	CPreviewView::OnEndPrintPreview(pDC, pInfo, point, pView);
    }
    

    最终结果图;
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    程序链接:https://download.csdn.net/download/weixin_42403113/11069726

    展开全文
  • window.showModalDialog(theURL+"&ttime="+new Date().getTime(),wbxstr,"dialogWidth=986px;dialogHeight=600px;... 我的打印预览代码如下(打印没问题):          关注中,我现在也遇到这个问题

    window.showModalDialog(theURL+"&ttime="+new Date().getTime(),wbxstr,"dialogWidth=986px;dialogHeight=600px;center:yes;scroll:no;status:no");

      我的打印预览代码如下(打印没问题): 
    <OBJECT classid='CLSID:8856F961-340A-11D0-A96B-00C04FD705A2' height=0 id=wb name=wb width=0> </OBJECT> 
    <div style="margin-left:150px"> 
    <input type='button' name='Submit1' value='- 打印 -' οnclick='window.print();' class='noprint'/> 
    <input type='button' name='Submit2' value='-打印预览-' οnclick='wb.execwb(7,1);' class='noprint'/>  
       

    关注中,我现在也遇到这个问题了,楼主有没解决?有的话告诉一下哇。


    楼主,碰巧我们的一个项目也用到了,呵呵。这个问题可废了不少时间。 这样的,对于WebBrowser控件的定义,不要放到弹出的窗体b.html里,而放在执行showModalDialog命令的窗体里a.html里。 通过window.showModalDialog()传递给弹出来的窗口,然后再使用,就没有问题了。 a.html片段: HTML code
    <script> window.onunload = function(){ alert("window.onunload"); } function popup(){ window.showModalDialog('b.html',WebBrowser,'dialogHight:500px;dialogWidth:650px;center:yes;resizeable:no;help:no;status;no'); }</script>......<object id="WebBrowser" name="WebBrowser" classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2" height="0" width="0"> </object> 被弹出的窗体b.html片段 HTML code

    <script> var args=window.dialogArguments; var wb = args; function print(){ wb.ExecWB(6,6); } </script> 


    由于网站模块开发的需要 遇到在弹出的模态窗口中实现打印功能的问题 把自己的解决方法记录如下: 方法一、使用对象实现在弹出模态窗口后自动打印模态窗口中的内容 由于将对象放在弹出的模态窗口中无法实现打印功能,所以将对象放在弹出模态窗口的页面中。 view plaincopy to clipboardprint? parent.php: 上述代码可以实现打印功能,可是打印出的内容却是弹出模态窗口的页面的内容而不是模态窗口的内容。一直没有找到解决的方法,还望有解决方法的朋友可以帮忙。 方法二、在弹出的模态窗口中添加打印按钮,点击打印按钮后改变按钮的css属性(为避免把按钮打印出来),使用window.print()来打印模态窗口中的内容。

    解决方法: a.aspx 中window.showModalDialog 调用方法传递 dialogArguments属性为 window 对象 window.showModalDialog("b.aspx",window,"....") ; b.aspx 中 var openobj = window; if(typeof(window.dialogArguments) == "object") { openobj = window.dialogArguments; } openobj.open("c.aspx"); 这样处理 c.aspx中 Session就不会丢失了绝对管用,我用过了

    解决方法:通过window.open()打开子页面,就可以正常使用IE的打印预览,打印了。通过opener.method()可以调用父窗口方法与子窗口通信,简单来说就是可以把父窗口的数据传入子窗口
    展开全文
  • 另一类对话框程序却没有相应支持,从MFC打印及打印预览的标准支持入手,可以在对话框程序中,增加三个类以支持打印及打印预览,本文介绍了这三个类的实现。  打印及打印预览是编写应用程序经常要解决的问题,为了...

    张明奇(卡哥)注释:成功版本

            MFC文档/视图的应用程序,向导给了打印及打印预览的标准支持。使这类应用程序打印及打印预览工作得以简化。另一类对话框程序却没有相应支持,从MFC打印及打印预览的标准支持入手,可以在对话框程序中,增加三个类以支持打印及打印预览,本文介绍了这三个类的实现。

            打印及打印预览是编写应用程序经常要解决的问题,为了理解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)
    --------------------- 
    作者:卡哥 
    来源:CSDN 
    原文:https://blog.csdn.net/L_Andy/article/details/8071768 
    版权声明:本文为博主原创文章,转载请附上博文链接!
    CView::OnBeginPrinting()分配专门用于打印的字体,画笔、画刷和其它对象,根据设备描述表计算并设置文档长,在设备描述表上存放所需的消息(这是第一个访问设备描述表的的虚拟函数)
    CView::OnPrepareDC()设置打印当前页面的文本或图形属性,修改视图原点,以打印当前页面,如果没有设置文档长度,在文档末尾终止打印循环(CprintInfo::m_bContinuePrinting赋值FALSE)
    CView::OnPrint()调用OnDraw进行输出;调用OnDraw前选择OnBeginPrinting分配的字体,调用OnDraw后取消对象,打印只出现在文档打印版中的页头和页脚,如果打印输出与屏幕输出的外观不同, 在这里打印,而不是调用OnDraw
    CView::OnEndPrinting()调用Cgdi::DeleteObject删除OnBeginPrinting分配的对象

     1.用MFC应用向导创建对话框应用程序,设主对话框类为CPrintPreviewDlg,在主对话框上放一按钮,(标题:打印预览,ID:IDC_PRINTPREVIEW_BUTTON),用类向导增加其BN_CLICKED的消息响应函数OnPrintPreviewButton生成打印预览界面
     

    void CPrintPreviewDlg::OnPrintPreviewButton()
    {
        CPrintFrame* pf = new CPrintFrame(this);
    }

          2、增加新类:

    用ClassWizard新建CPrintFrame类(基类CFrameWnd),功能上相当于文档/视图的应用程序的框架窗口类。
    用ClassWizard新建CPrintView类(基类CScrollView),功能上相当于文档/视图的应用程序的视图类。
    增加CPrintPreviewView类(基类CPreviewView,注意在头其定义头文件中加入包含afxpriv.h),用于打印预览界面的视图类。

            3、对新生成的各类修改如下:

    CPrintFrame类:

    ①增加公有数据成员

    CPrintPreviewDlg*    m_pOldWnd;        // 用于保存主对话框对象;
    CPrintView*              m_pView;              // 用于保存视图类对象;

    ②重载构造函数,保存对主对话框对象指针,创建窗口

    CPrintFrame::CPrintFrame(CPrintPreviewDlg* pOld)
    {
        m_pOldWnd = pOld;
        if ( !Create(NULL, "打印预览", WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CRect(200, 200, 500, 500)))
            TRACE0("Failed to create view window! \n");
    }
    

    ③修改析构函数,让主对话框显示'

    CPrintFrame::~CPrintFrame()
    {
        m_pOldWnd->ShowWindow(SW_SHOW);
    }

    ④添加打印模式函数,设置A4纸纵向打印或横向打印(可以选择使用)

    #define   DMORIENT_PORTRAIT                           1       //纵向  
    #define   DMORIENT_LANDSCAPE                        2       //横向
    
    void SetLandscapeMode(int   PrintMode)  
    {   
        PRINTDLG   pd;   
        pd.lStructSize=(DWORD)sizeof(PRINTDLG);   
        BOOL   bRet=AfxGetApp()->GetPrinterDeviceDefaults(&pd);   
        if(bRet)   
        {   
            //   protect   memory   handle   with   ::GlobalLock   and   ::GlobalUnlock  
            DEVMODE   FAR   *pDevMode=(DEVMODE   FAR   *)::GlobalLock(pd.hDevMode);
            pDevMode->dmPaperSize=DMPAPER_A4;   //将打印纸设置为A4   
            //   set   orientation   to   landscape   
            if(PrintMode==1)     //纵向打印   
                pDevMode->dmOrientation = DMORIENT_PORTRAIT;   
            else   if(PrintMode==2)    //横向打印   
                pDevMode->dmOrientation = DMORIENT_LANDSCAPE;       
            ::GlobalUnlock(pd.hDevMode);   
        }   
    }  
    

    ⑤用ClassWizard增加WM_Create消息处理函数,关联CPrintView视图对象;调用其OnFilePrintPreview函数进行打印预览(若要直接打印,可直接向其发送消息);隐藏主对话框。

    nt CPrintFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
            return -1;
     
            // TODO: Add your specialized creation code here
            CCreateContext context;
            context.m_pNewViewClass = RUNTIME_CLASS(CPrintView);
            context.m_pCurrentFrame = this;
            context.m_pCurrentDoc = NULL;
            context.m_pLastView = NULL;
            m_pView = STATIC_DOWNCAST(CPrintView, CreateView(&context));
     
            if (m_pView != NULL)
            {
                m_pView->ShowWindow(SW_SHOW);
                SetActiveView(m_pView);
           //   SetLandscapeMode(DMORIENT_LANDSCAPE);
            }
    
            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;
    }
    

    ⑥添加WM_Close消息处理函数

    void CPrintFrame::OnClose()
    {
        // TODO: Add your message handler code here and/or call default
        CPrintFrame* pf=(CPrintFrame*)::AfxGetMainWnd(); 
        CWinApp *pApp=AfxGetApp();
        pApp->m_pMainWnd = pf->m_pOldWnd; 
        pf->DestroyWindow();
        // CFrameWnd::OnClose();
    }
    

    CPrintView类:

    ①修改构造函数:将坐标射模式置为缺省模式。

    CPrintView::CPrintView()
    
    {
        m_nMapMode = MM_TEXT;
    
    }

    ②增加消息映射实现打印。

    ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)

    ③重载虚函数OnPreparePrinting,调用DoPreparePrinting生成用于打印或打印预览的设备描述表。

    BOOL CPrintView::OnPreparePrinting(CPrintInfo* pInfo)
    {
        // TODO: call DoPreparePrinting to invoke the Print dialog box
        //pInfo->SetMaxPage(1);
        return DoPreparePrinting(pInfo);
        // return CLogScrollView::OnPreparePrinting(pInfo);
    }
    

     

    ④增加公有函数OnFilePrintPreview,调用DoPrintPreview实现打印预览,该函数需要传入四个参数:打印预览工具条资源ID,执行打印及打印预览的视图对象指针,打印预览界面视图类的 CRuntimeClass指针,打印预览状态类CPrintPreviewState对象指针。
     

    void CPrintView::OnFilePrintPreview()
    {
        CPrintPreviewState* pState = new CPrintPreviewState;
        pState->lpfnCloseProc = _AfxPrintPreviewCloseProc; //设置打印预览窗口关闭时的调用函数
        if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this, RUNTIME_CLASS(CPrintPreviewView), pState))
        {
            TRACE0("Error, DoPrintPreview failed. \n");
            AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
            delete pState;
        }
    }
    

    ⑤一些其他函数的实现

    void CPrintView::OnInitialUpdate()
    {
    
     CScrollView::OnInitialUpdate();
    
     CSize sizeTotal;
     // TODO: 计算此视图的合计大小
     sizeTotal.cx = sizeTotal.cy = 100;
     SetScrollSizes(MM_TEXT, sizeTotal);
    
    }
    
    void CPrintView::OnDraw(CDC* pDC)
    {
        CDocument* pDoc = GetDocument();
        // TODO: add draw code here
    }
    
    void CPrintView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
    {
        // m_rectPrint = pInfo->m_rectDraw; 
    
        //进行打印的内容代码等;
        CLogScrollView::OnPrint(pDC, pInfo);
    }
    

    ⑥在PrintView.cpp文件中增加全局函数,_AfxMyPreviewCloseProc,当单击打印预览窗口关闭按钮时被调用。

    BOOL CALLBACK _AfxPrintPreviewCloseProc(CFrameWnd* pFrameWnd)
    {
        ASSERT_VALID(pFrameWnd);
        CPrintPreviewView* pView = (CPrintPreviewView*)pFrameWnd->GetDlgItem(AFX_IDW_PANE_FIRST);
        ASSERT_KINDOF(CPreviewView, pView);
        pView->OnPreviewClose();
        return FALSE;
    }
    

    CPrintPreviewView类:

    手动添加类CPrintPreviewView继承CPreviewView类,.h文件如下~

    #pragma once
    #include "afxpriv.h"
    
    #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 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_)
    
    增加工具栏按钮的消息响应函数OnPreviewClose(),OnPreviewPrint() .cpp如下详尽代码
    
    #include "stdafx.h"
    #include ".\mypreviewview.h"
    #include "StatisticsCoverDlg.h"
    #include ".\statisticscoverdlg.h"
    #include  "PrintFrame.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()
    {
     CPrintFrame* pf=(CPrintFrame*)::AfxGetMainWnd();
     CWinApp *pApp=AfxGetApp();    
     pApp->m_pMainWnd=pf->m_pOldWnd;
     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扩展动态链接库,以方便加入到程序中。
            打完收功~~
     

    展开全文
  • MFC文档/视图的应用程序,向导给了打印及打印预览的标准支持。使这类应用程序打印及打印预览工作得以简化。另一类对话框程序却没有相应支持,从MFC打印及打印预览的标准支持入手,可以在对话框程序中,增加三个类以...
           MFC文档/视图的应用程序,向导给了打印及打印预览的标准支持。使这类应用程序打印及打印预览工作得以简化。另一类对话框程序却没有相应支持,从MFC打印及打印预览的标准支持入手,可以在对话框程序中,增加三个类以支持打印及打印预览,本文介绍了这三个类的实现。 
    

           打印及打印预览是编写应用程序经常要解决的问题,为了理解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类的虚拟函数来定制文档/视图应用程序的打印及打印预览。在实际中,有很多基于对话框的应用程序,也需要提供打印及打印预览。但向导没有给基于对话框应用程序的基本支持。有了以上知识,可以构造出无文档的视图类,具体的实现时,增加三个类,用以支持打印及打印预览。以下用一具体实例说明。

            1、函数名() 覆盖函数可能完成的任务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应用向导创建对话框应用程序,设主对话框类为CPrintPreviewDlg,在主对话框上放一按钮,(标题:打印预览,ID:IDC_PRINTPREVIEW_BUTTON),用类向导增加其BN_CLICKED的消息响应函数OnPrintPreviewButton生成打印预览界面

    void CPrintPreviewDlg::OnPrintPreviewButton()
    {
        CPrintFrame* pf = new CPrintFrame(this);
    }

            2、增加新类:

    用ClassWizard新建CPrintFrame类(基类CFrameWnd),功能上相当于文档/视图的应用程序的框架窗口类。
    用ClassWizard新建CPrintView类(基类CLogScrollView),功能上相当于文档/视图的应用程序的视图类。
    增加CPrintPreviewView类(基类CPreviewView,注意在头其定义头文件中加入包含),用于打印预览界面的视图类。

            3、对新生成的各类修改如下:

    CPrintFrame类:

    ①增加公有数据成员

    CPrintPreviewDlg*    m_pOldWnd;        // 用于保存主对话框对象;
    CPrintView*              m_pView;              // 用于保存视图类对象;

    ②重载构造函数,保存对主对话框对象指针,创建窗口

    CPrintFrame::CPrintFrame(CPrintPreviewDlg* pOld)
    {
        m_pOldWnd = pOld;
        if ( !Create(NULL, "打印预览", WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CRect(200, 200, 500, 500)))
            TRACE0("Failed to create view window! ");
    }

    ③修改析构函数,让主对话框显示

    CPrintFrame::~CPrintFrame()
    {
        m_pOldWnd->ShowWindow(SW_SHOW);
    }

    ④添加打印模式函数,设置A4纸纵向打印或横向打印

    #define   DMORIENT_PORTRAIT                           1       //纵向  
    #define   DMORIENT_LANDSCAPE                        2       //横向

    void SetLandscapeMode(int   PrintMode)  
    {  
        PRINTDLG   pd;  
        pd.lStructSize=(DWORD)sizeof(PRINTDLG);  
        BOOL   bRet=AfxGetApp()->GetPrinterDeviceDefaults(&pd);  
        if(bRet)  
        {  
            //   protect   memory   handle   with   ::GlobalLock   and   ::GlobalUnlock  
            DEVMODE   FAR   *pDevMode=(DEVMODE   FAR   *)::GlobalLock(pd.hDevMode);
            pDevMode->dmPaperSize=DMPAPER_A4;   //将打印纸设置为A4  
            //   set   orientation   to   landscape  
            if(PrintMode==1)     //纵向打印  
                pDevMode->dmOrientation = DMORIENT_PORTRAIT;  
            else   if(PrintMode==2)    //横向打印  
                pDevMode->dmOrientation = DMORIENT_LANDSCAPE;      
            ::GlobalUnlock(pd.hDevMode);  
        }  
    }  

    ⑤用ClassWizard增加WM_Create消息处理函数,关联CPrintView视图对象;调用其OnFilePrintPreview函数进行打印预览(若要直接打印,可直接向其发送消息);隐藏主对话框。

    int CPrintFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
            return -1;
     
            // TODO: Add your specialized creation code here
            CCreateContext context;
            context.m_pNewViewClass = RUNTIME_CLASS(CPrintView);
            context.m_pCurrentFrame = this;
            context.m_pCurrentDoc = NULL;
            context.m_pLastView = NULL;
            m_pView = STATIC_DOWNCAST(CPrintView, CreateView(&context));
     
            if (m_pView != NULL)
            {
                m_pView->ShowWindow(SW_SHOW);
                SetActiveView(m_pView);
                SetLandscapeMode(DMORIENT_LANDSCAPE);
            }

            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;
    }

    ⑥添加WM_Close消息处理函数

    void CPrintFrame::OnClose()
    {
        // TODO: Add your message handler code here and/or call default
        CPrintFrame* pf=(CPrintFrame*)::AfxGetMainWnd(); 
        CWinApp *pApp=AfxGetApp();
        pApp->m_pMainWnd = pf->m_pOldWnd; 
        pf->DestroyWindow();
        // CFrameWnd::OnClose();
    }

    CPrintView类:

    ①修改构造函数:设置打印区域矩形大小。

    CPrintView::CPrintView():m_rectPrint(0, 0, 16600, -11520)
    {
        // m_rectPrint 为CRect类,打印区域矩形大小
    }

     ②增加消息映射实现打印。

    ON_COMMAND(ID_FILE_PRINT, CLogScrollView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CLogScrollView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CLogScrollView::OnFilePrintPreview)

    ③重载虚函数OnPreparePrinting,调用DoPreparePrinting生成用于打印或打印预览的设备描述表。

    BOOL CPrintView::OnPreparePrinting(CPrintInfo* pInfo)
    {
        // TODO: call DoPreparePrinting to invoke the Print dialog box
        pInfo->SetMaxPage(1);
        return DoPreparePrinting(pInfo);
        // return CLogScrollView::OnPreparePrinting(pInfo);
    }

    ④增加公有函数OnFilePrintPreview,调用DoPrintPreview实现打印预览,该函数需要传入四个参数:打印预览工具条资源ID,执行打印及打印预览的视图对象指针,打印预览界面视图类的 CRuntimeClass指针,打印预览状态类CPrintPreviewState对象指针。

    void CPrintView::OnFilePrintPreview()
    {
        CPrintPreviewState* pState = new CPrintPreviewState;
        pState->lpfnCloseProc = _AfxPrintPreviewCloseProc; //设置打印预览窗口关闭时的调用函数
        if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this, RUNTIME_CLASS(CPrintPreviewView), pState))
        {
            TRACE0("Error, DoPrintPreview failed. \n");
            AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
            delete pState;
        }
    }

    ⑤一些其他函数的实现

    void CPrintView::OnInitialUpdate()
    {
        CLogScrollView::OnInitialUpdate();

        CSize sizeTotal(m_rectPrint.Width(), -m_rectPrint.Height());
        // TODO: calculate the total size of this view
        SetLogScrollSizes(sizeTotal);
    }

    void CPrintView::OnDraw(CDC* pDC)
    {
        CDocument* pDoc = GetDocument();
        // TODO: add draw code here
        ...... // 打印部分的实现 略掉了~~
    }

    void CPrintView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
    {
        // m_rectPrint = pInfo->m_rectDraw;
        // SetLogScrollSizes(CSize(m_rectPrint.Width(), -m_rectPrint.Height()));
     
        CLogScrollView::OnPrint(pDC, pInfo);
    }

    ⑥在PrintView.cpp文件中增加全局函数,_AfxMyPreviewCloseProc,当单击打印预览窗口关闭按钮时被调用。

    BOOL CALLBACK _AfxPrintPreviewCloseProc(CFrameWnd* pFrameWnd)
    {
        ASSERT_VALID(pFrameWnd);
        CPrintPreviewView* pView = (CPrintPreviewView*)pFrameWnd->GetDlgItem(AFX_IDW_PANE_FIRST);
        ASSERT_KINDOF(CPreviewView, pView);
        pView->OnPreviewClose();
        return FALSE;
    }

    CPrintPreviewView类:

    手动添加类CPrintPreviewView继承CPreviewView类,.h文件如下~

    #include   <afxpriv.h>
    class CPrintPreviewView : public CPreviewView  

        DECLARE_DYNCREATE(CPrintPreviewView)  
    public:  
        afx_msg void OnPreviewClose();
     
    protected:
        CPrintPreviewView();
        virtual ~CPrintPreviewView();

        void OnDraw(CDC* pDC);
        void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView);
        afx_msg void OnPreviewPrint();
        // virtual void PositionPage(UINT   nPage);

        DECLARE_MESSAGE_MAP()
    };
      

    增加工具栏按钮的消息响应函数OnPreviewClose(),OnPreviewPrint()

    ON_COMMAND(AFX_ID_PREVIEW_CLOSE, OnPreviewClose)
    ON_COMMAND(AFX_ID_PREVIEW_PRINT, OnPreviewPrint)

    void CPrintPreviewView::OnDraw(CDC *pDC)
    {
        CPreviewView::OnDraw(pDC); 
        m_pToolBar->PostMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);// 控制条的命令状态更新
    }

    void CPrintPreviewView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView)

        CPreviewView::OnEndPrintPreview(pDC, pInfo, point, pView); 
    }

    void CPrintPreviewView::OnPreviewClose()

        CPrintFrame* pf=(CPrintFrame*)::AfxGetMainWnd(); 
        CWinApp *pApp=AfxGetApp();
        pApp->m_pMainWnd = pf->m_pOldWnd; 
        pf->DestroyWindow();
    }

    void CPrintPreviewView::OnPreviewPrint()

        m_pPrintView->SendMessage(WM_COMMAND, ID_FILE_PRINT); 
    }

            至此,基于对话框应用程序的具有打印及打印预览的基本支持已经生成,完全由新生成的三个类来支持。正如上一部分介绍的,可以在CMyView类中定义CView类的几个在打印过程中虚拟函数(CView::OnPreparePrinting,CView::OnBeginPrinting,CView::OnPrepareDC,CView::OnPrint,CView::OnEndPrinting,具体内容可参见前一部分)来定制其打印或打印预览的内容。也可以将实现打印或打印预览新增的三个类,生成MFC扩展动态链接库,以方便加入到程序中。

    转自:http://cool.worm.blog.163.com/blog/static/64339006200911111431775/

    展开全文
  • vc++打印及打印预览功能的实现

    千次阅读 2010-02-01 15:23:00
    VC++对话框程序打印及打印预览的实现 发布单位:湖北三峡职业技术学院本站原创 提交日期:2006-8-1 16:43:32 阅读次数:4840 摘要: MFC文档/视图的应用程序,向导给了打印及打印预览的标准支持。使这类应用程序打印及...
  • 本文首先介绍了利用MFC提供的文档视图框架来实现一个打印程序,实现打印预览,在此基础上,同时通过对MFC源代码的深入探讨,提出了利用该方法在对话框上用MFC实现打印功能,结果表明,利用MFC实现打印不仅方便,而且...
  • VC++对话框程序打印及打印预览的实现摘要: MFC文档/视图的应用程序,向导给了打印及打印预览的标准支持。使这类应用程序打印及打印预览工作得以简化。另一类对话框程序却没有相应支持,从MFC打印及打印预览的标准...
  • pb打印:PB中打印预览的实现

    千次阅读 2009-04-25 16:45:00
    转载自计算机世界日报 (文/刘荣芳) 作为目前比较流行的数据库...需要编程实现,打印效果需要反复调整并打印输出,既效率低下,又浪费资源,如何让用户在打印报表前能预览报表打印效果呢? 1、 在原窗口内实现预览
  • PowerBuilder提供了程序开发过程中的数据打印预览,下面介绍在程序应用中实现打印预览通用方法。打印预览窗口w_preview一、下面讲述创建上述窗口的实现过程:1.创建一个新窗口W_preview,设置该窗口的类型(Window...
  • C#打印、打印预览、页面设置案例

    千次阅读 2009-11-17 13:04:00
    在Form1中添加菜单mainMenu1,一个richTextBox1(定义为Public),一个打印文档控件PrintDocument,名称为MyPrintDC。一个状态栏名称为myStatus。 菜单项有: 文件(mnFile){新建(mnNew),打开(mnOpen),保存(mnSave),
  • 这篇文章介绍的内容是QT如何实现调用打印机来打印html中的网页及文件,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下工程里用到 QWebView,所以要在.pro里加上 QT += webkit webkitwidgets打印用到...
  • 2.点 击菜单栏里的“定制工具”-“选项”按钮调用“选项”弹窗,即修改程序设置。打印路径-打印输出路径1.在“选项”弹窗里,我们切换到路径/文件页面,找到“打印路径-打印输出路径”下默认设置的文件夹。2....
  • QT调用打印机打印html网页及文件

    千次阅读 2018-04-19 11:45:43
    工程里用到 QWebView, 所以要在.pro里加上 QT += webkit webkitwidgets 打印用到了 QPrinter, 所以要在.pro里加上 qtHaveModule(printsupport): QT += printsupport 直接附上源码吧,当然也是...
  • *&---------------------------------------------------------------------* *& Report Z01MMF019 *& Author's name: CAIXIANG ... Program title: 采购订单打印 *& Date: ...
  • 传送门:http://dianziermu.iteye.com/blog/375992今天弄了下打印相关的的内容,主要是为了打印页面内容的时候不想同时打印出“打印按钮”。主要有五种方法(其中6为删除打印页眉页脚的例子): 1、打印前将style...
  • 介绍:通过pdf地址先将文件下载到本地,然后调用打印机打印,最后将下载的文件删除。  环境:windows系统。(windows64位)  windows系统中安装python3.6.2环境  资料:  O2S.Components.PDFRender4NET.dll...
  • 今天弄了下打印相关的的内容,主要是为了打印页面内容的时候不想同时打印出“打印按钮”。 主要有五种方法(其中6为删除打印页眉页脚的例子):   1、打印前将style隐藏,打印后再显示出来。该方法较简单,且...
  • 网页打印按钮的源代码

    千次阅读 2011-06-13 09:10:00
    网页打印按钮的源代码:javascript:window.print(); 可以用css控制 @media print .a {display:block} .b {display:hidden} 好像是这样。把你不想打印的部分class设为b 首先在网页中添加:     ...
  • 也谈WEB打印(二):简单的分析一下IE的打印原理并实现简单的打印预览 在《也谈WEB打印(-):目前的几种方式及我们的任务》中,分析了一下当前Web打印的几种方式以及我们所遇到的问题,并提出了我们的要求,本文...
  • ):目前的几种方式及我们的任务》中,分析了一下当前Web打印的几种方式以及我们所遇到的问题,并提出了我们的要求,本文简单的分析一下IE的打印原理,并实现简单的打印预览功能。 首先,我们介绍一下IE架构: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,728
精华内容 2,291
关键字:

命令按钮如何调用打印预览