让一个非窗口组件(non-windowed component)可以接受来自Windows的消息

为什么要这样做?

有时候我们需要一个非窗口组件(比如一个非继承自TWinContrl的组件)可以接受Windows消息。要接受消息就需要一个窗口句柄,但是非窗口组件却没有句柄。这篇文章将讲述怎么让一个没有句柄的组件如何通过一个隐藏的窗口接受消息

这是怎么做到的?

例如
我的剪贴板查看组件就是一个不可视的组件。这个窗体可以接收提供信息关于更改剪贴板的消息。


Delphi库里面的AllocateHWnd函数可以帮助我们创建一个隐藏的窗口,同时与之相关的DeallocateHWnd函数可以释放当我们使用完的隐藏窗口。

这个隐藏的窗口将命令窗口过程。

通常当Windows调用一个stdcall函数时,AllocateHWnd函数能让我们像窗体过程一样的使用方法。

我们通过一个引用allocatehwnd函数所需的方法来并将它注册为一个窗口过程的方法来解决问题。

在这个被注册的方法内部我们可以处理我们感兴趣的消息同时传递给Windows


下面的代码清单2停工了一个如何使用AllocateHWnd函数的框架。尽管如此,我们的代码清单1定义一个组件类的轮廓:

------------------代码清单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------------------



同时下面将是实现部分的详细代码:


------------------代码清单2------------------
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

转载于:https://www.cnblogs.com/yzryc/p/6397393.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356160.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进阶– Java EE 7前端5强

系列继续。 在初步概述和Arjan关于最重要的后端功能的文章之后 ,我现在非常高兴让Ed Burns( edburns )使用他最喜欢的Java EE 7前端功能完成本系列。 感谢Markus Eisele让我有机会在他非常受欢迎的博客上发表帖子。 我和Markus的关系可以追溯…

一杯水怎么测试_一杯水就能鉴别翡翠真假的高招

大家好,小生有礼!鄙人是秋玉蝉珠宝的杨杨,很高兴能在茫茫互联网中相识就是有缘。先简单介绍一下秋玉蝉珠宝,我们是年轻的品牌,我们的理念一直秉承坚持做真翡翠,好翡翠,把握翡翠的精髓&#xff0…

214

python 进程:process 线程:thread转载于:https://www.cnblogs.com/jtlin/p/6397533.html

SpringBoot:与MyBatis合作

MyBatis是一个SQL映射框架,支持自定义SQL,存储过程和高级映射。 SpringBoot不为MyBatis集成提供官方支持,但MyBatis社区为MyBatis构建了SpringBoot入门程序。 您可以在http://blog.mybatis.org/2015/11/mybatis-spring-boot-released.html上…

wordpress房产信息网_Realia v3.1.2 wordpress房地产模板 租房网站模板

Product DescriptionRealia租赁门户模板。创造你自己的简单的方法房地产门户。教具支持dsidxpress WordPress插件和新的WP主题定制的API,它允许你做出实时的设计变化!你也可以选择20种颜色的变化,10的背景图案,3头的设置和盒装或全…

r语言dataellipse_r – 在ggplot2中微调stat_ellipse()

我想创建一个具有95%“精确”置信椭圆的二元正态分布的散点图.library(mvtnorm)library(ggplot2)set.seed(1)n c95 rho Sigma 我从双变量法线生成了1000个观测值,平均值为零,方差西格玛x z for(i in 1:n){z[i] p95[i] }我们可以使用stat_ellipse轻松地在生成数据的散…

openjpa_以编程方式向OpenJPA注册实体类型

openjpa我刚刚开始为Isis开发 OpenJPA对象库 。 在一般情况下,可以在persistence.xml文件中注册实体类型。 但是,Isis是一个框架,可以构建自己的元模型,并且可以自行确定哪些类构成实体。 因此,我不想强​​迫开发人员…

记录踩过的坑——代理IP

网络错误,查看是否有代理IP。转载于:https://www.cnblogs.com/dayang12525/p/6402068.html

php连接mysql_PHP连接MySQL数据库的三种方式

本篇文章给大家介绍一下PHP连接MySQL数据库的三种方式(mysql、mysqli、pdo),结合实例形式分析了PHP基于mysql、mysqli、pdo三种方式连接MySQL数据库的相关操作技巧与注意事项。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助…

使用Vert.x进行响应式开发

最近,似乎我们正在听到有关Java的最新和最好的框架的消息。 忍者 , SparkJava和Play等工具; 但是每个人都固执己见,使您感到您需要重新设计整个应用程序以利用它们的出色功能。 这就是为什么当我发现Vert.x时令我感到宽慰的原因。 Vert.x不是…

使用xtrabackup(innobackupex)实现MySQL的热备

mysql 的热备http://www.178linux.com/10139http://www.linuxidc.com/Linux/2014-04/99671.htmhttp://634871.blog.51cto.com/624871/1351049http://www.cnblogs.com/galengao/p/5755835.htmlhttp://heylinux.com/archives/3777.html 遇到问题,解决链接 http://blog…

mysql查看执行计划_MySql中如何使用 explain 查询 SQL 的执行计划

explain命令是查看查询优化器如何决定执行查询的主要方法。这个功能有局限性,并不总会说出真相,但它的输出是可以获取的最好信息,值得花时间去了解,因为可以学习到查询是如何执行的。1、什么是MySQL执行计划要对执行计划有个比较好…

vim的tab键设定

多在windows上编程的童鞋可能习惯于感受tab键为4个空格的长度,不过在linux系统中一般默认设定tab键为8个空格长度来显示。事实上tab也确实是8个空格的长度。不过由于习惯问题,某些童鞋还是希望在linux上也感受tab键为4个空格长度的显示,因为v…

依赖注入

依赖注入指的就是类A依赖于类B,通过外部注入的方式来实现,而不是通过自身去实现。 这样做的好处就是可以使得代码之间更加的解耦。 举个例子,船(ship)包含有船桨(oar),以下为高耦合的…

idea内置junit5_JUnit的内置Hamcrest Core Matcher支持

idea内置junit5在通过JUnit和Hamcrest改善对assertEquals的文章中,我简要讨论了Hamcrest “ 核心 ”匹配器与JUnit的现代版本“结合”在一起的情况。 在那篇文章中,我特别关注了JUnit的assertThat(T,Matcher)静态方法与…

jenkins 发送邮件模板

jenkins 发送邮件模板 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>${ENV, var"JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title> </head><body leftmargin"8" marginwidth"…

centos lnmp源码安装mysql_CentOS 6.6 下源码编译安装MySQL 5.7.5

说明&#xff1a;CentOS 6.6 下源码编译安装MySQL 5.7.51. 安装相关工具# yum -y install gcc-c ncurses-devel cmake make perl \gcc autoconf automake zlib libxml libgcrypt libtool bison2. 清理环境检查boost版本&#xff1a;# rpm -qa boost*卸载boost-*等库&#xff1a…

Oracle Spring Clean JavaFX应该吗?

我们确实在Codename One上依赖JavaFX&#xff0c;我们的模拟器需要它。 我们的桌面版本使用它&#xff0c;而我们的设计器工具基于Swing。 我们希望它成功&#xff0c;这对我们的业务至关重要&#xff01; 即使您是Java EE开发人员并且不关心桌面编程&#xff0c;我们也不是一个…

laravel mysql 锁表_Laravel中MySQL的乐观锁与悲观锁

MySQL/InnoDB的加锁&#xff0c;是一个老生常谈的话题。在数据库高并发请求下&#xff0c;如何兼顾数据完整性与用户体验的敏捷性是一代又一代程序员一直在思考的问题。乐观锁乐观锁之所以叫乐观&#xff0c;是因为这个模式不会对数据加锁。而是对数据操作保持一种乐观的心态&a…

python初心记录二

切片 L [1,2,3,4,5,6,7,8,9,0] L[0:3] L[-3] 迭代 如果给定一个list或tuple&#xff0c;我们可以通过for循环来遍历这个list或tuple&#xff0c;这种遍历我们称为迭代&#xff08;Iteration&#xff09;。 因为dict的存储不是按照list的方式顺序排列&#xff0c;所以&#xff0…