程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> 孫鑫VC++講座筆記-(4)MFC消息映射機制的剖析

孫鑫VC++講座筆記-(4)MFC消息映射機制的剖析

編輯:vc教程

一,消息映射機制

1,消息響應函數:(例:在CDrawVIEw類響應鼠標左鍵按下消息)

 1)在頭文件(DrawVIEw.h)中聲明消息響應函數原型。

//{{AFX_MSG(CDrawVIEw)   //注釋宏
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG   //注釋宏

說明:

在注釋宏之間的聲明在VC中灰色顯示。afx_msg宏表示聲明的是一個消息響應函數。

 2)在源文件(DrawVIEw.cpp)中進行消息映射。

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

說明:

在宏BEGIN_MESSAGE_MAP()與END_MESSAGE_MAP()之間進行消息映射。

宏ON_WM_LBUTTONDOWN()把消息WM_LBUTTONDOWN與它的響應函數OnLButtonDown()相關聯。這樣一旦有消息的產生,就會自動調用相關聯的消息響應函數去處理。

宏ON_WM_LBUTTONDOWN()定義如下:

#define ON_WM_LBUTTONDOWN()
 { WM_LBUTTONDOWN, 0, 0, 0, AfxSig_vwp,
  (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT, CPoint))&OnLButtonDown },

 3)源文件中進行消息響應函數處理。(DrawVIEw.cpp中自動生成OnLButtonDown函數輪廓,如下)

void CDrawVIEw::OnLButtonDown(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 CVIEw::OnLButtonDown(nFlags, point);
}

說明:

可見當增加一個消息響應處理,在以上三處進行了修改。可在消息響應函數裡添加消息處理代碼完成對消息的響應、處理。

2,消息響應的方式:

1)在基類中針對每種消息做一個虛函數,當子類對消息響應時候,只要在子類中重寫這個虛函數即可。缺點:MFC類派生層次很多,如果在基類對每個消息進行虛函數處理,那麼從基類派生的每個子類都將背負一個龐大的虛表,這樣浪費內存,故MFC沒有采取這中方式而采取消息映射方式。

2)消息映射方式:MFC在後台維護了一個句柄和C++對象指針對照表,當收到一個消息後,通過消息結構裡資源句柄(查對照表)就可找到與它對應的一個C++對象指針,然後把這個指針傳給基類,基類利用這個指針調用WindowProc()函數對消息進行處理,WindowProc()函數中調用OnWndMsg()函數,真正的消息路由及處理是由OnWndMsg()函數完成的。由於WindowProc()和OnWndMsg()都是虛函數,而且是用派生類對象指針調用的,由多態性知最總終調用子類的。在OnWndMsg()函數處理的時候,根據消息種類去查找消息映射,判斷所發的消息有沒有響應函數,具體方式是到相關的頭文件和源文件中尋找消息響應函數聲明(從注釋宏//{{AFX_MSG(CDrawVIEw).//}}AFX_MSG之間尋找),消息映射(從宏BEGIN_MESSAGE_MAP(...)....END_MESSAGE_MAP()之間尋找),最終找到對應的消息處理函數。當然,如果子類中沒有對消息進行處理,則消息交由基類處理。

說明:

virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);

二,有關繪圖

1,使用SDK獲取DC句柄:

HDC hdc;
hdc=::GetDc(m_hWnd);//獲取DC句柄
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hdc,point.x,point.y);
::ReleaseDC(m_hWnd,hdc);//釋放DC

2,利用CDC類指針和CWin類成員函數獲取DC。

CDC *pDC=GetDC();
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);

3,利用CClientDC對象。(CCl

[1] [2] 下一頁

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved