消息流程:
譬如用鼠標左鍵點擊一下窗體, 系統會收到一條 WM_LBUTTONDOWN 消息;
當鼠標抬起, 系統又會收到 WM_LBUTTONUP 消息.
系統收到消息後, 會告訴窗體發生的事情, 然後窗體再做出反應; 當然窗體能否做出反應要看窗體是否有相應的響應代碼.
要響應 WM_LBUTTONDOWN 消息, 我們需要在 OnMouseDown 事件中寫代碼;
要響應 WM_LBUTTONUP 消息, 我們需要在 OnMouseUp 事件中寫代碼;
當然我們也可以通過其他方法(譬如消息方法)來響應消息.
關於消息流程, 這樣說其實不夠完整, 更詳細的流程可以參見:
Windows 編程系列.
消息發送:
我們通過鼠標、鍵盤等操作, 就在有意無意地隨時向系統發送消息; 但有時我也需要間接發送消息, 譬如: 我們並不需要點擊窗體, 也可以向窗體發送一條 WM_LBUTTONDOWN 消息, 從而引發 OnMouseDown 事件的執行.
發送消息的常用函數:
function SendMessage(
hWnd: HWND; {目標句柄}
Msg: UINT; {要發送的消息(編號)}
wParam: WPARAM; {消息參數}
lParam: LPARAM {消息參數}
): LRESULT; stdcall; {返回處理結果}
function PostMessage(
hWnd: HWND; {目標句柄}
Msg: UINT; {要發送的消息(編號)}
wParam: WPARAM; {消息參數}
lParam: LPARAM {消息參數}
): BOOL; stdcall; {是否發送成功}
function Perform(
Msg: Cardinal; {要發送的消息(編號)}
WParam: WPARAM; {消息參數}
LParam: LPARAM {消息參數}
): LRESULT; {返回處理結果}
SendMessage 發送消息後會等待處理結果;
PostMessage 把消息送人等待處理的消息隊列.
發送 SendMessage 消息好比: 你扔一顆手榴彈到敵群中, 並期待看到血肉橫飛的場面;
發送 PostMessage 消息好比: 你在敵人就要路過的地方埋上一顆地雷, 你就不管了.
其實 SendMessage 和 PostMessage 在實用過程中區別並不是很大.
Perform 和上面兩個不同, 它是控件的一個方法, 最早定義在 TControl 類, TControl 的子孫都有這個方法, TControl 之上的父類們不需要處理消息, 也沒有消息要處理.
Perform 和 SendMessage 更相似, 但貌似少了一個參數, 其實沒有, 只是換了一下位置, 看它的調用對比:
SendMessage(控件句柄, 消息, 參數, 參數);
控件.Perform(消息, 參數, 參數);
消息和消息參數:
消息就是一個整數, 就是微軟給做的一個編號:
0 .. WM_USER-1: Windows 使用
WM_USER .. $7FFF: 窗體類使用
$8000 .. $BFFF: 保留
$C000 .. $FFFF: 應用程序使用
大於 $FFFF: 保留
Delphi 也自定義了一些消息, 分別是 CM_ 和 CN_ 打頭.
消息參數是個比較復雜的概念, 因為不同的消息有不同的參數規定, 其實學習消息的過程就是學習消息參數.
不過有些消息的參數就特簡單, 譬如 WM_CLOSE 是關閉窗口的消息, 它不需要什麼參數(不需要也要按格式寫個數).
下面的例子使用四種不同的方法來關閉窗口:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
SendMessage(Self.Handle, WM_CLOSE, 0, 0);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
PostMessage(Self.Handle, WM_CLOSE, 0, 0);
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Self.Perform(WM_CLOSE, 0, 0);
end;
end.