How a non-windowed component can receive messages from Windows -- AllocateHWnd

http://www.delphidabbler.com/articles?article=1

Why do it?

Sometimes we need a non-windowed component (i.e. one that isn‘t derived fromTWinControl) to receive Windows messages.

To receive messages the component needs a window handle, but a non-windowed component hasn‘t got one!

This article is about how to enable such a component to use a hidden window to receive messages.

How it‘s done

The Delphi library function AllocateHWnd is used to create a hidden window for us

and the related DeallocateHWnd disposes of the window when we‘ve finished with it.

The hidden window requires window procedure.

AllocateHWnd enables us to use a method as a window procedure where Windows normally requires a stdcall function.

We pass a reference to the required method to AllocateHWnd and

it takes care of the problem of registering the method as a window procedure for us.

Inside the registered method we handle the messages we are interested in

and hand the rest off to Windows using the DefWindowProc API call.

Listing 2 below provides a skeleton of how to use AllocateHWnd.

First though, Listing 1shows an outline definition for our component class:

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 to handle
        messages passed to our hidden window }
    ...
  public
     constructor Create(AOwner: TComponent); override;
       { create hidden window here: store handle in fHWnd}
     destructor Destroy; override;
       { free hidden window here }
     ...
  end;

And here are the implementation details:

constructor TMyClass.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ...
  // Create hidden window using WndMethod as window proc
  fHWnd := AllocateHWnd(WndMethod);
  ...
end;

destructor TMyClass.Destroy;
begin
  ...
  // Destroy hidden window
  DeallocateHWnd(fHWnd);
  ...
  inherited Destroy;
end;

procedure TMyClass.WndMethod(var Msg : TMessage);
var
  Handled: Boolean;
begin
  // Assume we handle message
  Handled := True;
  case Msg.Msg of
    WM_SOMETHING: DoSomething;
      // Code to handle a message
    WM_SOMETHINGELSE: DoSomethingElse;
      // Code to handle another message
    // Handle other messages here
    else
      // We didn‘t handle message
      Handled := False;
  end;
  if Handled then
    // We handled message - record in message result
    Msg.Result := 0
  else
    // We didn‘t handle message
    // pass to DefWindowProc and record result
    Msg.Result := DefWindowProc(fHWnd, Msg.Msg,
      Msg.WParam, Msg.LParam);
end;

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.

时间: 2024-10-06 20:11:34

How a non-windowed component can receive messages from Windows -- AllocateHWnd的相关文章

How a non-windowed component can receive messages from Windows

Why do it? Sometimes we need a non-windowed component (i.e. one that isn't derived fromTWinControl) to receive Windows messages. To receive messages the component needs a window handle, but a non-windowed component hasn't got one! This article is abo

Java EE 7 教程 第一部分 简介 第1章 概述 第1.7节 Java EE 7 APIs

原文:http://docs.oracle.com/javaee/7/tutorial/doc/overview007.htm 翻译:石卓林 [email protected] 注意:此章是1.8章前移而来,不知为何oracle删除了原1.7开发角色章节 1.7 Java EE 7 APIs Figure 1-6 shows the relationships among the Java EE containers. Figure 1-6 Java EE Containers Descript

WebWorker SharedWorker ServiceWorker

http://www.ibm.com/developerworks/cn/web/1112_sunch_webworker/ Worker Debug页 chrome://inspect/#workers HTML5中 Web Worker Web Worker 的三大主要特征:能够长时间运行(响应),理想的启动性能以及理想的内存消耗. 它允许在 Web 程序中并发执行多个 JavaScript 脚本,每个脚本执行流都称为一个线程,彼此间互相独立,并且有浏览器中的 JavaScript 引擎负责

Overview of iOS Crash Reporting Tools: Part 1/2

Believe it or not, developers are not perfect, and every once in a while you might have a (gasp!) bug in your app. You will try your best to ship your apps with no bugs in them, but more often than not you realise afterwards that a bug has slipped th

解决RecyclerView无法onItemClick问题

对于RecyclerView的使用,大家可以查看将替代ListView的RecyclerView 的使用(一),单单从代码结构来说RecyclerView确实比ListView优化了很多,也简化了我们编写代码量,但是有一个问题会导致开发者不会去用它,更比说替换ListView了,我不知道使用过RecyclerView的人有没有进一步查看,RecyclerView没有提供Item的点击事件,我们使用列表不仅仅为了显示数据,同时也可以能会交互,所以RecyclerView这个问题导致基本没有人用它,

使用VMware桥接模式组建局域网测试MSMQ(二)

上一篇讲了搭建VMware虚拟机实现与宿主机相互通信,环境已经就绪,现在就可以做MSMQ的分布式开发了. 本篇准备分四点介绍MSMQ: 1.MSMQ简介 2.MSMQ的安装 3.MSMQ编程开发 4.Demo下载 一.MSMQ简介 MSMQ本质上是一种消息传递协议,它允许在单独的服务端/客户端运行的应用程序间已可靠的方式通信.队列用来临时存储消息,服务器端向队列发送消息,客户端从队列读取消息.这就使得即使服务器端和客户端不在同一网络中,不能直接访问彼此,也能通过队列进行通信.相比之下,socke

【转载】ATL问题集

原文:http://blog.csdn.net/fengrx/article/details/4171629 这些问题是以前在csdn当版主是一些朋友整理的,今天找到了,贴到这里来! #1 如何使用控件不能改变大小? 答:有时我们需要创建不可改变大小的控件,像那种在运行时没有界面的控件(例:时间控件,SysInfo 等),想做到这种功能的话,请把以下代码加入到控件类的构造函数: m_bAutoSize = TRUE; SIZEL size = {24, 24}; AtlPixelToHiMetr

Java Secure Socket Extension (JSSE) Reference Guide

Skip to Content Oracle Technology Network Software Downloads Documentation Search Java Secure Socket Extension (JSSE) Reference Guide This guide covers the following topics: Skip Navigation Links Introduction Features and Benefits JSSE Standard API S

MiniFilter文件系统学习

Minfilter与legacy filter区别 比sfilter加载顺序更易控制. altitude被绑定到合适的位置. Minfilter在注册表服务项中有一项Altitude值 此值越高位置越靠前 (待考证 每一个minifilter驱动必须有一个叫做altitude的唯一标识符.一个minifilter驱动的altitude定义了它加载时在I/O栈中相对其他minifilter驱动的位置.值越小,栈中位置就越低 FSFilter Anti-Virus 320000-329999 此组包