一、
訊息的分類
1、
佇列訊息、非佇列訊息
l佇列訊息:
windows
為每個應用程式都建立乙個訊息佇列,那麼通過訊息佇列,進行傳送的訊息都屬於佇列訊息;一般來說,由滑鼠、鍵盤產生的訊息都屬於佇列訊息。(為什麼呢?想想,滑鼠、鍵盤事件都是由系統捕獲的,系統捕獲後要傳遞給應用程式,就一定的通過訊息佇列);
l非佇列訊息:
除了佇列訊息,剩下的自然而然就是非佇列訊息了;
u佇列訊息是通過
postmessage()
的方式投遞訊息的,這樣的訊息傳送也叫「寄送」,該函式寄送訊息即可返回,不需要等待程式處理結果;
u非佇列訊息是通過
sendmessage()
的方式進行的,這樣的訊息傳送叫「傳送」;訊息不需要進入視窗的訊息佇列,
然而不管是佇列訊息,還是非佇列訊息,訊息處理的起點都是
afxwndproc
。
不同的是佇列訊息,是作業系統把訊息投放到訊息佇列,應用程式空閒是,通過乙個訊息迴圈,搜尋訊息佇列,不停的從訊息佇列抓取訊息,並處理。大致流程是:
cwinthread->pumpmessage->cwnd->pretranslatemessage->…………..->user32
核心->afxwndprocbase->afxwndproc->…….(
繼續處理
)而非佇列訊息呢(即通過
sendmessage
方式傳送的訊息)?它是直接進入了
user32
核心,然後處理的流程和佇列訊息一樣了。
注意,不管是佇列訊息,還是非佇列訊息,都是從
user32
核心開始,轉到了
afxwndprocbase
(有時候不經過這裡),再到
afxwndproc
,所以可以認為
afxwndproc
是訊息傳遞與處理的起點!
補充一點兒:按理說,從
user32
出來後,不管是佇列訊息,還是非佇列訊息,應該由
windosw
系統發往各個視窗的訊息處理函式
(這個處理函式是
defwindowproc
,這是很直覺的想法,而且傳統的
sdk程式確實是這樣的,但是
mfc程式比傳統的
sdk多了
document/view
,如果如果某個訊息是做文件處理,那麼就讓這個訊息直接流到
document
中去不是更好嗎?所以才有了
mfc命令傳遞機制、
mfc訊息對映的出現
),但是為什麼都統一到了
afxwndproc
這裡呢?這裡用到了鉤子技術。(關於這一段兒描述的,不管是「深入淺出
mfc」、「
mfc逆向分析」、「精通
mfc」都由介紹,但是都不是很清楚,需要再仔細揣摩。而且由於
mfc版本的不同,實際的函式流程也可能和資料描述的不同)
[微軟使用者1]
2、命令訊息、通知訊息、一般訊息
下面以**來分析這幾類訊息:
形式**
誰能處理?
命令訊息
wm_command
選單、工具欄
凡派生自
ccmdtarget
的類,都可以
通知訊息
wm_notify
,也是以
wm_command
形式出現
子控制項傳給父控制項的
一般訊息(又叫標準訊息、視窗訊息)
wm_(任意)
,比如wm_create
、wm_move
等等派生自
cwnd
的類然而,看一下
mfc一些基類的繼承關係,如下圖:
cobject
|ccmdtarget||
|----cwnd----
||----cview
||----cframewnd
||----cdocument----cmydoc
看上圖的繼承關係,可以這麼說,
a)凡是派生自
cwnd
的類,可以攔截並處理任何
windows
訊息,不管是
wm_command
,還是wm_notify
,還是其它什麼
wm_create
、wm_move
等訊息;
b)而與視窗無關的
類、cdocument
類,因為繼承自
ccmdtarget
,只能處理
wm_command
訊息;因為沒有繼承自
cwnd
,不能處理一般訊息。
3、
訊息的處理流程
好了,有了前面1、
2小節的基礎,我們接下來來看訊息的處理流程:
[微軟使用者1]
這一塊兒似懂非懂,需要繼續研究
MFC 訊息機制
windows應用程式是通過訊息驅動的,在mfc軟體開發時,進行介面操作經常要用到訊息,通過訊息對應的處理函式來實現響應的操作。比如,使用者操作視窗,就會產生訊息,送給對應的訊息處理函式進行處理,對使用者的操作做出一些反應。mfc使用訊息對映機制來處理訊息,具體表現就是訊息和訊息處理函式一一對應的訊...
MFC訊息對映機制
一 mfc中採用的這種訊息處理機制成為 mfc訊息對映機制 乙個mfc訊息響應函式在程式中有三處相關資訊 函式原型,函式實現,關聯訊息和訊息響應函式的巨集。函式原型 標頭檔案cdrawview 兩個afx msg注釋巨集之間 訊息響應函式原型的宣告 afx msg void onlbuttondow...
MFC訊息對映機制
win32的訊息迴圈機制是 產生的訊息交由作業系統,將其放到應用程式的訊息佇列中。應用程式通過getmessage函式從這個佇列中取出 一條訊息 由dispatchmessage函式把訊息又交給作業系統,作業系統呼叫視窗過程函式wndproc進行處理。該函式利用switch case結構來判斷並響應...