久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

MFC消息系統(tǒng)(一)(轉(zhuǎn)載)

 xue_dong5437 2010-11-17
消息是指什么,?
     消息系統(tǒng)對于一個win32程序來說十分重要,它是一個程序運(yùn)行的動力源泉,。一個消息,,是系統(tǒng)定義的一個32位的值,他唯一的定義了一個事件,,向Windows發(fā)出一個通知,,告訴應(yīng)用程序某個事情發(fā)生了。例如,,單擊鼠標(biāo),、改變窗口尺寸、按下鍵盤上的一個鍵都會使Windows發(fā)送一個消息給應(yīng)用程序,。
    消息本身是作為一個記錄傳遞給應(yīng)用程序的,,這個記錄中包含了消息的類型以及其他信息。例如,,對于單擊鼠標(biāo)所產(chǎn)生的消息來說,,這個記錄中包含了單擊鼠標(biāo)時的坐標(biāo)。這個記錄類型叫做MSG,,MSG含有來自windows應(yīng)用程序消息隊(duì)列的消息信息,,它在Windows中聲明如下:
typedef struct tagMsg
{
       HWND    hwnd;       接受該消息的窗口句柄
       UINT    message;    消息常量標(biāo)識符,,也就是我們通常所說的消息號
       WPARAM  wParam;     32位消息的特定附加信息,確切含義依賴于消息值
       LPARAM  lParam;     32位消息的特定附加信息,,確切含義依賴于消息值
       DWORD   time;       消息創(chuàng)建時的時間
       POINT   pt;         消息創(chuàng)建時的鼠標(biāo)/光標(biāo)在屏幕坐標(biāo)系中的位置
}MSG;
    消息可以由系統(tǒng)或者應(yīng)用程序產(chǎn)生,。系統(tǒng)在發(fā)生輸入事件時產(chǎn)生消息。舉個例子, 當(dāng)用戶敲鍵, 移動鼠標(biāo)或者單擊控件,。系統(tǒng)也產(chǎn)生消息以響應(yīng)由應(yīng)用程序帶來的變化, 比如應(yīng)用程序改變系統(tǒng)字體改變窗體大小,。應(yīng)用程序可以產(chǎn)生消息使窗體執(zhí)行任務(wù),或者與其他應(yīng)用程序中的窗口通訊,。

消息中有什么,?
   
我們給出了上面的注釋,是不是會對消息結(jié)構(gòu)有了一個比較清楚的認(rèn)識,?如果還沒有,,那么我們再試著給出下面的解釋:
     hwnd 32位的窗口句柄。窗口可以是任何類型的屏幕對象,,因?yàn)閃in32能夠維護(hù)大多數(shù)可視對象的句柄(窗口,、對話框、按鈕,、編輯框等),。
     message用于區(qū)別其他消息的常量值,這些常量可以是Windows單元中預(yù)定義的常量,,也可以是自定義的常量,。消息標(biāo)識符以常量命名的方式指出消息的含義。當(dāng)窗口過程接收到消息之后,,他就會使用消息標(biāo)識符來決定如何處理消息,。例如、WM_PAINT告訴窗口過程窗體客戶區(qū)被改變了需要重繪,。符號常量指定系統(tǒng)消息屬于的類別,,其前綴指明了處理解釋消息的窗體的類型。
     wParam 通常是一個與消息有關(guān)的常量值,,也可能是窗口或控件的句柄,。
     lParam 通常是一個指向內(nèi)存中數(shù)據(jù)的指針。由于WParam,、lParam和Pointer都是32位的,,因此,它們之間可以相互轉(zhuǎn)換,。

消息標(biāo)識符的值
     系統(tǒng)保留消息標(biāo)識符的值在0x0000在0x03ff(WM_USER-1)范圍,。這些值被系統(tǒng)定義消息使用。 應(yīng)用程序不能使用這些值給自己的消息,。應(yīng)用程序消息從WM_USER(0X0400)到0X7FFF,,或0XC000到0XFFFF,;WM_USER到0X7FFF范圍的消息由應(yīng)用程序自己使用;0XC000到0XFFFF范圍的消息用來和其他應(yīng)用程序通信,,我們順便說一下具有標(biāo)志性的消息值:
     WM_NULL---0x0000    空消息,。
     0x0001----0x0087    主要是窗口消息。
     0x00A0----0x00A9    非客戶區(qū)消息
     0x0100----0x0108    鍵盤消息
     0x0111----0x0126    菜單消息
     0x0132----0x0138    顏色控制消息
     0x0200----0x020A    鼠標(biāo)消息
     0x0211----0x0213    菜單循環(huán)消息
     0x0220----0x0230    多文檔消息
     0x03E0----0x03E8    DDE消息
     0x0400              WM_USER
     0x8000              WM_APP
     0x0400----0x7FFF    應(yīng)用程序自定義私有消息

消息有哪幾種,?
   
其實(shí),,windows中的消息雖然很多,但是種類并不繁雜,,大體上有3種:窗口消息,、命令消息和控件通知消息。
     窗口消息大概是系統(tǒng)中最為常見的消息,,它是指由操作系統(tǒng)和控制其他窗口的窗口所使用的消息,。例如CreateWindow、DestroyWindow和MoveWindow等都會激發(fā)窗口消息,,還有我們在上面談到的單擊鼠標(biāo)所產(chǎn)生的消息也是一種窗口消息,。
     命令消息,這是一種特殊的窗口消息,,他用來處理從一個窗口發(fā)送到另一個窗口的用戶請求,,例如按下一個按鈕,他就會向主窗口發(fā)送一個命令消息,。
     控件通知消息,,是指這樣一種消息,一個窗口內(nèi)的子控件發(fā)生了一些事情,,需要通知父窗口,。通知消息只適用于標(biāo)準(zhǔn)的窗口控件如按鈕、列表框,、組合框,、編輯框,,以及Windows公共控件如樹狀視圖,、列表視圖等。例如,,單擊或雙擊一個控件,、在控件中選擇部分文本、操作控件的滾動條都會產(chǎn)生通知消息,。 她類似于命令消息,,當(dāng)用戶與控件窗口交互時,那么控件通知消息就會從控件窗口發(fā)送到它的主窗口,。但是這種消息的存在并不是為了處理用戶命令,,而是為了讓主窗口能夠改變控件,,例如加載、顯示數(shù)據(jù),。例如按下一個按鈕,,他向父窗口發(fā)送的消息也可以看作是一個控件通知消息;單擊鼠標(biāo)所產(chǎn)生的消息可以由主窗口直接處理,,然后交給控件窗口處理,。
    其中窗口消息及控件通知消息主要由窗口類即直接或間接由CWND類派生類處理。相對窗口消息及控件通知消息而言,,命令消息的處理對象范圍就廣得多,,它不僅可以由窗口類處理,還可以由文檔類,,文檔模板類及應(yīng)用類所處理,。
    由于控件通知消息很重要的,人們用的也比較多,,但是具體的含義往往令初學(xué)者暈頭轉(zhuǎn)向,,所以我決定把常見的幾個列出來供大家參考:
按扭控件
BN_CLICKED        用戶單擊了按鈕
 BN_DISABLE 按鈕被禁止
 BN_DOUBLECLICKED  用戶雙擊了按鈕
 BN_HILITE  用/戶加亮了按鈕
 BN_PAINT  按鈕應(yīng)當(dāng)重畫
 BN_UNHILITE 加亮應(yīng)當(dāng)去掉

組合框控件
 CBN_CLOSEUP 組合框的列表框被關(guān)閉
 CBN_DBLCLK 用戶雙擊了一個字符串
 CBN_DROPDOWN 組合框的列表框被拉出
 CBN_EDITCHANGE 用戶修改了編輯框中的文本
 CBN_EDITUPDATE 編輯框內(nèi)的文本即將更新
 CBN_ERRSPACE 組合框內(nèi)存不足
 CBN_KILLFOCUS 組合框失去輸入焦點(diǎn)
 CBN_SELCHANGE 在組合框中選擇了一項(xiàng)
 CBN_SELENDCANCEL 用戶的選擇應(yīng)當(dāng)被取消
 CBN_SELENDOK 用戶的選擇是合法的
 CBN_SETFOCUS 組合框獲得輸入焦點(diǎn)

編輯框控件
 EN_CHANGE 編輯框中的文本己更新
 EN_ERRSPACE 編輯框內(nèi)存不足
 EN_HSCROLL 用戶點(diǎn)擊了水平滾動條
 EN_KILLFOCUS 編輯框正在失去輸入焦點(diǎn)
 EN_MAXTEXT 插入的內(nèi)容被截?cái)?br> EN_SETFOCUS 編輯框獲得輸入焦點(diǎn)
 EN_UPDATE 編輯框中的文本將要更新
 EN_VSCROLL 用戶點(diǎn)擊了垂直滾動條消息含義

列表框控件
 LBN_DBLCLK 用戶雙擊了一項(xiàng)
 LBN_ERRSPACE 列表框內(nèi)存不夠
 LBN_KILLFOCUS 列表框正在失去輸入焦點(diǎn)
 LBN_SELCANCEL 選擇被取消
 LBN_SELCHANGE 選擇了另一項(xiàng)
 LBN_SETFOCUS 列表框獲得輸入焦點(diǎn)

 

隊(duì)列消息和非隊(duì)列消息
   
從消息的發(fā)送途徑來看,消息可以分成2種:隊(duì)列消息和非隊(duì)列消息,。消息隊(duì)列由可以分成系統(tǒng)消息隊(duì)列和線程消息隊(duì)列,。系統(tǒng)消息隊(duì)列由Windows維護(hù),線程消息隊(duì)列則由每個GUI線程自己進(jìn)行維護(hù),,為避免給non-GUI現(xiàn)成創(chuàng)建消息隊(duì)列,,所有線程產(chǎn)生時并沒有消息隊(duì)列,僅當(dāng)線程第一次調(diào)用GDI函數(shù)數(shù)系統(tǒng)給線程創(chuàng)建一個消息隊(duì)列,。隊(duì)列消息送到系統(tǒng)消息隊(duì)列,,然后到線程消息隊(duì)列;非隊(duì)列消息直接送給目的窗口過程,。
     對于隊(duì)列消息,,最常見的是鼠標(biāo)和鍵盤觸發(fā)的消息,例如WM_MOUSERMOVE,WM_CHAR等消息,,還有一些其它的消息,,例如:WM_PAINT、WM_TIMER和WM_QUIT,。當(dāng)鼠標(biāo),、鍵盤事件被觸發(fā)后,相應(yīng)的鼠標(biāo)或鍵盤驅(qū)動程序就會把這些事件轉(zhuǎn)換成相應(yīng)的消息,,然后輸送到系統(tǒng)消息隊(duì)列,,由Windows系統(tǒng)去進(jìn)行處理。Windows系統(tǒng)則在適當(dāng)?shù)臅r機(jī),從系統(tǒng)消息隊(duì)列中取出一個消息,,根據(jù)前面我們所說的MSG消息結(jié)構(gòu)確定消息是要被送往那個窗口,,然后把取出的消息送往創(chuàng)建窗口的線程的相應(yīng)隊(duì)列,下面的事情就該由線程消息隊(duì)列操心了,,Windows開始忙自己的事情去了,。線程看到自己的消息隊(duì)列中有消息,就從隊(duì)列中取出來,,通過操作系統(tǒng)發(fā)送到合適的窗口過程去處理,。
     一般來講,系統(tǒng)總是將消息Post在消息隊(duì)列的末尾,。這樣保證窗口以先進(jìn)先出的順序接受消息,。然而,WM_PAINT是一個例外,同一個窗口的多個 WM_PAINT被合并成一個 WM_PAINT 消息, 合并所有的無效區(qū)域到一個無效區(qū)域,。合并WM_PAIN的目的是為了減少刷新窗口的次數(shù),。
    非隊(duì)列消息將會繞過系統(tǒng)隊(duì)列和消息隊(duì)列,直接將消息發(fā)送到窗口過程,,,。系統(tǒng)發(fā)送非隊(duì)列消息通知窗口,系統(tǒng)發(fā)送消息通知窗口,。 例如,當(dāng)用戶激活一個窗口系統(tǒng)發(fā)送WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR,。這些消息通知窗口它被激活了。非隊(duì)列消息也可以由當(dāng)應(yīng)用程序調(diào)用系統(tǒng)函數(shù)產(chǎn)生,。例如,當(dāng)程序調(diào)用SetWindowPos系統(tǒng)發(fā)送WM_WINDOWPOSCHANGED消息,。一些函數(shù)也發(fā)送非隊(duì)列消息,例如下面我們要談到的函數(shù),。
    
消息的發(fā)送
     了解了上面的這些基礎(chǔ)理論之后,,我們就可以進(jìn)行一下簡單的消息發(fā)送與接收。
     把一個消息發(fā)送到窗口有3種方式:發(fā)送,、寄送和廣播,。
     發(fā)送消息的函數(shù)有SendMessage、SendMessageCallback,、SendNotifyMessage,、SendMessageTimeout;寄送消息的函數(shù)主要有PostMessage,、PostThreadMessage,、PostQuitMessage,;廣播消息的函數(shù)我知道的只有BroadcastSystemMessage,、BroadcastSystemMessageEx。
     SendMessage的原型如下:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam),,這個函數(shù)主要是向一個或多個窗口發(fā)送一條消息,,一直等到消息被處理之后才會返回,。不過需要注意的是,如果接收消息的窗口是同一個應(yīng)用程序的一部分,,那么這個窗口的窗口函數(shù)就被作為一個子程序馬上被調(diào)用,;如果接收消息的窗口是被另外的線程所創(chuàng)建的,那么窗口系統(tǒng)就切換到相應(yīng)的線程并且調(diào)用相應(yīng)的窗口函數(shù),,這條消息不會被放進(jìn)目標(biāo)應(yīng)用程序隊(duì)列中,。函數(shù)的返回值是由接收消息的窗口的窗口函數(shù)返回,返回的值取決于被發(fā)送的消息,。
     PostMessage的原型如下:BOOL PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam),,該函數(shù)把一條消息放置到創(chuàng)建hWnd窗口的線程的消息隊(duì)列中,該函數(shù)不等消息被處理就馬上將控制返回,。需要注意的是,,如果hWnd參數(shù)為HWND_BROADCAST,那么,,消息將被寄送給系統(tǒng)中的所有的重疊窗口和彈出窗口,,但是子窗口不會收到該消息;如果hWnd參數(shù)為NULL,,則該函數(shù)類似于將dwThreadID參數(shù)設(shè)置成當(dāng)前線程的標(biāo)志來調(diào)用PostThreadMEssage函數(shù),。
  從上面的這2個具有代表性的函數(shù),我們可以看出消息的發(fā)送方式和寄送方式的區(qū)別所在:被發(fā)送的消息是否會被立即處理,,函數(shù)是否立即返回,。被發(fā)送的消息會被立即處理,處理完畢后函數(shù)才會返回,;被寄送的消息不會被立即處理,,他被放到一個先進(jìn)先出的隊(duì)列中,一直等到應(yīng)用程序空線的時候才會被處理,,不過函數(shù)放置消息后立即返回,。
  實(shí)際上,發(fā)送消息到一個窗口處理過程和直接調(diào)用窗口處理過程之間并沒有太大的區(qū)別,,他們直接的唯一區(qū)別就在于你可以要求操作系統(tǒng)截獲所有被發(fā)送的消息,,但是不能夠截獲對窗口處理過程的直接調(diào)用。
  以寄送方式發(fā)送的消息通常是與用戶輸入事件相對應(yīng)的,,因?yàn)檫@些事件不是十分緊迫,,可以進(jìn)行緩慢的緩沖處理,例如鼠標(biāo),、鍵盤消息會被寄送,,而按鈕等消息則會被發(fā)送。
  廣播消息用得比較少,BroadcastSystemMessage函數(shù)原型如下:
      long BroadcastSystemMessage(DWORD dwFlags,LPDWORD lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM lParam);該函數(shù)可以向指定的接收者發(fā)送一條消息,,這些接收者可以是應(yīng)用程序,、可安裝的驅(qū)動程序、網(wǎng)絡(luò)驅(qū)動程序,、系統(tǒng)級別的設(shè)備驅(qū)動消息和他們的任意組合,。需要注意的是,如果dwFlags參數(shù)是BSF_QUERY并且至少一個接收者返回了BROADCAST_QUERY_DENY,,則返回值為0,,如果沒有指定BSF_QUERY,則函數(shù)將消息發(fā)送給所有接收者,,并且忽略其返回值,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多