成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳細介紹MFC中的消息映射

開發(fā) 后端
本文介紹的是MFC中的消息映射,我們都知道,MFC是一個C++的類庫,希望對大家有幫助,一起來看。

MFC是微軟基礎(chǔ)類庫的簡稱,是微軟公司實現(xiàn)的一個c++類庫,主要封裝了大部分的windows API函數(shù),消息系統(tǒng)對于一個win32程序來說十分重要,它是一個程序運行的動力源泉。一個消息,是系統(tǒng)定義的一個32位的值,他唯一的定義了一個事件,向Windows發(fā)出一個通知,告訴應(yīng)用程序某個事情發(fā)生了。

眾所周知,windows是基于消息驅(qū)動的,作好消息處理是WINDOWS編程的關(guān)鍵任務(wù)之一,用VC制作WINDOWS程式同樣離不開消息的處理。雖然VC++6的類向?qū)Э梢酝瓿山^大部分工作,但不幸的是,它并不能完成所有的工作。這就要求我們對 VC中消息的處理有一個比較清淅的認識。只有這樣才可能在必要的時候親自動手完成一些復(fù)雜的消息映射處理。

在MFC中消息是通過一種所謂的消息映射機制來處理的。其實質(zhì)是一張消息及其處理函數(shù)的一一對應(yīng)表以及分析處理這張表的應(yīng)用框架內(nèi)部的一些程序代碼.這樣的好處是可以避免像早期的 SDK編程一樣需要羅列一大堆的CASE語句來處理各種消息.由于不同種類的消息其處理方法是不同的,所以我們有必要先弄清楚 WINDOWS消息的種類。

背景:

WINDOWS 消息的種類

WINDOWS中消息主要有以下三種類型:

1、標準的WINDOWS消息:這類消息是以WM_為前綴,不過WM_COMMAND例外。 例如: WM_MOVE、WM_QUIT等.

2、命令消息:命令消息以WM_COMMAND為消息名.在消息中含有命令的標志符ID,以區(qū)分具體的命令.由菜單,工具欄等命令接口對象產(chǎn)生.

3、控件通知消息:控件通知消息也是以WM_COMMAND為消息名.由編輯框,列表框,子窗口發(fā)送給父窗口的通知消息.在消息中包含控件通知碼.以區(qū)分具體控件的通知消息.

其中標準的WINDOWS消息及控件通知消息主要由窗口類即直接或間接由CWND類派生類處理.相對標準WINDOWS消息及控件通知消息而言,命令消息的處理對象范圍就廣得多.它不僅可以由窗口類處理,還可以由文檔類,文檔模板類及應(yīng)用類所處理。

方法:

不同種類消息的映射方法。

在以上三種消息中,標準的WINDOWS消息映射是相當簡單的。可直接通過類向?qū)瓿刹煌⒌挠成涮幚恚圆辉诒疚挠懻撝小?/p>

凡是從CcmdTarget類派生的類都可以有消息映射.消息映射包括如下兩方面的內(nèi)容:

在類的定義文件中(.H)中加上一條宏調(diào)用:

  1. DECLARE_MESSAGE_MAP() 

通常這條語句中類定義的***.

在類的實現(xiàn)文件(.CPP)中加上消息映射表:

  1. BEGIN_MESSAGE_MAP(類名,父類名)  
  2.  ………..  
  3.  消息映射入口項.  
  4.  ……….  
  5.  END_MESSAGE_MAP( ) 

幸運的是除了某些類(如沒有基類的類或直接從CobjectO類派生的類)外.其它許多類均可由類向?qū)?盡管生成的類只是一個框架,需要我們補充內(nèi)容.但消息映射表已經(jīng)為我們加好了.只是入口項有待我們加入.

命令消息映射入口項是一個ON_COMMAND的宏.比如文件菜單下的"打開…"菜單(ID值為ID_FILE_OPEN)對應(yīng)的消息映射入口項為:

  1. ON_COMMAND(ID_FILE_NEW,OnFileOpen) 

加入消息映射入口項之后需要完成消息處理函數(shù).在類中消息處理函數(shù)都是類的成員函數(shù),要響應(yīng)一個消息,就必須定義一個該消息的處理函數(shù).定義一個消息處理函數(shù)包括以下三方面的內(nèi)容.

  • 在類定義中加入消息處理函數(shù)的函數(shù)原型(函數(shù)聲明)
  • 在類的消息映射表中加入相應(yīng)的消息映射入口項.
  • 在類的實現(xiàn)中加入消息處理函數(shù)的函數(shù)體.

需要說明的是消息處理函數(shù)的原型一定要以afx_msg打頭.比如:

  1. afx_msg OnFileOpen();// 函數(shù)原型 

作為約定.消息處理函數(shù)一般以O(shè)n打頭

但有時我們可能想用一個消息處理函數(shù)來處理一批消息。這時類向?qū)Ь蜔o能為力了。我們必須手工加入消息映射來完成這種工作。可用如下方法實現(xiàn):

首先在處理該消息所在類的實現(xiàn)文件(亦即.CPP)中加入的消息映射入口:

  1.  ...  
  2. BEGIN_MESSAGE_MAP(CMyApp, CWinApp)  
  3. file://{{AFX_MSG_MAP(CMyApp)  
  4.  ...  
  5. file://}}AFX_MSG_MAP  
  6. ON_COMMAND_RANGE(ID_MYCMD_ONE, ID_MYCMD_TEN, OnDoSomething)  
  7. END_MESSAGE_MAP( )  
  8. ... 

粗體標志的語句是我們加入的語句(以后約定我們加入的語句均用粗體標志).其中我們使用了宏ON_COMMAND_RANGE來實現(xiàn)從命令消息 ID_MYCMD_ONE到 ID_MYCMD_TEN都由OnDoSomthing一個消息函數(shù)處理.注意.ID_MYCMD_ONE到 ID_MYCMD_TEN的ID值一定要連續(xù).且ID_MYCMD_ONE值一般較小.

完成上述工作之后我們還需要在該類的頭文件(亦即.H)中加入消息處理函數(shù)的申明:

 

  1. // Generated message-map functions  
  2. protected:  
  3. file://{{AFX_MSG(CMyApp)  
  4. ...  
  5. file://}}AFX_MSG  
  6. afx_msg void OnDoSomething( UINT nID );  
  7. DECLARE_MESSAGE_MAP()  
  8. 由于這不是VC類向?qū)Ъ尤氲暮瘮?shù)申明,所以放在了//}}AFX_MSG之外. 

 

注意這個消息處理函數(shù)有一個UINT類型參數(shù).而處理單一命令的消息處理函數(shù)一般是沒有參數(shù)(除更新用戶接口對象狀態(tài)命令消息處理函數(shù)).這個參數(shù)的主要作用是提供用戶選擇的命令的ID值.

***要做的工作就是在該類的實現(xiàn)文件中實現(xiàn)該消息處理函數(shù). 同樣,有時我們也想使用一個消息處理函數(shù)處理一批更新用戶接口對象狀態(tài)命令消息.方法同上:

首先在.CPP文件中加入語句如下:

 

  1.  ...  
  2. BEGIN_MESSAGE_MAP(CMyApp, CWinApp)  
  3. file://{{AFX_MSG_MAP(CMyApp)  
  4. ...  
  5. file://}}AFX_MSG_MAP  
  6. ON_UPDATE_COMMAND_UI_RANGE (ID_MYCMD_ONE, ID_MYCMD_TEN, OnUpdateSomething)  
  7. END_MESSAGE_MAP( )  
  8.   ... 

 

在該類的頭文件(亦即.H)中加入消息處理函數(shù)的申明:

  1. // Generated message-map functions  
  2. protected:  
  3. file://{{AFX_MSG(CMyApp)  
  4. ...  
  5. file://}}AFX_MSG  
  6. afx_msg void OnUpdateSomething( CcmdUI * pcmdui );  
  7. DECLARE_MESSAGE_MAP() 

 

請各位注意了,仔細的讀者已經(jīng)注意到這里的消息處理函數(shù)并未像命令消息處理函數(shù)需要一個額外的UINT類型的參數(shù).原因在于pcmdui中已包含了此信息.所以不再需要這個參數(shù)了.***不要忘了完成函數(shù)體!

關(guān)于命令消息就討論到這個地方.接下來討論控件通知消息.

控件通知消息相對而言就復(fù)雜一點了.限于篇幅不能一一涉及.這里我們僅討論 WM_NOTIFY消息的處理.

WM_NOTFY產(chǎn)生的原因如下。

在WINDOWS3.X中控件通知它們父窗口,如鼠標點擊,控件背景繪制事件,通過發(fā)送一個消息到父窗口.簡單的通知僅發(fā)送一個WM_COMMAND消息.包含一個通知碼(比如BN_CLICKED)和一個在wParam中的控件ID及一個在lPraram中的控件句柄.因為wParam 和lParam均被使用.就沒有方法傳送其它的附加信息了.比如在BN_CLICKED 通知消息中.就沒有辦法發(fā)送關(guān)于當鼠標點擊時光標的位置信息.在這種情況下就只能使用一些特殊的消息.包括:WM_CTLCOLOR,WM_VSCROLL, WM_HSCROLL等等.值得一提的是這些消息能被反射回發(fā)送它們的控件.就是所謂的消息反射.有興趣的讀者請參閱有關(guān)專著.

在WIN32中同樣可以使用那些在WINDOWS3.1中使用的通知消息.不過不像過去通過增加特殊目的的消息來為新的通知發(fā)送附加的數(shù)據(jù).而是使用一個叫 WM_NOTIFY的消息,它能以一個標準的風格傳送大量的附加數(shù)據(jù).

WM_NOTIFY 消息包含一個存在wParam中的發(fā)送消息控件的ID和一個存在 lParam中的指向一個結(jié)構(gòu)體的指針.這個結(jié)構(gòu)可能是NMHDR結(jié)構(gòu)體.也可能是***個成員是NMHDR的更大的結(jié)構(gòu).因為NMHDR是***個成員,所以指向這個結(jié)構(gòu)的指針也可以指向NMHDR.

在許多情況下,這個指針將指向一個更大的結(jié)構(gòu),當你使用時必需轉(zhuǎn)換它.只有很少的通知消息.比如通用通知消息(它的名字以NM_打頭),工具提示控件的 TTN_SHOW和TTN_POP實際上在使用NMHDR結(jié)構(gòu).

NMHDR結(jié)構(gòu)包含了發(fā)送消息控件的句柄,ID及通知碼(如TTN_SHOW),其格式如下:

 

  1. Typedef sturct tagNMHDR{  
  2. HWND hwndFrom;  
  3. UINT idFrom;  
  4. UINT code;  
  5. } NMHDR; 

 

對TTN_SHOW消息而言,code成員的值將設(shè)為TTN_SHOW.

類向?qū)Э梢詣?chuàng)建ON_NOTIFY消息映射入口并為你提供一個處理函數(shù)的框架.來處理 WM_NOTIFY類型的消息.ON_NOTIFY消息映射宏有如下語法.

 

  1. ON_NOTIFY(wNotifyCode,id,memberFxn) 

 

數(shù)意義如下:

  •  wNotifyCode:要處理的通知消息通知碼。比如:LVN_KEYDOWN.
  •  Id:控件標識ID.
  •  MemberFxn:處理此消息的成員函數(shù).

此成員函數(shù)必需有如下的原形申明:

 

  1. afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result); 

 

比如:假設(shè)你想成員函數(shù)OnKeydownList1處理ClistCtrl(標識ID=IDC_LIST1)的 LVN_KEYDOWN消息,你可以使用類向?qū)砑尤缦碌南⒂成?

 

  1. ON_NOTIFY( LVN_KEYDOWN, IDC_LIST1, OnKeydownList1 ) 

 

在上面的例子中,類向?qū)峁┤缦潞瘮?shù):

  1. void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult)  
  2. {  
  3.  LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;  
  4.  // TODO: Add your control notification handler  
  5.  // code here  
  6.  *pResult = 0;  

 

這時類向?qū)峁┝艘粋€適當類型的指針.你既可以通過pNMHDR,也可以通過 pLVKeyDow來訪問這個通知結(jié)構(gòu)。

如前所述,有時我們可能需要為一組控件處理相同的WM_NOTIFY消息.這時需要使用ON_NOTIFY_RANGE而不是ON_NOTIFY.當你使用 ON_NOTIFY_RANGE時,你需要指定控件的ID范圍.其消息映射入口及函數(shù)原型如下:

  1. ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn ) 

 

參數(shù)說明:

  • wNotifyCode:消息通知碼.比如:LVN_KEYDOWN,
  • id: ***控件的標識ID。
  • idLast:***一個控件的標識ID。(標識值一定要連續(xù))
  • memberFxn: 消息處理函數(shù)。

成員函數(shù)必須有如下原型申明:

 

  1. afx_msg void memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result ); 

 

其中id的表示發(fā)送通知消息的控件標識ID

結(jié)束語:

于目前介紹MFC消息映射的資料甚少.而這部分內(nèi)容對編程又相當重要.本文簡要地介紹了MFC中的幾種重要的消息映射處理.但基于篇幅有限沒能作更全面更深入的探討.

責任編輯:于鐵 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-07-13 11:12:43

C++MFC

2009-12-08 16:09:02

WCF消息

2011-06-21 14:25:44

JavaScriptcookie

2011-07-08 16:54:39

JspCookies

2011-06-08 16:05:34

VB數(shù)組

2011-07-20 15:58:53

C++引用

2011-07-11 11:02:12

JAVA集合框架

2009-06-17 16:01:28

2011-07-11 15:02:54

枚舉

2011-07-21 15:44:33

Java內(nèi)部類

2011-07-08 11:19:51

jspaction

2011-07-07 08:49:14

iPhone Push Notificati

2011-06-15 15:16:54

Session

2011-07-14 11:08:30

C#繼承

2011-07-22 16:50:05

JAVA

2010-03-10 19:25:04

python多線程

2011-07-04 10:32:37

JAVA

2010-03-18 15:47:07

Java創(chuàng)建線程

2011-06-08 15:45:41

字符串JAVA

2010-03-16 13:04:17

Python環(huán)境
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 亚洲欧美日韩精品久久亚洲区 | 91精品国产777在线观看 | 欧美综合久久久 | 午夜91| 日本一区二区高清不卡 | 欧美日韩一二三区 | 国产极品车模吞精高潮呻吟 | 欧美日韩在线免费观看 | 国产日韩一区二区三免费高清 | 国产伦精品一区二区三区高清 | 国产精品亚洲精品日韩已方 | 日韩不卡在线 | 五月婷婷丁香婷婷 | 香蕉久久久 | 国产农村一级国产农村 | 91精品国产综合久久久亚洲 | 成人精品一区二区 | 国产视频一二三区 | 久久美女网 | 亚洲国产精品一区二区第一页 | 久久久在线视频 | 91 久久 | 成人免费黄色片 | 91久久久久久久久 | 免费亚洲网站 | 国产精品日产欧美久久久久 | 性色av香蕉一区二区 | 在线欧美小视频 | 欧美精品一区二区三区在线播放 | 久久精品视频在线观看 | 黄免费观看 | av大片在线观看 | 久久亚洲欧美日韩精品专区 | 日韩免费三级 | 欧美一区二区三区久久精品 | 成人h视频在线观看 | 久久在线精品 | av中文字幕在线观看 | 亚洲精品在线免费 | 中文字幕第一页在线 | 精品亚洲一区二区三区 |