DIY自己的AllocateHWnd函式

Max Woods發表於2014-08-02

Classes單元的AllocateHWnd函式是需要傳入一個處理訊息的類的方法的作為引數的,原型:

function AllocateHWnd(Method: TWndMethod): HWND;
 
很多時候,我們想要建立一個視窗,而又不想因為這個引數而建立一個類,怎麼辦?
換句話說,就是能不能使傳入的引數是個普通的函式而不是類的方法呢?答案是肯定的!
看看TWndMethod的宣告:
 

type
TWndMethod = procedure(var Message: TMessage) of object;

 

實際上類的方法在執行時,總是傳入了物件這個引數。
即此方法共傳了兩個引數,根據Delphi預設的registry呼叫約定,暫存器eax傳遞物件,edx傳遞Message結構變數。

因此我們可以宣告處理訊息的函式的型別:

 

type
TMyWndProc = procedure(AObject: TObject; var Message: TMessage);

 

我們自定義MyAllocateHWnd函式以接收這個型別的引數,內部呼叫AllocateHWnd:

function MyAllocateHWnd(Proc: TMyWndProc): HWND;
asm
  push 0//AObject
  push Proc//Message
  call AllocateHWnd
end;

 

ps:如果直接呼叫AllocateHwnd(Proc)是不能通過編譯的!

//呼叫示例:

var H: HWND;

procedure MyWndProc(AObject: TObject; var Message: TMessage);
begin
if Message.Msg = WM_USER + 111 then
ShowMessage('')
else
Message.Result := DefWindowProc(H, Message.Msg, Message.WParam, Message.LParam)
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
H := MyAllocateHWnd(MyWndProc)
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
DeallocateHWnd(H);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
SendMessage(H, WM_USER + 111, 0, 0)
end;

相關文章