http://www.xuebuyuan.com/1889769.html

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 // AObject
push Proc// Message
call AllocateHWnd
end;

如果直接调用AllocateHwnd(Proc)是不能通过编译的!

var H: HWND;

procedure MyWndProc(AObject: TObject; var Message: TMessage);
begin
if Message.Msg = WM_USER + 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 + , , );
end;
unit uMain;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type
TForm1 = class( TForm )
Button1 : TButton;
procedure FormCreate( Sender : TObject );
procedure FormDestroy( Sender : TObject );
procedure Button1Click( Sender : TObject );
private
{ Private declarations }
public
{ Public declarations }
end; var
Form1 : TForm1; implementation {$R *.dfm} type
TMyWndProc = procedure( AObject : TObject; var Message : TMessage ); var
H : HWND; function MyAllocateHWnd( Proc : TMyWndProc ) : HWND;
asm
push // AObject
push Proc // Message
call AllocateHWnd
end; procedure MyWndProc( AObject : TObject; var Message : TMessage );
begin
if message.Msg = WM_USER + then
ShowMessage( 'Receive Message!' )
else
message.Result := DefWindowProc( H, message.Msg, message.WParam,
message.LParam )
end; procedure TForm1.Button1Click( Sender : TObject );
begin
PostMessage( H, WM_USER + , , );
end; procedure TForm1.FormCreate( Sender : TObject );
begin
H := MyAllocateHWnd( MyWndProc );
end; procedure TForm1.FormDestroy( Sender : TObject );
begin
DeallocateHWnd( H );
end; end.

让AllocateHwnd接受一般函数地址作参数的更多相关文章

  1. 让AllocateHwnd接受一般函数地址作参数(105篇博客)

    http://www.xuebuyuan.com/1889769.html Classes单元的AllocateHWnd函数是需要传入一个处理消息的类的方法的作为参数的,原型: function Al ...

  2. php函数按地址传递参数(php引用)

    php函数按地址传递参数(php引用) 一.总结 1.php引用:php引用和c++一样,都是在变量前加&(取地址符号) 2.php函数按地址传递参数:php函数按地址传递参数(php引用)也 ...

  3. python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False。

    python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False. 重难点:定义函数的方法.使用str类型的find()函数,可以 ...

  4. vlc 详细使用方法:libvlc_media_add_option 函数中的参数设置

    vlc 详细使用方法:libvlc_media_add_option 函数中的参数设置 [转载自]tinyle的专栏 [原文链接地址]http://blog.csdn.net/myaccella/ar ...

  5. nodeJS接受post传过来的参数

    1.nodeJs接受Post传递的参数需要通过绑定两个事件来获取, querystring = require("querystring");  1 app.post('/comm ...

  6. 百万年薪python之路 -- 函数的动态参数

    1.函数的动态参数 1.1 动态接收位置参数 在参数位置用*表示接受任意参数 def eat(*args): print('我想吃',args) eat('蒸羊羔','蒸熊掌','蒸鹿尾儿','烧花鸭 ...

  7. python27期day10:函数的动态参数、函数的注释、函数的名称空间、函数的嵌套、global(修改全局的)、nonlocal(修改局部的)、函数名的第一类对象及使用、作业题。

    1.动态参数的作用: 能够接收不固定长度参数 位置参数过多时可以使用动态参数 * args是程序员之间约定俗称(可以更换但是不建议更换) * args获取的是一个元组 ** kwargs获取的是一个字 ...

  8. Python函数02/函数的动态参数/函数的注释/名称空间/函数的嵌套/global以及nolocal的用法

    Python函数02/函数的动态参数/函数的注释/名称空间/函数的嵌套/global以及nolocal的用法 目录 Python函数02/函数的动态参数/函数的注释/名称空间/函数的嵌套/global ...

  9. Web APi之捕获请求原始内容的实现方法以及接受POST请求多个参数多种解决方案(十四)

    前言 我们知道在Web APi中捕获原始请求的内容是肯定是很容易的,但是这句话并不是完全正确,前面我们是不是讨论过,在Web APi中,如果对于字符串发出非Get请求我们则会出错,为何?因为Web A ...

随机推荐

  1. 用vs2012的命令利用xsd文件生成对应的C#类,把xml的string类型映射到生成的类

    输入命令: xsd d:\TDDOWNLOAD\atom-author-link.xsd /c /language:C# /outputdir:d:\ 含义: 将d:\TDDOWNLOAD\atom- ...

  2. Java魔法类:sun.misc.Unsafe

    Unsafe类在jdk 源码的多个类中用到,这个类的提供了一些绕开JVM的更底层功能,基于它的实现可以提高效率.但是,它是一把双刃剑:正如它的名字所预示的那样,它是Unsafe的,它所分配的内存需要手 ...

  3. 用Delphi实现文件关联

      文件关联为我们带来很多的方便.Delphi自带有注册表对象TRegistry,可以通过它取得或改变注册表相关键值的内容. Function GetAssociatedExec(FileExt: S ...

  4. Microsoft Office 2010 requires 的 MSXML 版本 6.10.1129.0 be 已安装在您计算机的安装"的基于 Windows 7 的计算机上安装 Office 2010 时出现错误消息

    https://support.microsoft.com/zh-cn/kb/2290714

  5. centos配置中文显示和中文输入

    我现在使用虚拟机运行centos,但是安装完成后系统显示英文,而且无法进行中文输入,这使我感到很烦躁,虽然我对自己说,这样可以逼迫自己适应全英文的环境,但作为一个中国人还是难以忍受,所以记录一下解决办 ...

  6. Window.onLoad 和 DOMContentLoaded事件的先后顺序

    相信写js的,都知道window.onload吧,但是并不是每个人都知道DOMContentLoaded,其实即使你不知道,很有可能你也经常使用了这个东西. 一般情况下,DOMContentLoade ...

  7. 通过xshell 设置代理上网

    前言: 前段时间,选修了一门并行计算,老师给我们每个人分配了一个linux登录账号,通过这个账号,可能登录学校的一台linux . 一次偶然的机会,了解到可以通过xshell , ssh服务器给本地开 ...

  8. 基于AWS的自动化部署实践

    过年前,我给InfoQ写了篇文章详细介绍我们团队在过去4年基于AWS的自动化部署实践.文章包括了:为什么选择AWS.AWS上自动化部署的优势和挑战.我们的解决方案,以及和AWS DevOps方案(Op ...

  9. about云资源共享

      Nosql资源: http://www.aboutyun.com/thread-5655-1-1.html (1)redis安置(2)RedisAdminUI.zip(3)redis安装部署(4) ...

  10. Android签名用keytool和jarsigner制作apk文件

    生成证书 keytool -genkey -alias aeo_android.keystore -keyalg RSA -validity -keystore aeo_android.keystor ...