標籤:
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;這個函數用於將訊息傳送到視窗的訊息佇列。
轉自:http://www.cnblogs.com/railgunman/articles/1790078.html
Delphi中的訊息處理