让一个非窗口组件(non-windowed component)可以接受来自Windows的消息
为什么要这样做?
有时候我们需要一个非窗口组件(比如一个非继承自TWinContrl的组件)可以接受Windows消息。要接受消息就需要一个窗口句柄,但是非窗口组件却没有句柄。这篇文章将讲述怎么让一个没有句柄的组件如何通过一个隐藏的窗口接受消息
这是怎么做到的?
例如
我的剪贴板查看组件就是一个不可视的组件。这个窗体可以接收提供信息关于更改剪贴板的消息。
Delphi库里面的AllocateHWnd函数可以帮助我们创建一个隐藏的窗口,同时与之相关的DeallocateHWnd函数可以释放当我们使用完的隐藏窗口。
这个隐藏的窗口将命令窗口过程。
通常当Windows调用一个stdcall函数时,AllocateHWnd函数能让我们像窗体过程一样的使用方法。
我们通过一个引用allocatehwnd函数所需的方法来并将它注册为一个窗口过程的方法来解决问题。
在这个被注册的方法内部我们可以处理我们感兴趣的消息同时传递给Windows
下面的代码清单2停工了一个如何使用AllocateHWnd函数的框架。尽管如此,我们的代码清单1定义一个组件类的轮廓:
type
{*******************************
Our class derived from TComponent
or another ancestor class
********************************}
TMyClass = class(TComponent)
private
fHWnd: HWND;
{*******************************
field to store the window handle
存储窗口句柄的字段
********************************}
...
protected
procedure WndMethod(var Msg: TMessage); virtual;
{*******************************
window proc - called by Windows 窗口过程(window proc) 由windows系统调用
to handle messages passed to our
hidden window 该窗口过程是用来处理传递到我们的隐藏窗口的
...
public
constructor Create(AOwner: TComponent); override;
{*******************************
create hidden window here:
store handle in fHWnd
在这里创建隐藏窗体,并且把它的句柄存储在fHWnd字段。
********************************}
destructor Destroy; override;
{*******************************
free hidden window here
销毁隐藏窗口过程
********************************}
...
end;
------------------代码清单1------------------
同时下面将是实现部分的详细代码:
constructor TMyClass.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
...
//创建一个隐藏窗体并且用WndMethod过程
fHWnd := AllocateHWnd(WndMethod);
...
end;
destructor TMyClass.Destroy;
begin
...
//销毁隐藏窗口
DeallocateHWnd(fHWnd);
...
inherited Destroy;
end;
procedure TMyClass.WndMethod(var Msg : TMessage);
var
Handled: Boolean;
begin
//假定我们可以处理消息
Handled := True;
case Msg.Msg of
WM_SOMETHING: DoSomething;
//处理消息的代码
WM_SOMETHINGELSE: DoSomethingElse;
//处理另一个消息的代码
//这里处理其他的消息
else
//我们不再处理消息
Handled := False;
end;
if Handled then
//我们在消息记录里处理消息
Msg.Result := 0
else
//我们通过DefWindowProc函数
//不处理的消息同时记录结果
Msg.Result := DefWindowProc(fHWnd,
Msg.Msg,
Msg.WParam,
Msg.LParam);
end;
------------------代码清单2------------------
原文:Of course, we could just use the Windows API to create a window the hard way and provide a windows procedure.
But it is more difficult to use a method as a window procedure if we do it this way.
The clever features about AllocateHWnd are that (a) it creates the hidden window for us and (b) it allows us to use a method, rather than a simple procedure,
as the window procedure – and a method is more useful since it has access to the class's private data.
译文:当然,我们仅使用 Windows API提供的比较难的方式创建了一个window(窗口)并提供窗口过程。
但是,如果我们采用这种方式,那么把一个方法作为窗口过程来使用的话将是困难的。
关于AllocateHWnd灵活的特性有:
(a)它创建一个隐藏窗口给我们使用
(b)它允许我们使用一个方法,而不是一个简单的过程(procedure),作为该窗口过程——当使用这个方法来访问该类的私有数据的时候更加有用。
后记:第一次翻译文章,可能有些地方理解的不是很透彻,所以附录原文地址如下.
原文:http://www.delphidabbler.com/articles?article=1
让一个非窗口组件(non-windowed component)可以接受来自Windows的消息的更多相关文章
- 怎么让一个非窗口组件可以接受来自Windows的消息
为什么要这样做? 有时候我们需要一个非窗口组件(比如一个非继承自TWinContrl的组件)可以接受Windows消息.要接受消息就需要一个窗口句柄,但是非窗口组件却没有句柄.这篇文章将讲述怎么让一个 ...
- Java-Spring MVC如何返回一个非JSP文件名字的地址
return new ModelAndView("redirect:/bizitem/goEditItem.do?item_id="+item_id+"&msg= ...
- 4年前端、2年CTO:一个非科班程序员的真实奋斗史
1.引言 我,Scott,一家创业公司的 CTO. 从业6年却很少写文章,近一年来接触了几十个刚毕业的前端新人,也面试了100多个前端工程师和Nodejs工程师,对于前端发展的这个职业算是有些感触 ...
- [物理学与PDEs]第3章习题1 只有一个非零分量的磁场
设磁场 ${\bf H}$ 只有一个非零分量, 试证明 $$\bex ({\bf H}\cdot\n){\bf H}={\bf 0}. \eex$$ 证明: 不妨设 ${\bf H}=(0,0,H_3 ...
- Quartz的集群模式和单机模式共存-让一个非集群的Quartz与集群节点并行着运行
假如你让一个非集群的 Quartz 应用与集群节点并行着运行,设法使用 JobInitializationPlugin和 RAMJobStore Quartz支持可选节点执行jobquartz集群,会 ...
- 最后一个非零数字(POJ 1604、POJ 1150、POJ 3406)
POJ中有些问题给出了一个长数字序列(即序列中的数字非常多),这个长数字序列的生成有一定的规律,要求求出这个长数字序列中某个位上的数字是多少.这种问题通过分析,找出规律就容易解决. 例如,N!是一个非 ...
- coalesce函数-返回参数中第一个非null值
coalesce函数-返回参数中第一个非null值 学习了:http://www.cnblogs.com/zc_0101/archive/2009/08/11/1543650.html 这个要复杂一些 ...
- Python算法每日一题--001--给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 示例 1: 输入: [ ...
- 一个非侵入的Go事务管理库——如何使用
在文章"清晰架构(Clean Architecture)的Go微服务: 事物管理"中,我谈到了如何在清晰架构中实现非侵入的事务管理. 它允许你把事务代码与业务逻辑代码分开,并且让你 ...
随机推荐
- 怎么查看SAS到期时间
通过以下命令,可以查看SAS到期时间: proc setinit; run;
- CRM4.0 上传附件大小限制
问题背景: 上传附件大小默认为 5M 可以通过以下设置修改其大小 : "设置"--〉“管理”--〉“系统设置”--〉“电子邮件”--〉“设置附件文件的大小限制”
- Unity打包Android平台AssetBundle脚本
注意,BuildTarget tagetPlatform参数为BuildTarget.Android using UnityEngine; using UnityEditor; public clas ...
- wordpress写文章添加gif图片变成静态图片的解决办法
添加文章时gif只能静态,记得在添加时选择完整尺寸,不要压缩即可
- 零基础学习python_字典(25-26课)
今天学到后面的知识,突然发现之前学习到的字典列表啥的都有点忘了,打算补一下之前学到的字典,到时候你看的时候,字符串.列表.字典.元祖这几个没啥顺序,刚开始学的时候了解下方法,当然你可以死记硬背下,后面 ...
- vim more
启用鼠标 :set mouse=a 跳转到下一函数 下一个函数开头 ]] 当前函数末尾/下一个函数的末尾 ][ 当前函数开头/上一个函数的开头 [[ 选项可以按任何顺序生效,可以放在文件名前或后边 ...
- git回滚到某个版本操作
git回滚到某个版本操作: 1.git log //查看指过去的版本 2. git reset --hard 复制上面commit后的字符串到此处 如果只想 回滚单机的,那么到上面就结束,如果 ...
- Java编辑PDF写入文字 插入图片
package com.test; import com.itextpdf.text.BaseColor; import com.itextpdf.text.Font; import com.itex ...
- Weblogic环境(JSP)文件下载问题(下载的文件与原文件大小不一致问题)
最近发现一个问题有个download.jsp文件下载jsp在Tomcat下正常,在Weblogic下不太正常! Weblogic下载的文件比原文件大两个字节,查看文件像是文件内容最后多了空行 检查do ...
- Linux将某目录授权给某组里的某用户
chown -Rf 用户名:组名 目录