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 :=
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.

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

  1. 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) ...

  2. [React Intl] Use a react-intl Higher Order Component to format messages

    In some cases, you might need to pass a string from your intl messages.js file as a prop to a compon ...

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

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

  4. WebWorker SharedWorker ServiceWorker

    WebWorker 是什么? 为 JavaScript 引入线程技术 不必再用 setTimeout().setInterval().XMLHttpRequest 来模拟并行 Worker 利用类似线 ...

  5. Receive Windows Messages In Your Custom Delphi Class - NonWindowed Control - AllocateHWnd

    http://delphi.about.com/od/windowsshellapi/a/receive-windows-messages-in-custom-delphi-class-nonwind ...

  6. SSIS Component的ValidateExternalMetadata属性

    ValidateExternalMetadata Property Indicates whether the component validates its column metadata agai ...

  7. How PhoneGap & Titanium Works

    转载自 http://www.appcelerator.com/blog/2012/05/comparing-titanium-and-phonegap/ How PhoneGap Works As ...

  8. Microsoft Win32 to Microsoft .NET Framework API Map

    Microsoft Win32 to Microsoft .NET Framework API Map .NET Development (General) Technical Articles   ...

  9. .net Framework Class Library(FCL)

    from:http://msdn.microsoft.com/en-us/library/ms229335.aspx 我们平时在VS.net里引用的那些类库就是从这里来的 The .NET Frame ...

随机推荐

  1. 关于Xcode的项目文件夹

    当我们在打开的项目中,对某个文件夹 Show in Finder的时候,发现对代码的分类文件夹没有全在一堆,在项目中明明对代码分了类,为什么在Finder中没有文件夹?? 这是因为,Xcode项目中的 ...

  2. android部分手机onclick事件触发2次

    var t1 = null; function btnSave() { if (t1 == null) { t1 = new Date().getTime(); } else { var t2 = n ...

  3. pcap文件的文件头的link type

    http://www.tcpdump.org/linktypes.html Link-layer header type values LINKTYPE_ name LINKTYPE_ value C ...

  4. [Papers]NSE, $u$, Lorentz space [Sohr, JEE, 2001]

    $$\bex \bbu\in L^{p,r}(0,T;L^{q,\infty}(\bbR^3)),\quad\frac{2}{p}+\frac{3}{q}=1,\quad 3<q<\inf ...

  5. EhCache 分布式缓存/缓存集群

    开发环境: System:Windows JavaEE Server:tomcat5.0.2.8.tomcat6 JavaSDK: jdk6+ IDE:eclipse.MyEclipse 6.6 开发 ...

  6. ANT 发布项目中 build.xml 文件的详细配置

    xml 代码 <?xml version="1.0" encoding="UTF-8"?> <!-- name:对应工程名字 default: ...

  7. 被投资人“送”入看守所 z

    http://news.cnblogs.com/n/506969/ 拜读了[[畅言]读<被投资人“送”入看守所>一文有感]一文有感,很想跟作者探讨几句.虽然他的看法很有理性,但站在一个刑案 ...

  8. bundle install rake-10.4.2

    这个是由于被墙了的原因,提供一个不用FQ解决的方法 淘宝做了一个gem镜像,地址是http://ruby.taobao.org/  为什么有这个? 由于国内网络原因(你懂的),导致 rubygems. ...

  9. 《Java数据结构与算法》笔记-CH4-6栈结构实现中缀转后缀

    /** * 中缀表达式转换成后缀表达式: 从输入(中缀表达式)中读取的字符,规则: 操作数: 写至输出 左括号: 推其入栈 右括号: 栈非空时重复以下步骤--> * 若项不为(,则写至输出: 若 ...

  10. MoveTo和MoveBy

    cc.MoveTo是“移动到这里",而cc.MoveBy则是“相对于之前点再移动”,通俗一点就是说这里需要两个坐标pos1(x1,y1),pos2(x2,y2). 如果是cc.MoveTo的 ...