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. 【PHP入门到精通】:Ch03:PHP语言基础

    1, PHP风格 这里为了显示代码把"<"和">"和key值以空格分开了,实际书写时切记不要将其分开: (1) < ?php ? >: ...

  2. 小结JS中的OOP(下)

    关于JS中OOP的具体实现,许多大神级的JS专家都给出了自己的方案. 一:Douglas Crockford 1.1 Douglas Crockford实现的类继承 /** * 原文地址:http:/ ...

  3. SmartGit STUDY 2

    The Index The Index is an intermediate cache for preparing a commit. With SmartGit, you can make hea ...

  4. HDU5804 Price List (BestCoder Round #86 A)水题

    分析:大于总和输出1 #include <cstdio> #include <cstring> #include <algorithm> using namespa ...

  5. Maven安装testNG

    1.Maven安装testNG (1)打开网站:http://testng.org/doc/maven.html (2)复制如下代码,粘贴到项目的pom.xml文件: 1 <dependency ...

  6. [转]Linux文件权限详解

    转自:http://blog.chinaunix.net/uid-25052030-id-174343.html 在linux中的每一个文件或目录都包含有访问权限,这些访问权限决定了谁能访问和如何访问 ...

  7. Android各个版本代号及其特性

    - Android1.1 2008 年9月发布的Android第一版 - Android1.5 Cupcake (纸杯蛋糕) 2009年4月30日,官方1.5版本(Cupcake 纸杯蛋糕)的Andr ...

  8. Linux系统下查看已经登录用户并踢出的方法

    LINUX是个多用户系统,一旦连接到网络中,它可以同时为多个登录用户提供服务. 查看用户的操作 查看当前用户: [ROOT@LOCALHOST ROOT] # W                    ...

  9. PHP代码格式化批量脚本

    @echo off echo please input phpCB url: set /p input= cd /d "E:\tools\phpCB\" phpCB --space ...

  10. js运动 九宫格展开

    <!doctype html> <html> <head> <meta charset = "utf-8"> <title&g ...