1、windows的消息驅動體系
在windows系統中,消息傳遞是實現對鄉間通信和控制的主要手段。可以額系統都以消息驅動的方式工作。系統中發生的用戶輸入操作、顯示信息的改變、系統環境參數變化等所有時間都以系統定義消息的形式出現在相關的應用程序和窗口。所以程序設計的主要任務就是為這些消息的處理設計代碼。
在應用程序中,發送者可以通過發送消息要求接收者完成相應的處理。當程序運行時,windows系統為每個應用程序實例建立一個消息隊列,一次保存發送給該程序實例的消息,在應用程序的主控部分,需要設置一個消息循環,利用一組系統函數從該程序實例的消息隊列中依次讀取和分析消息,並將他們發送給指定的消息。這種消息傳遞可以使用系統定義消息,也可以使用用戶自定義的消息。現有的多種可視化開發環境,都已經將這一過程封裝到了各種類,部件,以及部件的方法中。
當我們利用它們寫一個應用程序時,必須考慮每個對象要做什麼,將他們分解為不同的消息處理函數,並且對應不同的消息。雖然有的控件(部件)種類繁多,編寫程序非常便利。但這些畢竟是一些通用的對象和消息處理函數,如果我們要編寫自己的部件或者想要更加靈活的運用現有控件就必須深刻了解消息驅動體系以及消息的映射,消息處理函數編寫和系統有關消息操作的函數。
2、DELPHI開發環境:
DELPHI已成為日益普及的優秀的32位WINDOWS開發環境,其中一個最大的特點就是在DELPHI 中可自定義消息寫自己的構件(Cmponent)的,因為編寫構件一般要對相應的消息進行處理.。
3、DELPHI中的消息:
在Delphi 中所有的類都有一個內建的用於處理消息、調用消息處理過程的機制。VCL定義了發送所有WINDOWS消息(包括自定義消息)的消息派送系統,你只需要建立消息處理方法。一個Windows 消息是一個包含多個字段的數據記錄。其中最重要的是消息標識,在WINDOWS中已經定義了許多消息其他有用的字段是兩個參數和一個結果字段。一個16位和一個32位參數wparan錄數據類型:
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;
esultLo: Word;
ResultHi: Word);
end;
4、消息的使用:
在DELPHI中用戶可以自定義消息及消息處理句柄消息處理句柄的定義有如下幾個原則:
1、消息處理句柄方法必須是一個過程
2、方法聲明後要有一個message命令型常數).
3、消息處理句柄方法不需要用override 命令來顯式指明重載祖先的一個消息處理句柄
4、在消息處理句柄中一般先是用戶自己對消息的處理用祖先類中對應此消息的處理句柄(有些情況下可能正相反).由於可能對祖先類中對此消息的處理句柄的名字和參數類型不清楚避免此麻煩調用Defaulthandler方法.(當然如果要屏蔽掉此消息了)。
消息處理句柄方法聲明為:
procedure Mymsgmethod(var message:Tmessage); message Msgtype;
同樣用戶也可以定義自己的消息自定義消息及消息處理句柄舉例如下:
const my_paint=Wm_user+1;
type
Tmypaint=record
msgid:cardinal;
msize:word;
mcolor:longint;
msgresult:longint;
end; //也可以使用Tmessage類型
type
Tmycontrol=class(TCustomControl)
protected
procedure change(var message:Tmypaint); message my_paint;
.....
end;
......
procedure Tmycontrol.change(var message:Tmypaint);
begin
size:=message.msize; { 設 置Tmybutton 尺 寸 屬 性}
color:=message.mcolor; { 設 置Tmybutton 顏 色 屬 性}
{do something else}
inherited; { 交 由Tcustomcontrol 處 理}
end;
重載消息句柄方法:你可以直接重載windows定義的窗口消息添加自己的處理。例如在應用中重載windows的窗口消息wm_paint:
type
TMyComponent = class(...)
...
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
end;
然後再實現部分添加消息句柄的過程。
5、delphi中有關消息的重要函數和屬性:
(1) procedure DefaultHandler(var Message); virtual;
如果一個對象處理某個消息,則該函數提供對消息的默認處理。
(2) procedure Dispatch(var Message); virtual;
這個函數用於調用對象的消息處理函數。
(3)Windowproc屬性:
type TWndMethod = procedure(var Message: TMessage) of object;
property WindowProc: TWndMethod;
這個屬性用於指定一個函數,用這個函數來響應message參數指定的windows消息。例如:
procedure TMyListBoxDescendant.ToggleSubClass(On: Boolean);
begin
if On then
WindowProc := SubClassWndProc;
else
WindowProc := WndProc;
end;
(4)function Perform(Msg: Cardinal; WParam這個函數用來向控件自己發一個消息。
例如:
procedure TForm1.Button1Click(Sender: TObject);
begin
with RichEdit1 do
Begin
SelStart := StrToInt(MaskEdit1.Text);
RichEdit1.Perform(EM_SCROLLCARET
end;
end;
(5)procedure Broadcast(var Message);這個函數用於向所有的子控件廣播一個消息。
(6)procedure DefaultHandler(var Message); virtual;該函數提供了隊所有消息的默認處理,可以重載這個虛擬函數。Message參數是無類型的,但可以強制轉換成Tmessage類型。
6、windows API中有關消息的幾個重要函數:
(1)GetMessage函數:
BOOL GetMessage(LPMSG lpMsg HWND hWnd
UINT wMsgFilterMin UINT wMsgFilterMax// 最後的消息);
delphi中的定義:
function GetMessageA(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin
這個函數可以有選擇的從消息隊列重得到消息。
(2)TranslateMessage函數:
BOOL TranslateMessage(CONST MSG *lpMsg // 消息的地址);
delphi中的定義:
function TranslateMessage(const lpMsg: TMsg): BOOL; stdcall;
這個函數用於將virtul-key消息翻譯為字符消息。
(3)DispatchMessage函數:
LONG DispatchMessage(CONST MSG *lpmsg // 消息的指針);
delphi中的定義:
function DispatchMessage(const lpMsg: TMsg): Longint; stdcall;
這個函數派送消息到窗口過程。
(4)PostMessage函數:
BOOL PostMessage(HWND hWnd UINT Msg WPARAM wParam
LPARAM lParam // 第二個消息參數);
delphi中的定義:
function PostMessageA(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;這個函數用於將消息傳送到窗口的消息隊列。