當前位置:成語大全網 - 書法字典 - windows消息處理機制的消息實現

windows消息處理機制的消息實現

Windows窗體是如何在屏幕上顯示的?眾所周知,它是通過API繪圖來實現的。Windows操作系統提供了壹系列API函數來實現界面的繪制功能,例如:

繪制文本

DrawEdge繪制邊框

繪圖圖標繪圖圖標

位圖繪制位圖

矩形繪制矩形

無論程序界面多麽復雜,都是由這些函數實現的。

那麽什麽時候調用這些函數呢?顯然,我們需要壹個控制中心來下達命令,我們還需要壹個命令傳輸機制來將命令立即送達目的地。這個控制中心是壹個能量源,就像心臟壹樣,源源不斷地向各處輸送血液。這種命令傳輸機制就是Windows消息機制。Windows消息就像身體裏的血液,是命令傳遞的信使。

Windows消息控制中心通常是三層結構,最頂層是Windows內核。Windows內核維護壹個消息隊列,二級控制中心從這個消息隊列中獲取其管轄的消息,然後進行處理。壹些消息被直接處理,而其他消息被發送到下壹級窗口或控件。二級控制中心壹般是每個Windows應用程序的應用對象。第三級控制中心是Windows窗體對象,每個窗體都有壹個默認的窗體進程,負責處理收到的各種消息。如下圖所示:

(註:windows指windows操作系統;窗口:即windows窗口;窗體:包括帶有句柄的窗口和控件;控件是指壹個控件,它本身可能是也可能不是壹個窗口;應用程序是壹個應用程序,該應用程序可能不使用Windows消息機制。這裏我們討論消息循環的應用程序。)

消息以固定的結構傳輸到應用程序,如下所示:

公共類型消息

hwnd壹樣長

消息長度

wParam壹樣長

lParam壹樣長

時間壹樣長

pt As POINTAPI

結束類型

其中hwnd是表單的句柄,message是指示消息類型的消息常數,wParam和lParam都是32位的附加信息,這取決於消息的類型,time是發送消息的時間,pt是發送消息時鼠標的位置。

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

1,標準Windows消息:

此消息以WM_開頭。

2.通知消息

通知消息是標準Windows控件的消息。這些控件包括:按鈕、組合框、編輯框、列表框、列表視圖控件、樹視圖控件、工具欄、菜單等。每條消息都以不同的字符串開頭。

3.自定義消息

程序員也可以定制消息。並非每個控件都可以接收消息、轉發消息和繪制自身。只有帶手柄的控件才能做到這壹點。有句柄的控件本質上是壹個窗口,它可以獨立存在,可以作為其他控件的容器,而沒有句柄的控件(如Label)不能獨立存在,只能作為窗口控件的子控件。他們自己不會畫,只能依靠父窗體來畫。

句柄的本質是壹個由系統自動維護的32位值,它在整個操作系統中的任何時刻都是唯壹的。但是,句柄所代表的表單被釋放後,句柄也將被釋放,並且該值可能會被其他表單使用。也就是說,句柄的值是動態的,並且它只是壹個唯壹的標識符。操作系統使用句柄來識別和查找它所代表的對象。

然而,並不是所有的句柄都是窗體的句柄,在Windows系統中還有許多其他類型的句柄,例如畫布(hdc)句柄、畫筆句柄、繪畫畫筆句柄和應用程序句柄。此句柄無法接收消息。但無論是哪種句柄,它都是對象在系統中的唯壹標識。本文只討論表單句柄。

那為什麽把手會讓窗戶如此獨特呢?其實都是因為新聞。由於有了句柄,窗體可以接收消息,因此它知道何時繪制自己,繪制子控件,並知道鼠標何時單擊了窗口的哪個部分,從而做出相應的處理。手柄就像人的身份證,有了它就可以從事各種社會活動;否則,妳要麽是社會看不到的黑戶,要麽妳可以追隨他人,通過他人證明自己的存在。1.從消息隊列中獲取消息:

您可以通過PeekMessage或GetMessage函數從Windows消息隊列中獲取消息。Windows保存的消息隊列按線程分組,這意味著每個線程都有自己的消息隊列。

2.發送消息

將消息發送到指定的表單通常是通過以下兩個函數完成的:SendMessage和PostMessage。這兩個函數的區別在於PostMessage函數只向線程消息隊列添加壹條消息。如果消息添加成功,則返回True,否則返回False,並且消息是否被處理或處理的結果是未知的。另壹方面,SendMessage有些不同。它不是將消息添加到隊列中,而是直接翻譯消息並調用消息處理(即線程將消息發送給自己),並且在消息處理完成之前不會返回。因此,如果我們希望立即執行發送的消息,我們應該調用SendMessage。

還有壹點是SendMessage發送的消息不會被添加到消息隊列中(錯誤:線程發送給其他線程的消息也會被添加到其他線程的消息隊列中,即使這兩個線程處於同壹進程中),因此無法通過PeekMessage或GetMessage獲取SendMessage發送的消息。

此外,有些消息無法成功處理PostMessage,例如wm_settext。所以不是所有的消息都可以使用PostMessage。

還有壹些其他用於發送消息的API函數,如PostThreadMessage、SendMessageCallback、SendMessageTimeout、SendNotifyMessage等。消息流通是應用程序能夠繼續存在的根本原因。如果循環退出,應用程序結束。

讓我們看看Delphi中封裝的消息循環:

第壹步:程序開始運行。

申請。初始化;//初始化

申請。create form(t form 1,form 1);//創建主窗體

申請。跑步;//開始運行,並準備消息循環。

如果沒有創建主窗體,應用程序也可以存在和運行。

步驟2:開始調用HandleMessage。

程序應用。跑步;

開始

f running:= True;

嘗試

AddExitProc(done application);

if FMainForm & lt& gt那就零

開始

案例展示

SW_SHOWMINNOACTIVE: FMainForm。FWindowState:= ws minimized;

SW_SHOWMAXIMIZED: MainFormwindow state:= ws maximized;

結束;

如果FShowMainForm那麽

如果FMainForm。FWindowState = wsMinimized then

最小化else

FMainForm。visible:= True;

重復//註意:循環開始。

嘗試

HandleMessage

除...之外

handle exception(Self);

結束;

直至終止;//循環結束條件

結束;

最後

f running:= False;

結束;

結束;

步驟3:在消息周期中處理消息。

程序應用。HandleMessage

定義變量

msg:TMsg;

開始

如果不是process message(Msg),則為Idle(Msg );

結束;

功能應用。process message(var Msg:TMsg):Boolean;

定義變量

handled:Boolean;

開始

結果:= False

如果PeekMessage(Msg,0,0,0,PM_REMOVE),則

開始

結果:= True

如果味精。消息& lt& gt那就退出吧

開始

已處理:= False

如果賦值(FOnMessage),則為FOnMessage(Msg,Handled);

如果不是is intmsg(Msg)且未處理,則不是IsMDIMsg(Msg),並且

not IsKeyMsg(Msg)和not IsDlgMsg(Msg)then

開始

TranslateMessage

DispatchMessage

結束;

結束

其他

f terminate:= True;

結束;

結束;

表單過程實際上是壹個回調函數。所謂回調函數實際上是Windows操作系統或外部程序調用的函數。回調函數通常具有指定的參數格式,並通過地址傳遞給調用者。窗口進程中調用的Windows操作系統。創建窗口時,需要在分配表單句柄時傳入回調函數的地址。那為什麽我們在編程中通常看不到這個回調函數呢?這是因為我們的編程工具已經為我們生成了壹個默認的表單過程。這個程序需要做的是判斷不同的消息類型,然後做出不同的處理。例如,可以為鍵盤或鼠標輸入等生成事件。事件本質上是消息的封裝,是IDE編程環境提供的簡化編程的有用工具。這種封裝在表單流程中實現。每個IDE都封裝了許多Windows消息,例如,關於激活WM _ activate onclick WM _ xbuttondowoncreate WM _ createondblclick WM _ xbuttonblclick onkeydownwm _ keydowonkeypress的事件消息。WM _ CHAR OnKeyUp WIN _ KEYUP OnPaint WM _ PAINT on resize WM _ SIZE on TIMER WM _ TIMER