Windows程式設計__孫鑫C++Lesson4《繪圖操作》

來源:互聯網
上載者:User

Windows程式設計__孫鑫C++Lesson4《繪圖操作》

本節要點:

1.訊息捕獲對象

2.MFC訊息映射機制

3.MFC繪圖操作

4.靜態成員函數與靜態變數

//*****************************************************************************

1.view類在架構類之上,因此架構類無法捕獲WM_LBUTTONDOWN訊息
2.MFC訊息映射
其中的一種思路是:基類定義所有的虛函數,但MFC類間關係複雜,不宜採用這種方式;
MFC訊息映射機制要點:
(1)訊息和具體視窗相關, MFC維護了一個控制代碼與c++類指標映射,通過控制代碼能找到C++類對象的指標;
(2)子類指標傳遞給基類,基類調用CWnd::WindowProc處理,其函數原型為:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
可以看出他們均為虛函數。在CWnd::WindowProc會調用CWnd::OnWndMsg處理;
(3)CWnd::OnWndMsg會通過訊息映射宏之間的函數原型聲明尋找訊息映射,如果子類沒有添加訊息響應則由父類處理.
MFC架構提供的宏實現訊息映射:
(1)注釋宏  表示函數原型是訊息響應的原型聲明
//{{AFX_MSG(CDrawView)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG

(2)訊息映射宏 ,關聯訊息響應函數
BEGIN_MESSAGE_MAP(CDrawView, CView)
//{{AFX_MSG_MAP(CDrawView)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
(3)添加訊息響應函數
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

CView::OnLButtonDown(nFlags, point);
}
3.MFC繪圖函數
(1)畫直線實現
//WIn32 SDK平台下實現
HDC hdc;
hdc=::GetDC(m_hWnd);//CDrawView從CWnd派生而來 m_hWnd儲存了控制代碼
::MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hdc,point.x,point.y);
::ReleaseDC(m_hWnd,hdc);
//*****************************************************************************

//MFC封裝的CDC類實現
    CDC* pDC=GetDC();
    pDC->MoveTo(m_ptOrigin);
    pDC->LineTo(point);
    ReleaseDC(pDC);
//*****************************************************************************

//用CClientDC實現
  //CClientDC DC關聯了客戶區
//CClientDC dc(this);//View類建立DC在客戶區作圖
/*CClientDC dc(GetParent());//構造主架構的DC在客戶區作圖
    dc.MoveTo(m_ptOrigin);
    dc.LineTo(point);*/
//*****************************************************************************

//用CWindowDC實現
          //CWindowDC 可訪問視窗的客戶區和非客戶區
  //CWindowDC dc(this);//View類建立DC在客戶區作圖
  //CWindowDC dc(GetParent());//在架構客戶區和非客戶區作圖
//CWindowDC dc(GetDesktopWindow());//dc與整個桌面視窗相關 可以在整個視窗作圖
      dc.MoveTo(m_ptOrigin);
      dc.LineTo(point);
//*****************************************************************************

//畫筆建立與選擇
    CClientDC dc(this);
    CPen pen(PS_SOLID,1,RGB(255,0,0));
    CPen *pOldPen=dc.SelectObject(&pen);
    dc.MoveTo(m_ptOrigin);
    dc.LineTo(point);
    dc.SelectObject(pOldPen);

作圖效果如:
//*****************************************************************************

//畫刷建立與填充矩
CClientDC dc(this);
CBrush brush(RGB(255,0,0));
dc.FillRect(CRect(m_ptOrigin,point),&brush); //傳遞畫刷指標時,不需要選中畫刷
//*****************************************************************************

//位元影像畫刷建立與填充矩形地區
    CClientDC dc(this);
    CBitmap  bitmap;
    bitmap.LoadBitmap(IDB_BITMAP1);//IDB_BITMAP1為位元影像的資源ID
    CBrush  brush(&bitmap);
    dc.FillRect(CRect(m_ptOrigin,point),&brush);

作圖效果如:


//*****************************************************************************

//透明畫刷(空話刷建立)
CClientDC dc(this);
CBrush * pBrush=CBrush::FromHandle( (HBRUSH)GetStockObject(NULL_BRUSH) );
CBrush * pOldBrush=dc.SelectObject(pBrush);
dc.Rectangle(CRect(m_ptOrigin,point));
dc.SelectObject(pOldBrush);

效果如:

//*****************************************************************************

關於ReleaseDC:
函數原型:  int ReleaseDC( CDC* pDC );
MSDN 注釋 The application must call the ReleaseDC method for each call to the GetWindowDC method and for each call to the GetDC method.
關於客戶區與非客戶區:
架構的客戶區從工具列開始向下,View類客戶區在工具列之下的地區,非客戶區包括標題列和功能表列.
(2)畫連續線
//****************************************************************************

//連續線條

  CClientDC dc(this);
  CPen pen(PS_SOLID,1,RGB(255,0,0));
  CPen *pOldPen=dc.SelectObject(&pen);
if(IsLbuttonDow)
{
  dc.MoveTo(m_ptOrigin);
  dc.LineTo(point);
  m_ptOrigin=point;//原點值更改
}
dc.SelectObject(pOldPen);

效果如:

(3)畫扇形
//*****************************************************************************

//扇形

CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(255,0,0));
CPen *pOldPen=dc.SelectObject(&pen);
if(IsLbuttonDow)
{
  dc.MoveTo(m_ptOrigin);
  dc.LineTo(m_ptOld);
        dc.MoveTo(m_ptOrigin);
  dc.LineTo(point);
  m_ptOld=point;
}
dc.SelectObject(pOldPen);
//*****************************************************************************

//帶邊線的扇形
CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(255,0,0));
CPen *pOldPen=dc.SelectObject(&pen);
if(IsLbuttonDow)
{        ////SetROP2 設定繪畫模式
  //dc.SetROP2(R2_MERGENOTPEN); 看不見線條
  //dc.SetROP2(R2_BLACK);//黑色
  dc.MoveTo(m_ptOrigin);
  dc.LineTo(m_ptOld);
        dc.MoveTo(m_ptOld);
  dc.LineTo(point);
  m_ptOld=point;
}
dc.SelectObject(pOldPen);

效果如:

4.靜態函數與靜態變數
在建立透明畫刷時,語句CBrush * pBrush=CBrush::FromHandle( (HBRUSH)GetStockObject(NULL_BRUSH) );中調用了CBrush類的靜態成員函數完成了指標轉換.
該函數原型為:static CBrush* PASCAL FromHandle( HBRUSH hBrush );
關於靜態成員函數與變數要點:
(1)靜態方法屬於類本身 不屬於具體對象  類載入時已經分配記憶體,可以再類外調用
(2)態成員變數必須在類的定義外部初始化,非靜態成員在類未執行個體化時尚未分配記憶體空間

Win32 Console Application Test.cpp 實驗代碼如下:

//*****************************************************************************

#include <iostream.h>
class Point
{
public:
     void output()
  {
        x=0;
  y=0;
        init();//可以引用靜態成員方法  從記憶體模型來考慮
  }
     static void init()//靜態方法  對象沒有產生之前已經存在於記憶體 而非靜態成員x,y尚未分配記憶體空間
  {
   //x=0,y=0;//  error C2597: illegal reference to data member 'Point::x' in a static member function
   a=0;//error LNK2001: unresolved external symbol "private: static int Point::b" (?b@Point@@0HA)
   b=0;//靜態成員變數必須在類的定義外部初始化
  }
private:
 int x,y;
 static int a,b;
};
int Point::a=0;
int Point::b=0;//靜態成員的初始化在類外實現
void main()
{
    //Point pt;
 //pt.init();
 //pt.output();
 Point::init();//靜態方法屬於類本身 不屬於具體對象  類載入時已經分配記憶體
 //error C2352: 'Point::output' : illegal call of non-static member function
 //Point::output();//內部成員必須實實在在存在記憶體空間才能調用這個方法
}
//*****************************************************************************

本節小結:

1.Win32 SDK平台函數很好用,但是在類內部用成員函數更方便.

2.繪圖類CDC的結構關係為:

在MFC編程式的過程中應該始終注意類間關係,類的種類和用途,以便找到適合的類來實現特定功能,就像本節在客戶區和非客戶區以及整個案頭繪圖一樣,不同的類有不同的特點。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.