让AllocateHwnd接受一般函数地址作参数
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接受一般函数地址作参数的更多相关文章
- 让AllocateHwnd接受一般函数地址作参数(105篇博客)
http://www.xuebuyuan.com/1889769.html Classes单元的AllocateHWnd函数是需要传入一个处理消息的类的方法的作为参数的,原型: function Al ...
- php函数按地址传递参数(php引用)
php函数按地址传递参数(php引用) 一.总结 1.php引用:php引用和c++一样,都是在变量前加&(取地址符号) 2.php函数按地址传递参数:php函数按地址传递参数(php引用)也 ...
- python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False。
python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False. 重难点:定义函数的方法.使用str类型的find()函数,可以 ...
- vlc 详细使用方法:libvlc_media_add_option 函数中的参数设置
vlc 详细使用方法:libvlc_media_add_option 函数中的参数设置 [转载自]tinyle的专栏 [原文链接地址]http://blog.csdn.net/myaccella/ar ...
- nodeJS接受post传过来的参数
1.nodeJs接受Post传递的参数需要通过绑定两个事件来获取, querystring = require("querystring"); 1 app.post('/comm ...
- 百万年薪python之路 -- 函数的动态参数
1.函数的动态参数 1.1 动态接收位置参数 在参数位置用*表示接受任意参数 def eat(*args): print('我想吃',args) eat('蒸羊羔','蒸熊掌','蒸鹿尾儿','烧花鸭 ...
- python27期day10:函数的动态参数、函数的注释、函数的名称空间、函数的嵌套、global(修改全局的)、nonlocal(修改局部的)、函数名的第一类对象及使用、作业题。
1.动态参数的作用: 能够接收不固定长度参数 位置参数过多时可以使用动态参数 * args是程序员之间约定俗称(可以更换但是不建议更换) * args获取的是一个元组 ** kwargs获取的是一个字 ...
- Python函数02/函数的动态参数/函数的注释/名称空间/函数的嵌套/global以及nolocal的用法
Python函数02/函数的动态参数/函数的注释/名称空间/函数的嵌套/global以及nolocal的用法 目录 Python函数02/函数的动态参数/函数的注释/名称空间/函数的嵌套/global ...
- Web APi之捕获请求原始内容的实现方法以及接受POST请求多个参数多种解决方案(十四)
前言 我们知道在Web APi中捕获原始请求的内容是肯定是很容易的,但是这句话并不是完全正确,前面我们是不是讨论过,在Web APi中,如果对于字符串发出非Get请求我们则会出错,为何?因为Web A ...
随机推荐
- MongoDB Auto-Sharding(自动分片)入门介绍
MongoDB是10gen团队开发的一款面向文档的NoSQL数据库.最近一年多以来,MongoDB被越来越多的大型网站应用到生产环境中,比较著名的有Foursquare, bit.ly, Source ...
- JDBC数据源(DataSource)的简单实现
数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用. 数据源提供了一种简单获取数据库连接的方式,并能在内部通过一个池的机制来复用数据库连接,这样就大大减少创建数据 ...
- Safari on iOS 7 中Element.getClientRects的Bug
在Safari浏览器中,DOMElement和Range对象都提供了getBoundingClientRect方法和getClientRects方法.顾名思义,getBoundingClientRec ...
- Ajax轮询以及Comet模式—写在Servlet 3.0发布之前(转)
2008 年的夏天,偶然在网上闲逛的时候发现了 Comet 技术,人云亦云间,姑且认为它是由 Dojo 的 Alex Russell 在 2006 年提出.在阅读了大量的资料后,萌发出写篇 blog ...
- JS方式调用本地的可执行文件
看到一个方法,有些用,先存下来,有用的时候再用. 前几天,在IE,FIREFOX中实现了用JS方式调用本地的可执行文件.地址:www.yihaomen.com/article/js/211.htm , ...
- iOS学习笔记之回调(二)
写在前面 上一篇学习笔记中简单介绍了通过目标-动作对实现回调操作:创建两个对象timer和logger,将logger设置为timer的目标,timer定时调用logger的sayOuch函数.在这个 ...
- SQLite数据库和JPA简单介绍
SQLite数据库和JPA简单介绍 一.SQLite简单使用 SQLite是遵循ACID的关系数据库管理系统,它的处理速度很快,它的设计目标是嵌入式的,只需要几百K的内存就可以了. 1.下载SQLit ...
- 再来说说Activity
经过前面多天的了解,现在可以确信一点: activity提供了用户和程序交互的界面. 而且android里有四大组件:Activity,Service,BroadcastReceiver,Conten ...
- 【Android】创建、读取XML文件
创建: package webdomain; import java.io.File; import java.io.FileNotFoundException; import java.io.Fil ...
- Go语言相关图书推荐
Go语言编程 作 者 许式伟 等 著 出 版 社 人民邮电出版社 出版时间 2012-08-01 版 次 1 页 数 245 印刷时间 2012-08-01 开 ...