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

Example
My Clipboard Viewer Component is a non-visual component that uses the hidden window techniques described here. The window receives Windows messages that provide information about changes to the clipboard.

The Delphi library function AllocateHWnd is used to create a hidden window for us and the related DeallocateHWnddisposes 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 stdcallfunction. We pass a reference to the required method toAllocateHWnd 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;
Listing 1

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;
Listing 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.

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

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

  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. iText使用经历

    最近用iText搞了下PDF,虽然一路趟坑而过,毕竟是搞出来了,所以iText还是不错的开源PDF生成软件的.先看搞出来的PDF长啥样: 然后看一路趟过来的坑: 1.表格怎么生成,具体是行怎么生成?列 ...

  2. 获取post发送过来的xml包

     if (Request.HttpMethod.ToLower() == "post") { byte[] ar; ar = new byte[this.Request.Input ...

  3. 安装VS2012出问题后,反复重启电脑。

    安装VS2012在装 VC++相关部分时出了问题,自动重启了. 重启后安装仍重启. 系统设置里取消了“自动重启”, 出现0x000000F4,网上搜索下,说是和硬盘有关,电源线.数据线.或电源不稳. ...

  4. Servlet容器请求处理

    红色部分为本章所述模块 所讲述的请求流程模块,大家已经很清楚了.那怎么给大家去讲的更清晰,大家理解的更容易呢?当然是,带着问题去学习,吸收或许会更快些啦.:) 开篇之前,给大家提以下几个问题,这些问题 ...

  5. bzoj2026: [SHOI2009]Coin

    Description Constantine刚结束在MySky Island的度假,正准备离开的时候,他想送给她的好朋友YY一份特别的礼物——MySky Island上特别的手工艺品宝石纪念币.宝石 ...

  6. 垃圾收集器之:CMS收集器

    HotSpot JVM的并发标记清理收集器(CMS收集器)的主要目标就是:低应用停顿时间.该目标对于大多数交互式应用很重要,比如web应用.在我们看一下有关JVM的参数之前,让我们简要回顾CMS收集器 ...

  7. 杂项:Mantis

    ylbtech-杂项:Mantis 缺陷管理平台Mantis,也做MantisBT,全称Mantis Bug Tracker.Mantis是一个基于PHP技术的轻量级的开源缺陷跟踪系统,以Web操作的 ...

  8. Unreal Engine 4 性能优化工具(Profiler Tool)

    转自:http://aigo.iteye.com/blog/2296548 Profiler Tool Reference https://docs.unrealengine.com/latest/I ...

  9. javascript 节点操作拷贝节点cloneNode()

    cloneNode(a)方法接受一个布尔值参数,表示是否深拷贝 true:表示执行深拷贝,复制本节点以及整个子节点树. false:浅拷贝.只复制节点本身. 复制后返回的节点副本属于文档所有,但是并没 ...

  10. Ubuntu-14.04.1 desktop安装时遇到的小问题

    su root认证失败:sudo passwd root,然后设置新密码. 重装linux导致g++显示已安装,但无法使用:将"系统设置"/"软件源"中所有更新 ...