Classes單元的AllocateHWnd函式是需要傳入一個處理訊息的類的方法的作為引數的,原型:
function
AllocateHWnd(Method: TWndMethod): HWND;
很多時候,我們想要建立一個視窗,而又不想因為這個引數而建立一個類,怎麼辦?
換句話說,就是能不能使傳入的引數是個普通的函式而不是類的方法呢?答案是肯定的!
看看TWndMethod的宣告:
換句話說,就是能不能使傳入的引數是個普通的函式而不是類的方法呢?答案是肯定的!
看看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;