Windows訊息機制以及相關API
訊息系統對於一個win32程式來說十分重要,它是一個程式執行的動力源泉。一個訊息,是系統定義的一個32位的值,他唯一的定義了一個事件,向 Windows發出一個通知,告訴應用程式某個事情發生了。例如,單擊滑鼠、改變視窗尺寸、按下鍵盤上的一個鍵都會使Windows傳送一個訊息給應用程式。
訊息本身是作為一個記錄傳遞給應用程式的,這個記錄中包含了訊息的型別以及其他資訊。例如,對於單擊滑鼠所產生的訊息來說,這個記錄中包含了單擊滑鼠時的座標。這個記錄型別叫做MSG,MSG含有來自windows應用程式訊息佇列的訊息資訊,它在Windows中宣告如下:
typedef struct tagMsg { HWND hwnd; //接受該訊息的視窗控制代碼 UINT message; //訊息常量識別符號,也就是我們通常所說的訊息號 WPARAM wParam; //32位訊息的特定附加資訊,確切含義依賴於訊息值 LPARAM lParam; //32位訊息的特定附加資訊,確切含義依賴於訊息值 DWORD time; //訊息建立時的時間 POINT pt; //訊息建立時的滑鼠/游標在螢幕座標系中的位置 }MSG;
訊息可以由系統或者應用程式產生。系統在發生輸入事件時產生訊息。舉個例子, 當用戶敲鍵, 移動滑鼠或者單擊控制元件。系統也產生訊息以響應由應用程式帶來的變化, 比如應用程式改變系統字型改變窗體大小。應用程式可以產生訊息使窗體執行任務,或者與其他應用程式中的視窗通訊。
我們給出了上面的註釋,是不是會對訊息結構有了一個比較清楚的認識?如果還沒有,那麼我們再試著給出下面的解釋:
hwnd 32位的視窗控制代碼。視窗可以是任何型別的螢幕物件,因為Win32能夠維護大多數可視物件的控制代碼(視窗、對話方塊、按鈕、編輯框等)。
message用於區別其他訊息的常量值,這些常量可以是Windows單元中預定義的常量,也可以是自定義的常量。訊息識別符號以常量命名的方式指出訊息的含義。當視窗過程接收到訊息之後,他就會使用訊息識別符號來決定如何處理訊息。例如、WM_PAINT告訴視窗過程窗體客戶區被改變了需要重繪。符號常量指定系統訊息屬於的類別,其字首指明瞭處理解釋訊息的窗體的型別。
wParam 通常是一個與訊息有關的常量值,也可能是視窗或控制元件的控制代碼。
lParam 通常是一個指向記憶體中資料的指標。由於WParam、lParam和Pointer都是32位的,因此,它們之間可以相互轉換。
把一個訊息傳送到視窗有3種方式:傳送、寄送和廣播。
傳送訊息的函式有SendMessage、SendMessageCallback、SendNotifyMessage、 SendMessageTimeout;寄送訊息的函式主要有PostMessage、PostThreadMessage、 PostQuitMessage;廣播訊息的函式我知道的只有BroadcastSystemMessage、 BroadcastSystemMessageEx。
SendMessage的原型如下:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam),這個函式主要是向一個或多個視窗傳送一條訊息,一直等到訊息被處理之後才會返回。不過需要注意的是,如果接收訊息的視窗是同一個應用程式的一部分,那麼這個視窗的視窗函式就被作為一個子程式馬上被呼叫;如果接收訊息的視窗是被另外的執行緒所建立的,那麼視窗系統就切換到相應的執行緒並且呼叫相應的視窗函式,這條訊息不會被放進目標應用程式佇列中。函式的返回值是由接收訊息的視窗的視窗函式返回,返回的值取決於被髮送的訊息。
PostMessage的原型如下:BOOL PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam),該函式把一條訊息放置到建立hWnd視窗的執行緒的訊息佇列中,該函式不等訊息被處理就馬上將控制返回。需要注意的是,如果hWnd引數為 HWND_BROADCAST,那麼,訊息將被寄送給系統中的所有的重疊視窗和彈出視窗,但是子視窗不會收到該訊息;如果hWnd引數為NULL,則該函式類似於將dwThreadID引數設定成當前執行緒的標誌來呼叫PostThreadMEssage函式。
從上面的這2個具有代表性的函式,我們可以看出訊息的傳送方式和寄送方式的區別所在:被髮送的訊息是否會被立即處理,函式是否立即返回。被髮送的訊息會被立即處理,處理完畢後函式才會返回;被寄送的訊息不會被立即處理,他被放到一個先進先出的佇列中,一直等到應用程式空線的時候才會被處理,不過函式放置訊息後立即返回。
實際上,傳送訊息到一個視窗處理過程和直接呼叫視窗處理過程之間並沒有太大的區別,他們直接的唯一區別就在於你可以要求作業系統截獲所有被髮送的訊息,但是不能夠截獲對視窗處理過程的直接呼叫。
以寄送方式傳送的訊息通常是與使用者輸入事件相對應的,因為這些事件不是十分緊迫,可以進行緩慢的緩衝處理,例如滑鼠、鍵盤訊息會被寄送,而按鈕等訊息則會被髮送。
廣播訊息用得比較少,BroadcastSystemMessage函式原型如下:
long BroadcastSystemMessage(DWORD dwFlags,LPDWORD lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM lParam);該函式可以向指定的接收者傳送一條訊息,這些接收者可以是應用程式、可安裝的驅動程式、網路驅動程式、系統級別的裝置驅動訊息和他們的任意組合。需要注意的是,如果dwFlags引數是BSF_QUERY並且至少一個接收者返回了BROADCAST_QUERY_DENY,則返回值為0,如果沒有指定BSF_QUERY,則函式將訊息傳送給所有接收者,並且忽略其返回值。
訊息的接收主要有3個函式:GetMessage、PeekMessage、WaitMessage。
GetMessage原型如下:BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);該函式用來獲取與hWnd引數所指定的視窗相關的且wMsgFilterMin和wMsgFilterMax引數所給出的訊息值範圍內的訊息。需要注意的是,如果hWnd為NULL,則GetMessage獲取屬於呼叫該函式應用程式的任一視窗的訊息,如果 wMsgFilterMin和wMsgFilterMax都是0,則GetMessage就返回所有可得到的訊息。函式獲取之後將刪除訊息佇列中的除
WM_PAINT訊息之外的其他訊息,至於WM_PAINT則只有在其處理之後才被刪除。
PeekMessage原型如下:BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);該函式用於檢視應用程式的訊息佇列,如果其中有訊息就將其放入lpMsg所指的結構中,不過,與GetMessage不同的是,PeekMessage函式不會等到有訊息放入佇列時才返回。同樣,如果hWnd為NULL,則PeekMessage獲取屬於呼叫該函式應用程式的任一視窗的訊息,如果hWnd=-1,那麼函式只返回把hWnd引數為NULL的PostAppMessage函式送去的訊息。如果
wMsgFilterMin和wMsgFilterMax都是0,則PeekMessage就返回所有可得到的訊息。函式獲取之後將視最後一個引數來決定是否刪除訊息佇列中的除 WM_PAINT訊息之外的其他訊息,至於WM_PAINT則只有在其處理之後才被刪除。
WaitMessage原型如下:BOOL WaitMessage();當一個應用程式無事可做時,該函式就將控制權交給另外的應用程式,同時將該應用程式掛起,直到一個新的訊息被放入應用程式的佇列之中才返回。
相關推薦
Windows訊息機制以及相關API
訊息系統對於一個win32程式來說十分重要,它是一個程式執行的動力源泉。一個訊息,是系統定義的一個32位的值,他唯一的定義了一個事件,向 Windows發出一個通知,告訴應用程式某個事情發生了。例如,單擊滑鼠、改變視窗尺寸、按下鍵盤上的一個鍵都會使Windows傳送一個訊
Rabbitmq中的工作機制以及相關的springboot整合
Rabbitmq中的工作機制以及相關的springboot整合 1.安裝rabbitmq 獲取rabbitmq映象:docker pull rabbitmq:management 建立並執行容器: docker run -d --hostname my
學習筆記10.4----Windows訊息機制
1)作業系統訊息機制:百度百科——訊息機制 解釋的很清楚。作業系統掃描輸入裝置狀態-(轉換為訊息)-傳送給焦點窗體 ,對於每一個正在執行的Windows應用程式,系統為其建立一個“訊息佇列”。 2)control的invoke,begin invoke .委託的invok
python學習--python實現按鍵精靈之windows訊息機制文章整理
1.如何利用Python和win32程式設計避免重複性體力勞動(一)——開始、FindWindow和FindWindowEx http://blog.csdn.net/seele52/article/details/17504925 2.如何利用Python和win32程式設計避免重
windows訊息機制詳解
MessageBox("ComboBox 選項"+str+" selected!"); 在按鈕1 的響應函式OnButton1()中新增程式碼: m_tab1.SetCurSel(0); NMHDR nmhdr; nmhdr.code=TCN_SELCHANGE; nmhdr.hwndFrom=GetDlgI
180108 逆向-Windows訊息機制(鍵盤訊息)
1625-5 王子昂 總結《2018年1月8日》 【連續第465天總結】 A. Windows訊息系統-鍵盤訊息 B. 鍵盤訊息 概述 應用程式從系統接收到的關於鍵盤的訊息可以分為兩類:擊鍵和字元。 物理層面上,對於某個按鍵(例如A),會發出“按
windows訊息機制
一 Windows中有一個系統訊息佇列,對於每一個正在執行的Windows應用程式,系統為其建立一個“訊息佇列”,即應用程式佇列,用來存放該程式可能 建立的各種視窗的訊息。應用程式中含有一段稱作“訊息迴圈”的程式碼,用來從訊息佇列中檢索這些訊息並把它們分發到相應的視窗函式中。 二 Win
MFC(一)——WINDOWS訊息機制
建立一個完整的視窗需要經過下面四個操作步驟: 設計一個視窗類; 註冊視窗類; 建立視窗; 顯示及更新視窗。 #include <Windows.h> #include <stdio.h> LRESULT CALLBACK Wi
windows訊息機制中lparam與wparam兩個引數的分析
一. WPARAM 和 LPARAM 本質上沒有什麼區別:都是32位數, 但是區別也還是有的:MICROSOFT在使用時兩種引數分別代表不同的含義和內容,WPARAM常常代表一些控制元件的ID或者高位低位組合起來分別表示滑鼠的位置,如果訊息的傳送者需要將某種結構的指標或者是
深入理解windows 訊息機制
再例如,按下一個按鈕,他向父視窗傳送的訊息也可以看作是一個控制元件通知訊息;單擊滑鼠所產生的訊息可以由主視窗直接處理,然後交給控制元件視窗處理。其中視窗訊息及控制元件通知訊息主要由視窗類即直接或間接由CWND類派生類處理。相對視窗訊息及控制元件通知訊息而言,命令訊息的處理物件範圍就廣得多,它不僅可以由視窗類處
Windows訊息機制『經典』
Windows訊息機制【轉】 2010-03-06 15:17:47| 分類: c/c++/c#語言相關 |字號 訂閱 原文地址: http://blog.csdn.net/recle/archive/2008/11/08/3256614.aspx (經修正的)原文
WIN32學習——Windows訊息機制(一)
1、Win32視窗程式採用的是事件驅動方式執行,也就是訊息機制,當系統通知視窗工作時,就是採用訊息的方式派發給視窗,通過呼叫視窗處理函式進行對訊息對處理。 2、訊息MessageBox結構體: int MessageBox( HWND hWnd, //父視窗
windows訊息機制與ASP.net winform控制元件訊息傳遞之滑鼠點選click事件
window系統是一個訊息驅動的系統, windows作業系統本身有自己的訊息佇列,訊息迴圈,它捕捉鍵盤,滑鼠的動作生成訊息,並將這個訊息傳給應用程式的訊息佇列。 當用戶用滑鼠click桌面時,其實使用者是不能直接接觸到某個控制元件的。表面上看,的確是使用者用
Windows訊息機制之二(續)-- windows訊息和訊息佇列
與基於MS - DOS的應用程式不同,Windows的應用程式是事件(訊息)驅動的。它們不會顯式地呼叫函式(如C執行時庫呼叫)來獲取輸入,而是等待windows向它們傳遞輸入。 windows系統把應用程式的輸入事件傳遞給各個視窗,每個視窗有一個函式,稱為視窗訊息處理函式。
[轉]windows訊息機制(MFC)
訊息分類與訊息佇列 Windows中,訊息使用統一的結構體(MSG)來存放資訊,其中message表明訊息的具體的型別, 而wParam,lParam是其最靈活的兩個變數,為不同的訊息型別時,存放資料的含義也不一樣。 time表示產生訊息的時間,pt表示產生訊息時滑
Windows 訊息機制淺析
1. Windows 的歷史中國人喜歡以史為鑑,而事實也確實是,如果你能知道一件事情的來龍去脈,往往可以更容易地理解事物為什麼會表現為當前這樣的現狀。所以,我的介紹性開場白通常會以一段歷史開始。不過,我不會以精確到年月日的那種方式詳細講述,而是選取幾個對我們的程式設計生涯有重
windows 訊息機制、視窗過程與執行緒間訊息傳遞
按照自己的理解好好整理一遍 訊息機制 windows是一個訊息驅動的系統,會有一個總的系統訊息的佇列,滑鼠、鍵盤等等都會流入到這個佇列中,同時會為每個執行緒維護一個訊息佇列(注意預設是有GUI呼叫的執行緒才有,對於沒有GUI或者視窗的執行緒,只有當線上程內呼叫get/pe
(四)Lock,ReentrantLock,ReentrantReadWriteLock類的使用以及相關api---synchronized進階
這篇部落格記錄了Lock,ReentrantLock,ReentrantReadWriteLock類的使用以及其一些api: 碼字不易~~另外《java多執行緒程式設計核心技術》這本書讀著很爽 前言說明:之前為了解決多執行緒時的非執行緒安全問題,使用的是synchronized。接下來記錄的是他的升級版本Re
WPF的訊息機制(三)- WPF內部的5個視窗之處理啟用和關閉的訊息視窗以及系統資源通知視窗
原文: WPF的訊息機制(三)- WPF內部的5個視窗之處理啟用和關閉的訊息視窗以及系統資源通知視窗 目錄 WPF的訊息機制(一)-讓應用程式動起來 WPF的訊息機制(二)-WPF內部的5個視窗 (1)隱藏訊息視窗 (2)處理啟用和關閉的訊息視窗和系統資源通知視窗
淺談Windows SDK視窗程式的訊息機制
Windows系統的訊息機制 一個庫函式(比如fopen),最終會呼叫作業系統的API來實現其功能,在Windows中,不僅庫函式最終會呼叫系統函式,系統函式反過來也會呼叫使用者函式,這種機制就是通過訊息來實現的。 我們假設程式發生了一項滑鼠點選“關閉”按鈕的操作,系統會發現這次操作,並將這次操作包裝成訊息