delphi中的訊息
訊息是windows發出的乙個通知,它告訴應用程式某個事件發生了。在delphi中,大多數情況下windows的訊息被封裝在vcl的事件中,我們只需處理相應的vcl事件就可以了,但如果我們需要編寫自己的控制項、截獲或過濾訊息就必須深入研究win32的訊息處理機制。
在delphi中訊息以tmessage記錄的方式定義。開啟message.pas檔案,我們可以看到tmessage是這樣定義的:
type
tmessage = packed record
msg: cardinal;
case integer of
0: ( wparam: longint;
lparam: longint;
result: longint);
1: ( wparamlo: word;
wparamhi: word;
lparamlo: word;
lparamhi: word;
resultlo: word;
resulthi: word);
end;
其中,msg是區別於其他訊息的常量值,這些常量值可以是windows單元中預定義的常量,也可以是使用者自己定義的常量。wparam通常是乙個與訊息有關的常量值,也可以是視窗或控制項的控制代碼。lparam通常是乙個指向記憶體中資料的指標。
result是訊息處理的返回值。wparam、lparam和result都是32位的,如果想訪問其中的低16位或高16位可以分別使用wparamlo、wparamhi、 lparamlo、lparamhi、resultlo和resulthi。
在delphi中除了通用的tmessage外,還為每個windows定義了乙個特殊的訊息記錄。我們可以瀏覽message.pas檔案,下面是鍵盤的訊息記錄:
twmkey = packed record
msg: cardinal;
charcode: word;
unused: word;
keydata: longint;
result: longint;
與鍵盤相關的訊息如:wm_keydown、 wm_keyup、 wm_char、 wm_syskeydown wm_syskeyup、 wm_syschar的記錄也被定義為twmkey。在message.pas檔案中有以下宣告:
twmchar=twmkey; twmkeydown=
twmkey;twmkeyup=twmkey; twmsys
-keydown=twmkey; twmsyskeyup=
twmkey;twmsyschar=twmkey;
訊息的傳送
訊息處理就是定義應用程式如何響應windows的訊息。在delphi中每乙個訊息都有自己的處理過程,它必須是乙個物件中的方法,且只能傳遞乙個tmessage或其他特殊的訊息記錄,方法宣告後要有乙個message命令,後接乙個在0到32767之間的常量。
前面我們提到的訊息都是標準的windows訊息(wm_x),除此之外還有vcl內部訊息、通知訊息和使用者自定義訊息。
vcl內部訊息通常以「cm_」開頭,用於管理vcl內部的事物。如果改變了某個屬性值或元件的其他一些特性後,需要通過內部訊息將該變化通知其他元件。例如,啟用輸入焦點訊息是向被啟用的或被停用的元件傳送的,用於接受或放棄輸入焦點。
另外還有通知訊息,乙個視窗內的子控制項發生了一些事情,需要通知父視窗,這是通過通知訊息實現的。它只適用於標準的視窗控制項,如按鈕、列表框、編輯框等等。開啟message.pas檔案,在標準的windows後就是通知訊息的宣告:
const
bn_clicked = 0;
bn_paint = 1;
bn_hilite = 2;
以上是按鈕的通知訊息,分別表示使用者單擊了按鈕、按鈕應當重畫、使用者加亮了按鈕。
使用者也可以自己定義訊息、給自己傳送訊息和編寫訊息處理過程。訊息的常量值為wm_user+100到$7fff, 這個範圍是windows為使用者自定義訊息保留的。
delphi訊息的傳送有三種方法:
1.tcontrol類的perform物件方法。可以向任何乙個窗體或控制項傳送訊息,只需要知道窗體或控制項的例項。其宣告如下:
function tcontrol.perform(msg:cardinal;wparam,lparam:longint):longint
2.windows的api函式sendmessage()和postmessage()。其宣告如下:
function sendmessage(hwnd: hwnd; msg: uint;wparam:wparam; lparam: lparam):lresult;stdcall;
function sendmessage(hwnd: hwnd; msg: uint;wparam: wparam; lparam:lparam):lresult;stdcall
postmessage函式將訊息新增到應用程式的訊息佇列中去。應用程式的訊息迴圈會從訊息佇列中提取登記的該訊息,再傳送到相應的視窗中。
sendmessage函式可以越過訊息佇列直接向視窗過程傳送。所以當windows需要立刻返回值時使用sendmessage,當需要不同的應用程式依次處理訊息時使用postmessage。而perform從本質上和sendmessage相似,它們直接向視窗過程傳送。sendmessage、postmessage函式只需要知道視窗的控制代碼就可以傳送訊息,所以它們可以向非delphi窗體傳送一條訊息,但而perform必須知道窗體或控制項的例項。
vcl訊息處理機制
type tmessageevent = procedure (var msg: tmsg; var handled: boolean) of object;
其中tmsg是windows中定義的訊息記錄,我們可以這樣宣告:
procedure onmymessage(var msg:tmsg;var handled:boolean);
onmessage事件將捕獲傳送給應用程式的所有訊息,這是乙個非常繁忙的事件,因此在處理onmessage事件的處理過程中設定斷點進行訊息處理是不明智的。
vcl物件用於接收訊息的方法叫mainwndproc。它是定義在twincontrol類中的靜態方法,不能被過載。它不直接處理訊息,當訊息離開mainwndproc後,訊息被傳遞給物件的wndproc方法,wndproc方法是在tcontrol類中定義的乙個虛擬方法,由它呼叫dispatch方法。dispatch根據傳入的message來尋找相應的處理方法,如果最後找不到,就繼續向上到父類中尋找訊息處理方法,一直到找到為止,如果找不到則呼叫defaulthandler。defaulthandler方法對訊息進行最後的處理,然後把訊息傳遞給windows的defwindowproc函式或其他預設的視窗過程。
delphi訊息處理
摘自 劉藝 delphi6企業級解決方案與應用剖析 2009 8 23 delphi訊息處理 訊息的資料結構 tmessage record msg word case integer of 0 wparam word lparam longint result longint 1 wparamlo...
Delphi中的訊息處理
1 windows的訊息驅動體系 在windows系統中,訊息傳遞是實現物件間通訊和控制的主要手段。可以系統都以訊息驅動的方式工作。系統中發生的使用者輸入操作 顯示資訊的改變 系統環境引數變化等所有事件都以系統定義訊息的形式出現在相關的應用程式和視窗。所以程式設計的主要任務就是為這些訊息的處理設計 ...
delphi的訊息處理的相關函式
twincontrol.mainwndproc tcontrol.wndproc tobject.dispatch tobject.defaulthandler procedure twincontrol.mainwndproc var message tmessage begin try try ...