程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi的消息處理

Delphi的消息處理

編輯:Delphi
Delphi是Borland公司的一種面向對象的可視化軟件開發工具。 Delphi集中了Visual C++和Visual Basic兩者的優點:容易上手、功能強大,特別是在界面設計、數據庫編程、網絡編程方面更有其獨特的優勢。
  
  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
  
  {$EXTERNALSYM BN_CLICKED}
  
  BN_CLICKED = 0;
  
  {$EXTERNALSYM BN_PAINT}
  
  BN_PAINT = 1;
  
  {$EXTERNALSYM BN_HILITE}
  
  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消息處理機制
  
  在Delphi應用程序的源代碼中有語句Application.Run,它的作用是啟動消息循環,然後調用Application.ProcessMessage,該函數會在應用程序的消息隊列中查找一條消息。當在消息隊列中檢索到一條消息後,觸發Application.OnMessage事件。這樣在Windows本身對消息處理之前,就會響應OnMessage事件的處理過程,它優於任何消息處理,而且只接收登記的消息,即前面所述的由PostMessage發送的消息。響應Application.OnMessage事件的處理過程必須是TmessageEvent類型,其聲明如下:
  
  type TMessageEvent = procedure (var Msg: TMsg; var Handled: Boolean) of object;
  
  其中TMsg是Windows中定義的消息記錄,我們可以這樣聲明:
  
  Procedure OnMyMessage(var Msg:TMsg;var Handled:Boolean);
  
  然後把此方法賦給Application.OnMessage事件:
  
  Application.OnMessage :=OnMyMessage;
  
  OnMessage事件將捕獲發送給應用程序的所有消息,這是一個非常繁忙的事件,因此在處理OnMessage事件的處理過程中設置斷點進行消息處理是不明智的。
  
  VCL對象用於接收消息的方法叫MainWndProc。它是定義在Twincontrol類中的靜態方法,不能被重載。它不直接處理消息,當消息離開MainWndProc後,消息被傳遞給對象的WndProc方法,WndProc方法是在Tcontrol類中定義的一個虛擬方法,由它調用Dispatch方法。Dispatch根據傳入的Message來尋找相應的處理方法,如果最後找不到,就繼續向上到父類中尋找消息處理方法,一直到找到為止,如果找不到則調用Defaulthandler。Defaulthandler方法對消息進行最後的處理,然後把消息傳遞給Windows的DefWindowProc函數或其他默認的窗口過程。
  
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved