基于对话框的图像打印程序

来源:互联网 发布:程序员修炼之道pdf网盘 编辑:程序博客网 时间:2024/05/18 18:45

DialogPrint

1      dialog based->DialogPrint

2      添加button, ID:IDC_PRINTIMG, Caption:打印图像

3      双击button,点击ok,建立OnPrintimg ()函数

4      添加新类CMainFrame.

ClassNiew->DialogPrint classes->右键New Class-> NameCMainFrame  Base class:CFrameWnd.点击OK

5      新带参数的构造函数.

MainFrame.h

添加

public

CMainFrame(DRAWFUN pDraw,CWnd*pOldW,CWnd* pCallW,BOOL bDirect,LPCTSTR stTitle=NULL);

同时添加

Public:

         CWnd*      pOldWnd;

         CWnd*      pCallWnd;

         DRAWFUN Draw;

         BOOL        bDirectPrint;

protected:

         CStatusBar  m_wndStatusBar;

         CToolBar    m_wndToolBar;

         CWrapperView  *m_pView;

MainFrame.cpp中添加

CMainFrame::CMainFrame(DRAWFUN pDraw,CWnd*pOldW,CWnd* pCallW,BOOL bDirect,LPCTSTR stTitle)

{

         Draw=pDraw;

         pOldWnd=pOldW;

         pCallWnd=pCallW;

         bDirectPrint=bDirect;

         CString ss;

         if(stTitle!=NULL)

                   ss=_T(stTitle);

         else

         {                

                  pOldW->GetWindowText(ss);

                   if(!ss.IsEmpty())

                            ss=ss+_T(" (预览)");

                   else

                            ss=ss+_T("打印预览");

         }

         if(!Create(NULL,ss,WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,CRect(200,200,500,500)))

                   //       if(!Create(NULL,ss,WS_OVERLAPPEDWINDOW ))//| FWS_ADDTOTITLE,CRect(200,200,500,500)))

                   TRACE0("Failed to create view window/n");

        

}

6           ClassView-> CMainFrame->右键Add Virtual Function…->OnCmdMsg->Add and Edit.

转到实现函数里添加

         // let the view have first crack at the command

         if (m_pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))

                   return TRUE;

ClassView-> CMainFrame->右键Add Virtual Function…->PreCreateWindow->Add and Edit.

转到实现函数里添加

         if( !CFrameWnd::PreCreateWindow(cs) )

                   return FALSE;

         // TODO: Modify the Window class or styles here by modifying

         //  the CREATESTRUCT cs

        

         cs.dwExStyle &= ~WS_EX_CLIENTEDGE;

         cs.lpszClass = AfxRegisterWndClass(0);

         return TRUE;

并注释掉

//       return CFrameWnd::PreCreateWindow(cs);

7      ClassView视图->CMainFrame->右键Add Windows Message Handle…->WM_CREATE-> Add and Edit. 转到实现函数里添加

         CCreateContext context;

         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(m_pView != NULL)

         {

                  if(!bDirectPrint)

                            m_pView->ShowWindow(SW_SHOW);

                   SetActiveView(m_pView);

         }      

         SetIcon(pOldWnd->GetIcon(FALSE),FALSE);

         SetIcon(pOldWnd->GetIcon(TRUE),TRUE);

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

                   pOldWnd->ShowWindow(SW_HIDE);

         }

8      添加新类CWrapperView.

ClassNiew->DialogPrint classes->右键New Class->弹出对话框中NameCWrapperView  Base class: CView.->OK

CWrapperView.h

将构造函数和析构函数全改为

public:

         CWrapperView();

         virtual ~CWrapperView();

CWrapperView.cpp构造函数中

         m_pFrameWnd = NULL;

         HDC hDC=::GetDC(m_hWnd);

         SetMapMode(hDC,MM_ISOTROPIC);

10        ClassView视图->CWrapperView->右键Add Virtual Function…->OnPrint->Add and Edit.

转到实现函数里添加

         if(pDC)

         {

                   CMainFrame* pf=(CMainFrame*)::AfxGetMainWnd();           

                   (*pf->Draw)(pDC,pInfo,(void*)pf->pCallWnd);             

         }

并注释掉

//       CView::OnPrint(pDC, pInfo);

ClassView视图->CWrapperView->右键Add Virtual Function…-> OnPreparePrinting ->Add and Edit.

转到实现函数里添加

return DoPreparePrinting(pInfo);

并注释掉

//       return CView::OnPreparePrinting(pInfo);

Add Virtual Function…-> OnEndPrinting ->Add and Edit.

11    CWrapperView.cpp中寻找段落

BEGIN_MESSAGE_MAP(CWrapperView, CView)

         //{{AFX_MSG_MAP(CWrapperView)

                   // NOTE - the ClassWizard will add and remove mapping macros here.

                   ON_COMMAND(ID_FILE_PRINT, OnFilePrint)

         //}}AFX_MSG_MAP

END_MESSAGE_MAP()

其中ON_COMMAND(ID_FILE_PRINT, OnFilePrint)为添加内容。

CWrapperView.h中寻找段落

protected:

     //{{AFX_MSG(CWrapperView)

              // NOTE - the ClassWizard will add and remove member functions here.

     afx_msg void OnFilePrint();

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

其中afx_msg void OnFilePrint();为添加内容。

12    在主对话框头文件DialogPrintDlg.h中添加

#include "mainframe.h"

13    DialogPrintDlg.cpp添加

// CDialogPrintDlg dialog

void Drawf(CDC* pDC,CPrintInfo* pInfo,void* pVoid=NULL);

同时添加

void Drawf(CDC* pDC,CPrintInfo* pInfo,void* pVoid)

{      

         ((CControlDlg*)pVoid)->OnPrint(pDC,pInfo);       

}

14    OnPrintimg ()中添加

m_PreFrame = new CMainFrame(Drawf,this,this,TRUE);

15    MainFrame.h中添加

#include "wrapperview.h"

16    StdAfx.h中添加

typedef void(*DRAWFUN)(CDC* pDC,CPrintInfo* pInfo,void* pVoid=NULL);

17    ClassView->CDialogPrintDlg右键->Add Member Function…->void OnPrint(CDC* pDC,CPrintInfo* pInfo)->OK

实现函数内添加(图像的加载方式各异,本例实现方法为CxImage类)

         CDC          MemDC; // 内存设备环境指针,在视的整个存在过程都将存在

         CBitmap      Bitmap,*pOldBmp,Bitmap2;     

         CRect        Source, Dest,Source2, Dest2; // 记录源位图尺寸和最终显示尺寸

         BITMAP       bm;

         CxImage              showimage;

         showimage.Load("E://bear.bmp",CXIMAGE_SUPPORT_BMP);

        

         ///////////////////////////////////////////////////////////////

         if(MemDC.GetSafeHdc() == NULL)

         {

                  

                   HBITMAP hbitmap=showimage.MakeBitmap();

                   Bitmap.Attach(hbitmap);

                  

                   Bitmap.GetObject(sizeof(bm),&bm);

                   MemDC.CreateCompatibleDC(pDC);

                   pOldBmp=MemDC.SelectObject(&Bitmap);

                  

                   Source.top=0;

                   Source.left=0;

                   Source.right= bm.bmWidth;

                   Source.bottom = bm.bmHeight;

                  

                   Dest = Source;

         }

        

         CDC* DC=GetWindowDC();

         int iLogPixelX=DC->GetDeviceCaps(LOGPIXELSX);

         int iLogPixelY=DC->GetDeviceCaps(LOGPIXELSY);

        

         pDC->DPtoLP(&Dest);

         if(pDC->IsPrinting())

         {

                   Dest.left=(int)(Dest.left*((double)pDC->GetDeviceCaps(LOGPIXELSX))/iLogPixelX);

                   Dest.right=(int)(Dest.right*((double)pDC->GetDeviceCaps(LOGPIXELSX))/iLogPixelX);

                   Dest.top=(int)(Dest.top*((double)pDC->GetDeviceCaps(LOGPIXELSY))/iLogPixelY);

                   Dest.bottom=(int)(Dest.bottom*((double)pDC->GetDeviceCaps(LOGPIXELSY))/iLogPixelY);

         }

        

         pDC->StretchBlt(Dest.left, Dest.top, Dest.right, Dest.bottom,

                  

                   &MemDC, Source.left, Source.top, Source.right,Source.bottom, SRCCOPY);

        

         //textout

         CString       strPrint=_T("The image is printed!");

         CFont        m_font,*OldFont;

         m_font.CreatePointFont(800,"隶书");

         OldFont=pDC->SelectObject(&m_font);

         pDC->TextOut(Dest.right/2,Dest.bottom,strPrint); 

18    DialogPrintDlg.h中添加

Public

 CMainFrame *m_PreFrame;

19        WrapperView.cpp#include "MainFrame.h"

至于架构理论上为什么这样,暂时我也没搞明白,基于对话框的打印还是得通过一个FrameView实现,我也是根据几篇文章以及论文,还有几个例子捣鼓出来的,对于出处,如有雷同引用,敬请海涵或联系。反正能实现基于对话框的图像打印功能了,只不过是单幅图像的打印,不能实现多页打印,在此基础上可以进行扩展,重载CWrapperView几个打印函数,可以实现多页或者预览打印吧,不过没研究,想做的可以在这个程序的基础上设上断点debug下,会走到底层的打印函数去,可能对于重载有帮助吧。

 

原创粉丝点击