當前位置:首頁 » 服務存儲 » win消息機制存儲
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

win消息機制存儲

發布時間: 2023-04-16 11:59:37

A. 誰能給我講一講windows消息機制qq:524730955

Windows操作系統最大的特點就是其圖形化的操作界面,其圖形化界面是建立在其消息處理機物州制這個基礎之上的。如果不理解Windows消息處理機制,肯定無法深入的理解Windows編程。可惜很多程序員對Windows消息只是略有所聞,對其使用知之甚少,更不了解其內部實現原理,本文試著一步一步向大家披露我理解的Windows消息機制。可以說,掌握了這一部分知識,就是掌握了Windows編程中的神兵利器,靈活運用它,將會極大的提高我們的編程能力。

一、 消息概述
Windows窗體是怎樣塌螞纖展現在屏幕上的呢?眾所周知,是通過API繪制實現的。Windows操作系統提供了一系列的API函數來實現界面的繪制功能,例如:

DrawText繪制文字

DrawEdge繪制邊框

DrawIcon繪制圖標

BitBlt 繪制點陣圖

Rectangle繪制矩形



再復雜的程序界面都是通過這個函數來實現的。

那什麼時候調用這些函數呢?顯然我們需要一個控制中心,用來進行「發號施令」,我們還需要一個命令傳達機團仿製,將命令即時的傳達到目的地。這個控制中心,就是一個動力源,就像一顆心臟,源源不斷地將血液送往各處。這個命令傳達機制就是Windows消息機制,Windows消息就好比是身體中的血液,它是命令傳達的使者。

Windows消息控制中心一般是三層結構,其頂端就是Windows內核。Windows內核維護著一個消息隊列,第二級控制中心從這個消息隊列中獲取屬於自己管轄的消息,後做出處理,有些消息直接處理掉,有些還要發送給下一級窗體(Window)或控制項(Control)。第二級控制中心一般是各Windows應用程序的Application對象。第三級控制中心就是Windows窗體對象,每一個窗體都有一個默認的窗體過程,這個過程負責處理各種接收到的消息。

消息是以固定的結構傳送給應用程序的,結構如下:

Public Type MSG

hwnd As Long

message As Long

wParam As Long

lParam As Long

time As Long

pt As POINTAPI

End Type

其中hwnd是窗體的句柄,message是一個消息常量,用來表示消息的類型,wParam和lParam都是32位的附加信息,具體表示什麼內容,要視消息的類型而定,time是消息發送的時間,pt是消息發送時滑鼠所在的位置。

Windows操作系統中包括以下幾種消息:

1、標准Windows消息:

這種消息以WM_打頭。

2、通知消息

通知消息是針對標准Windows控制項的消息。這些控個包括:按鈕(Button)、組合框(ComboBox)、編輯框(TextBox)、列表框(ListBox)、ListView控制項、Treeview控制項、工具條(Toolbar)、菜單(Menu)等。每種消息以不同的字元串打頭。

3、自定義消息

編程人員還可以自定義消息。

二、 關於Windows句柄
不是每個控制項都能接收消息,轉發消息和繪制自身,只有具有句柄(handle)的控制項才能做到。有句柄的控制項本質上都是一個窗體(window),它們可以獨立存在,可以作為其它控制項的容器,而沒有句柄的控制項,如Label,是不能獨立存在的,只能作為窗口控制項的子控制項,它不能繪制自身,只能依靠父窗體將它繪制來。

句柄的本質是一個系統自動維護的32位的數值,在整個操作系統的任一時刻,這個數值是唯一的。但該句柄代表的窗體釋放後,句柄也會被釋放,這個數值又可能被其它窗體使用。也就是說,句柄的數值是動態的,它本身只是一個唯一性標識,操作系統通過句柄來識別和查找它所代表的對象。

然而,並非所有的句柄都是窗體的句柄,Windows系統中還中很多其它類型的句柄,如畫布(hdc)句柄,畫筆句柄,畫刷句柄,應用程序句柄(hInstance)等。這種句柄是不能接收消息的。但不管是哪種句柄,都是系統中對象的唯一標識。本文只討論窗體句柄。

那為什麼句柄使窗口具有了如此獨特的特性呢?實際是都是由於消息的原因。由於有了句柄,窗體能夠接收消息,也就知道了該什麼時候繪制自己,繪制子控制項,知道了滑鼠在什麼時候點擊了窗口的哪個部分,從而作出相應的處理。句柄就好像是一個人的身份證,有了它,你就可以從事各種社會活動;否則的話,你要麼是一個社會看不到的黑戶,要麼跟在別人後面,通過別人來證明你的存在。

三、 消息的傳送
1、從消息隊列獲取消息:

可以通過PeekMessage或GetMessage函數從Windows消息隊列中獲取消息。Windows保存的消息隊列是以線程(Thread)來分組的,也就是說每個線程都有自己的消息隊列。

2、發送消息

發送消息到指定窗體一般通過以下兩個函數完成:SendMessage和PostMessage。兩個函數的區別在於:PostMessage函數只是向線程消息隊列中添加消息,如果添加成功,則返回True,否則返回False,消息是否被處理,或處理的結果,就不知道了。而SendMessage則有些不同,它並不是把消息加入到隊列里,而是直接翻譯消息和調用消息處理,直到消息處理完成後才返回。所以,如果我們希望發送的消息立即被執行,就應該調用SendMessage。

還有一點,就是SendMessage發送的消息由於不會被加入到消息隊列中,所以通過PeekMessage或GetMessage是不能獲取到由SendMessage發送的消息。

另外,有些消息用PostMessage不會成功,比如wm_settext。所以不是所有的消息都能夠用PostMessage的。

還有一些其它的發送消息API函數,如PostThreadMessage,SendMessageCallback,SendMessageTimeout,SendNotifyMessage等。

四、 消息循環與窗體過程
消息循環是應用程序能夠持續存在的根本原因。如果循環退出,則應用程序就結束了。

我們來看一看Delphi中封裝的消息循環是怎樣的:

第一步:程序開始運行(Run)

Application.Initialize;//初始化

Application.CreateForm(TForm1, Form1);//創建主窗體

Application.Run;//開始運行,准備進行消息循環

如果不創建主窗體,應用程序同樣可以存在和運行。

第二步:開始調用消息循環(HandleMessage)

procere TApplication.Run;

begin

FRunning := True;

try

AddExitProc(DoneApplication);

if FMainForm <> nil then

begin

case CmdShow of

SW_SHOWMINNOACTIVE: FMainForm.FWindowState := wsMinimized;

SW_SHOWMAXIMIZED: MainForm.WindowState := wsMaximized;

end;

if FShowMainForm then

if FMainForm.FWindowState = wsMinimized then

Minimize else

FMainForm.Visible := True;

Repeat //註:循環開始

try

HandleMessage;

except

HandleException(Self);

end;

until Terminated;//循環結束條件

end;

finally

FRunning := False;

end;

end;

第三步:消息循環中對消息的處理。

procere TApplication.HandleMessage;

var

Msg: TMsg;

begin

if not ProcessMessage(Msg) then Idle(Msg);

end;

function TApplication.ProcessMessage(var Msg: TMsg): Boolean;

var

Handled: Boolean;

begin

Result := False;

if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then

begin

Result := True;

if Msg.Message <> WM_QUIT then

begin

Handled := False;

if Assigned(FOnMessage) then FOnMessage(Msg, Handled);

if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and

not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then

begin

TranslateMessage(Msg);

DispatchMessage(Msg);

end;

end

else

FTerminate := True;

end;

end;

窗體過程實際上是一個回調函數。所謂的回調函數,實際上就是由Windows操作系統或外部程序調用的函數。回調函數一般都有規定的參數格式,以地址方式傳遞給調用者。窗口過程中是Windows操作系統調用了,在一個窗口創建的時候,在分配窗體句柄的時候就需要傳入回調函數地址。那為什麼我們平時編程看不到這個回調函數呢?這是由於我們的編程工具已經為我們生成了默認的窗體過程,這個過程的要做的事情就是判斷不同的消息類型,然後做出不同的處理。例如可以為鍵盤或滑鼠輸入生成事件等。

五、 消息與事件
事件本質上是對消息的封裝,是IDE編程環境為了簡化編程而提供的有用的工具。這個封裝是在窗體過程中實現的。每種IDE封裝了許多Windows的消息,例如:

事件
消息

OnActivate
WM_ACTIVATE

OnClick
WM_XBUTTONDOWN

OnCreate
WM_CREATE

OnDblClick
WM_XBUTTONDBLCLICK

OnKeyDown
WM_KEYDOWN

OnKeyPress
WM_CHAR

OnKeyUp
WIN_KEYUP

OnPaint
WM_PAINT

OnResize
WM_SIZE

OnTimer
WM_TIMER

了解了這一點後,我們完成可以封裝自己的事件。

通過上面的介紹,相信各位已經對Windows消息機制有了一定的理解了。通過Windows消息編程,我們不但可以實現很多常規功能,而且可以實現很多IDE類庫沒有提供的功能;另外,我們還可以通過消息鉤子,對消息進行截獲,改變其默認的處理函數,從而突破平台或軟體功能的限制,極大的擴展程序的功能;我們還可以修改默認的窗體過程,按自己的要求來響應消息;或者自定義消息,實現程序之間的即時通訊等等。通過更加深入的學習,我們還會接觸到更多與Windows消息機制相關其它Windows相對比較底層的知識,如果能夠這樣,驀然回首,你會發現自己原來離「高手」不遠了。

B. windows消息機制是怎麼一回事謝謝!

Windows的消息系統是由3個部分組成的:
· 消息隊列。Windows能夠為所有的應用程序維護一個消息隊列。應用程序必須從消息隊列中獲取
消息,然後分派給某個窗口。
· 消息循環。通過這個循環機制應用程序從消息隊列中檢索消息,再把它分派給適當的窗口,然
後繼續從消息隊列中檢索下一條消息,再分派給適當的窗口,依次進行。
· 窗口過程。每個窗口都有一個窗口過程來接收傳遞給窗口的消息,它的任務就是獲取消息然後
響應它。窗口過程是一個回調函數;處理了一個消息後,它通常要返回一個值給Windows。
注意回調函數是程序中的一種函數,它是友敗由Windows或外部模塊調用的。
一個消息從產生到被一個窗口響應,其中有5個步驟:
1) 系統中發生了某個事件。
2) Windows把這個事件翻譯為消息,然後把它放到消息隊列中。
3) 應用程序從消息隊列中接收到這個消息,把它存放在TMsg記錄中。
4) 應用程序把消息傳遞給一個適當的窗口的窗口過程。
5) 窗口過程響應這個消息並進行處理。
步驟3和4構成了應用程序的消息循環。消息循環往往是Windows應用程序的核心,因為消息循環
使一個應用程序能夠響應外部的事件。消息循環的任務就是從消息隊列中檢索消息,然後把消息傳遞給適當的窗口。如果消息隊列中沒有消息,Windows就允許其他應用程序處理它們的消息。
Windows操作系統最大的特點就是其圖形化的操作界面,其圖形化界面是建立在其消息處理機制這個基礎之上的。如果不理李悄解Windows消息處理機制,肯定無法深入的理解Windows編程。可惜很多程序員對Windows消息只是略有所聞,對其使用知之甚少,更不了解其內部實現原理,本文試著一步一步向大家披露我理解的Windows消息機制。可以說,掌握了這一部分知識,就是掌握了Windows編程中的神兵利器,靈活哪告渣運用它,將會極大的提高我們的編程能力。

C. 請問如何簡述windows消息機制

Windows的應用程序一般包含窗口(Window),它主要為用戶提供一種可視化的交互方式,窗口是總是在某個線程(Thread)內創建團信的。Windows系統通過消息機制來管理交互,消息(Message)被發送,保存,處理,一個線程會維護自己的一套消息隊列(Message Queue),以保持線程間的獨占性。隊列的特點無非是先進先出,這種機制可以實現一種非同步的需求響應過程。
如何發送消息?

消息的發送終歸通過函數調用,比較常用的有PostMessage(),SendMessage(),另外還有一些Post*或Send*的函數。函數的調用者即發送消息的人。

誰來發送消息?硬體輸入是如何被響應的?

消息可以由Windows系統發送,也可以由應用程序本身;可以向線程內發送,也可以誇線程。主要是看發送函數的調用者。

對於硬體消息,Windows系統啟動時會運行一個叫Raw Input Thread的線程,簡稱RIT。這個線程負責處理System Hardware Input Queue(SHIQ)裡面的消息,這些消息由硬體驅動發送。RIT負責把SHIQ里的消息分發到線程的消息隊列裡面,那RIT是如何知道該發給誰呢?如果是滑鼠事件,那就看滑鼠指針所指的塌雀輪窗口屬於哪個線程,如果是鍵盤那就看哪個窗口當前是激活的。一些特殊的按鍵會有所不同,比如 Alt+Tab,Ctrl+Alt+Del等,RIT能保證他們不受當前線程的影響而死鎖。RIT只能同時和一個歲襲線程關聯起來。

D. windows消息機制流程

(1)操作系統接收到應用程序的窗口消息,將消息投遞到該應用程序的消息隊列中。 (2)應用程序在消息循環中調用GetMessage函數從消息隊列中取出一條一條的消息。取出消息後,應用程序可以對消息進行一些預處理,例如,放棄對某些消息的響應,或者調用TranslateMessage產生新的消息。 (3)應用程序調用DispatchMessage,將消息回傳給操作系統。消息是由MSG結構體對象來表示的,其中就包含了接收消息的窗口的句柄。因此,DispatchMessage函數總能進行正確的傳遞。 (4)系統利用WNDCLASS結構體的lpfnWndProc成員保液手存的窗口過程函數的指針調用窗口過稿慧程,對消息進行處理(即「系統給應用程序發送了消息」)。 注意:消息映射為什麼不是虛函數呢? 答:C++有一個名為vtable的虛函數分發表。如果用虛函數發送消息CWnd將為超過100個消息來申明虛函數,對於沒個虛函數,vtable中對應有4個位元組,那麼應用程序將需要400多個位元組的表來支持虛擬消息處理函數。所以為了避免大型鍵埋答的vtable,MFC使用宏來把WINDOWS消息連接到C++成員函數。MFC消息處理程序需要函數原型,函數體和在消息映射中的輸入項(宏調用),ClassWizard幫助我們將消息處理程序添加到類中。

E. 理解windows消息機制

消息機制是Windows應用程序的核心。在Windows中發生的一切都可以用消息來表示,消息用於告訴操作系統發生了什麼,所有的Windows應用程序都是消息驅動的,
在Windows中,不同的消息由應用程序的不同部分進行處理。MFC庫將很多底層的消息都屏蔽了,使用戶更加方便、簡易地處理消息。例如,用戶接收到諸如移動滑鼠鍵(WM_MOUSEMOVE)消息或單擊滑鼠鍵(WM_LRBUTTONDOWN)消息時不必處理窗口和滑鼠的重畫工作,MFC及應用程序框架會替用戶做這些工作。在使用MFC進行編程時,用戶只需處理一些高層的消息,例如,「用戶在單擊窗口中的OK按扭」,「用戶現在選中了下拉列表框中的第五項」等等,這樣就大大減輕了程序員的負擔。
一個消息是由消息的名稱(UINT)和兩個參數(WPARAM, LPARAM)組成。消息的參數中鎮笑敬包含有重要的信息。例如對滑鼠消息而言,LPARAM中一般包含滑鼠的位置信息,而WPARAM參數中包含了發生該消息時,SHIFT、CTRL等鍵的狀態信息,對於不同的消息類型來說,兩個參數也都相應地具有明確意義。
消息與輸入焦點
Windows是一個以消息為導向的系統,應用程序只能被動地等待用戶按鍵的消息,不能主動地去讀鍵盤的狀態,也就是說,每當鍵盤上有個鍵被按下,系統就會發出一個按鍵消息給窗口,告訴它某個鍵被按下去了,只要滑鼠移動一下,系統也會發出相應的消息,並把滑鼠的坐標信息傳給窗口。
Windows可以同時執行許多程序,但鍵盤只有一個,怎麼判斷由哪個窗口接收鍵盤及滑鼠的消息呢?採用「輸入焦點」(inpuut focus)技術可以解決這個問題。只要某個窗口取得輸入焦點,它不但會被提升到屏幕的最前面,顏色也會有所不同,所有的鍵盤消息就會導向該窗口,該窗口也成為「活動窗口」。
窗口如何取得輸入焦點?通常被滑鼠單擊的窗口會得到輸入焦點,除此之外,程序本身也可以利用SetFocus()來指定哪個窗口擁有輸入焦點。
CWnd* CWnd::SetFocus();
如果調用某窗口的SetFocus()成員函數,該窗口就可以取得輸入焦點,該函數返回前一個擁有輸入焦點的窗口。
如果某個窗口的輸入焦點被搶走,Windows系統就會發出WM_KILLFOCUS消息御慎給這個失去輸入焦點的窗口,同時還會告訴該窗口下一個取得輸入焦點的窗口的指針。而獲得輸入焦點的窗口則會收到WM_SETFOCUS消息。
消息響應函數分別為:
afx_msg void OnKillFocus(CWnd* pNewWnd);
其中的參數為得到輸入焦點的窗口的指針。
Afx_msg void OnSetFocus(CWnd* pOldWnd);
其中的參數為失去輸入焦點的窗口的指升閉針。
消息的分類
Windows系統預定義了許多消息,每個消息都擁有一個宏定義,即用形象的字元串來標識消息,一系列#define 語句將消息與特定數值聯系起來,可以在頭文件WinUser.h中找到這些宏定義,例如
#define WM_PAINT 120
可以在程序中通過消息名「WM_PAINT」來訪問它。其他消息如:
#define WM_MOUSEMOVE 0x0200
#define WM_LBUTTONDOWN 0x0201
#define WM_LBUTTONUP 0x0202
#define WM_LBUTTONDBLCLK 0x0203
#define WM_RBUTTONDOWN 0x0204
#define WM_RBUTTONUP 0x0205
#define WM_RBUTTONDBLCLK 0x0206
#define WM_MBUTTONDOWN 0x0207
#define WM_MBUTTONUP 0x0208
#define WM_MBUTTONDBLCLK 0x0209
系統定義的消息有不同的前綴,不同的前綴有不同的含義。