zoukankan      html  css  js  c++  java
  • DIY自己的AllocateHWnd函数

    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;
  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/3886796.html
Copyright © 2011-2022 走看看