孫鑫VC++視頻學習筆記之11:圖形保存和重繪

轉自:http://webbery.tianyablog.com

  閱讀本文前,我們假設您已經:
   1,知道如何創建一個單文檔的App Wizard
   2,知道C++ 類、函數重載等簡單知識
   3,知道如何給View類或者Doc文檔添加成員變量
   4,會用MFC的IDE調試工具最好,那麼本文的程序您可以copy去調試
   5,知道如何爲某個框架類添加虛函數或消息處理函數
  
   
  
  1,透明畫刷
  
  CClientDC dc(this);
  
  CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
  
  dc.SelectObject(pBrush);
  
  2,保存繪製的圖像(窗口重繪時仍然存在)
  
  CGraphView類中添加m_ptOrigin,m_ptEnd,m_nDrawType三個變量,分別用於保存圖像起始點、終止點和圖像類型
  
  1)構造一個CGraph類,用於存放每個對象
  
  頭文件Graph.h
  
  #if !defined(AFX_GRAPH_H__)
  
  #define AFX_GRAPH_H__
  
  
  
  #if _MSC_VER > 1000
  
  #pragma once
  
  #endif // _MSC_VER > 1000
  
  
  
  class CGraph
  
  {
  
  public:
  
   UINT m_nDrawType;
  
   CPoint m_ptOrigin;
  
   CPoint m_ptEnd;
  
   CGraph();
  
   CGraph( UINT m_nDrawType,CPoint m_ptOrigin,CPoint m_ptEnd);
  
   virtual ~CGraph();
  
  
  
  };
  
  2),因爲不知道將會繪製多少圖像對象,用集合類來替代複雜的鏈表結構。View類中定義,添加
  
   CPtrArray m_ptArray;
  
  3),在OnLButtonDown和OnLButtonUp中分別保存兩個點,並在OnLButtonUp中添加以下語句,用集合類來保存圖像元素
  
  //CGraph graph(m_nDrawType,m_ptOrigin,m_ptEnd);這種方法是錯誤的,因爲局部變量將被銷燬
  
  CGraph *pGraph;
  
  pGraph = new CGraph(m_nDrawType,m_ptOrigin,m_ptEnd);//在堆中分配內存,不會被釋放,生命週期和進程一致,直至delete出現
  
  m_ptArray.Add(&graph);
  
  
  
  CPaintDC只能在WM_PAINT的消息相應中使用,其創建和析構調用BenginDC和EndDC
  
  CClientDC創建時調用GetDC,析構時調用ReleaseDC
  
  OnPrepareDC,對CScrollView調用OnPrepareDC會做調整,
  
  OnPaint()函數爲WM_PAINT的相應函數,如果沒有重載OnPaint函數,那麼OnPaint基函數是直接調用OnDraw函數。如果重載了OnPaint()函數,那麼只有在子類中OnPaint()的調用OnDraw()
  
  
  
  Win32應用程序接口(API)使用四種座標空間:世界座標系空間、頁面空間、設備空間、和物理設備空間。應用程序運用世界座標系空間對圖形輸出進行旋轉、斜切(扭曲)或者反射
  
   Win32 API把世界座標系空間和頁面空間成爲邏輯空間;作後一種座標空間(物理設備空間)通常指應用程序窗口的客戶區;但是它也包括整個桌面、完整的窗口(包括 框架、標題欄和菜單欄)或打印機的一頁或繪圖儀的一頁紙。物理設備的尺寸隨顯示器、打印機或繪圖儀所設置的尺寸而變化。
  
  如果要在物理設備上繪製輸出,windows把一個矩形區域從一個座標空間拷貝到(映射到)另一個座標空間,直至最終完整地輸出呈現在物理設備上(通常是屏幕或者打印機)
  
   如果該應用程序調用了SetWorldTransform函數,那麼映射就從應用程序的世界座標系空間開始;否則,映射在頁面控件中進行。在 Windows把矩形區域的每一點從一個空間拷貝到另一個空間時,它採用了一種被稱爲轉換的算法,轉換是把對象從一個座標空間拷貝到另一個座標空間時改變 (轉變)這一對象的刀削、方位、和形態,儘管轉換把對象看成一個整體,但它也作用於對象中的每一點或每條線。
  
  一個典型轉換的例子
  
  圖形旋轉、斜切的例子在MSDN中using Coordinate spaces and transformations中有TransformAndDraw函數的實現,可以仿照之。例如AutoCAD中對圖像的切割、旋轉、局部放大等。
  
  OnInitialUpdate,窗口創建完成後,第一個被調用的函數
  
  SetMapMode函數
  
  SetScrollSizes在窗口創建之後調用
  
  滾動窗口中重繪圖像時出現的圖形移動問題
  
  1,原因:重繪時調用了OnPrepareDC設置了視點座標
  
  2,保存數據時先調用OnPrepareDC調整,再調用DPtoLP轉換後,再保存,就可以了。
  
  
  
  另外兩種保存圖形數據的方法
  
  CMetaFileDC
  
  1,在View.h中添加定義
  
  CMetaFileDC m_dcMetaFile;
  
  2,在view的構造函數中初始化
  
  m_dcMetaFile.Create();
  
  3,在OnLButtonUp中將所有dc指針更換爲m_dcMetaFile
  
  4,在OnDraw中以前的繪圖語句註釋掉,添加以下
  
  HMETAFILE hmetaFile;
  
  hmetaFile=m_dcMetaFile.Close();
  
  pDC->PlayMetaFile(hmetaFile);//播放原文件
  
  m_dcMetaFile.Create();//新創建原文件,準備原文件設備上下文
  
  m_dcMetaFile.PlayMetaFile(hmetaFile);//把前面的原文件播放一遍,避免丟失。相當於保存以前的繪圖命令
  
  DeleteMetaFile(hmetaFile);//播放結束,釋放原文件句柄
  
  5,保存
  
  copyMetaFile
  
  1)保存語句
  
  HMETAFILE hmetaFile;
  
  hmetaFile=m_dcMetaFile.Close();
  
  CopyMetaFile(hmetaFile,"meta.wmf");
  
  m_dcMetaFile.Create();
  
  DeleteMetaFile(hmetaFile);
  
  2)打開圖形
  
  HMETAFILE hmetaFile;
  
  hmetaFile=GetMetaFile("meta.wmf");
  
  m_dcMetaFile.PlayMetaFile(hmetaFile);
  
  DeleteMetaFile(hmetaFile);
  
  Invalidate();
  
  
  
  利用兼容DC保存圖形
  
  1,在View中定義變量
  
  CDC m_dcCompatible;
  
  2,在OnLButtonUp中添加
  
  if(!m_dcCompatible.m_hDC)
  
  {
  
  m_dcCompatible.CreateCompatibleDC(&dc);
  
  CRect rect;
  
  GetClientRect(&rect);
  
  CBitmap bitmap;
  
  //用當前客戶區大小來創建兼容位圖
  
  bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
  
  //把兼容位圖選入兼容DC中。此位圖bitmap可以是普通位圖,也可以是兼容位圖
  
  m_dcCompatible.SelectObject(&bitmap);
  
  m_dcCompatible.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);
  
  m_dcCompatible.SelectObject(pBrush);
  
  }
  
  3,把OnLButtonUp中dc指針都換成m_dcCompatible
  
  已經建立好的基類爲CView的視類,改變爲有滾動條的視類,即CScroolView步驟
  
  1,將CXXXView的.h and .cpp文件中CView統統用CScrollView替換,注意類定義繼承的地方
  
  2,添加OnInitialUpdate,在其中添加滾動條的初始化。不做這一步的話,將運行出錯
  
  SetScrollSizes(MM_TEXT,CSize(800,600));

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章