Receive Windows Messages In Your Custom Delphi Class - NonWindowed Control - AllocateHWnd
Even "without your knowledge" Windows messages are being posted and handled by forms in your application.
For example, when the user closes the form in your application,
the WM_CLOSE message is sent to the window/form and the form gets closed (if you do not react programmatically).
For an application to receive a Window message, the application must provide a "window" a message will be sent to.
In normal situation this window is the (main) form in your application.
You write a procedure to handle a specific message, like WM_NCHitTest, and you are done.
BUT, what is you do NOT have a window to receive a message?
What if you want to handle messages in your custom class derived from TObject?
Handle Windows Messages in TMyObject = class(TObject)
A Delphi control that has a window handle (derives from TWinControl) can receive Windows messages.
The TObject does not expose a window handle, and therefore any of your custom classes (deriving from TObject)
cannot receive and handle Windows messages, at least not "by default".
To enable your custom class to receive Windows messages you must provide a window handle to the message sender.
The trick is in using the following methods (defined in classes.pas - therefore straightforward to use):
- AllocateHWnd(WndMethod : TWndMethod). AllocateHWnd is used to create a window that is not associated with a windowed control.
- The WndMethod : TWndMethod specifies the window procedure that the generated window uses to respond to messages.
- DeallocateHWnd. DeallocateHWnd destroys window that was created using the AllocateHWnd function.
// The TMsgReceiver skeleton below is a custom class derived from TObject capable of receiving and handling Windows messages. interface TMsgReceiver = class(TObject)
private
fMsgHandlerHWND : HWND;
procedure WndMethod( var Msg: TMessage);
public
constructor Create;
destructor Destroy; override;
end; implementation constructor TMsgReceiver.Create;
begin
inherited Create; fMsgHandlerHWND := AllocateHWnd(WndMethod);
end; destructor TMsgReceiver.Destroy;
begin
DeallocateHWnd(fMsgHandlerHWND);
inherited;
end; procedure TMsgReceiver.WndMethod(var Msg: TMessage);
begin
if Msg.Msg = WM_MY_UNIQUE_MESSAGE then
begin
//do something
end
else
Msg.Result := DefWindowProc(fMsgHandlerHWND, Msg.Msg, Msg.wParam, Msg.lParam);
end;
In the WndMethod procedure (the window procedure for the hidden window) you handle all the messages you are interested in.
For all other mesages a call to DefWindowProc is needed to ensure default processing for any messages that your code does not process.
Handle a Message From Another Application
With the above skeleton, you can now handle messages sent from other applications.
Suppose some application registers Windows message using RegisterWindowMessage API call.
The RegisterWindowMessage function is typically used to register messages for communicating between two cooperating applications.
The "sending" application would have a line like:
WM_MY_APP_MESSAGE := RegisterWindowMessage('MSG_MY_APP_MESSAGE');
Where WM_MY_APP_MESSAGE is a cardinal value field used when posting the message to (all) windows.
Let's say we post this message in a form's OnMouseDown event:
procedure TClickSendForm.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
PostMessage(HWND_BROADCAST, WM_MY_APP_MESSAGE, x, y);
end;
The HWND_BROADCAST parameter ensures that our WM_MY_APP_MESSAGE is posted to all top-level windows in the system,
including disabled or invisible unowned windows, overlapped windows, and pop-up windows AND our TMsgReceiver hidden window.
To handle the message in the TMsgReceiver instance have the WndMethod as:
procedure TMsgReceiver.WndMethod( var Msg: TMessage);
begin
if Msg.Msg = WM_MY_UNIQUE_MESSAGE then
begin
Point.X := Msg.LParam;
Point.Y := Msg.WParam;
// just to have some "output"
Windows.Beep(Point.X, Point.Y);
end
else
Msg.Result := DefWindowProc(fMsgHandlerHWND, Msg.Msg, Msg.wParam, Msg.lParam);
end;
The "Point" is a field in the TMsgReceiver.
And there you have it - TMsgReceiver receiving where the user has clicked on the form in some other application.
The WM_MY_UNIQUE_MESSAGE also needs to be registered in TMsgReceiver.
Download full source code to explore.
Receive Windows Messages In Your Custom Delphi Class - NonWindowed Control - AllocateHWnd的更多相关文章
- 启动windows的服务--《用delphi开发共享软件》-15.2桌面提示器
在dos 下用命令启动一个服务:NET START "Windows Desktop Reminder" 一下为用delphi启动服务: Function RunProcess(s ...
- (5)LoraWAN:Join procedure、Receive Windows
网络在建立之初,终端设备启动后需要向服务端发起Jion请求(接入请求),只有在接入请求得到成功答复,并根据答复配置相关参数后,终端才算成功加入网络.Jion成功后才能进行数据的上行.下行通信. Jio ...
- Sending messages to non-windowed applications -- AllocateHWnd, DeallocateHWnd
http://delphi.about.com/od/windowsshellapi/l/aa093003a.htm Page 1: How Delphi dispatches messages in ...
- Custom Roles Based Access Control (RBAC) in ASP.NET MVC Applications - Part 1 (Framework Introduction)
https://www.codeproject.com/Articles/875547/Custom-Roles-Based-Access-Control-RBAC-in-ASP-NET Introd ...
- Windows API 的数据类型与 Delphi 数据类型对照表
Windows 数据类型 Delphi 数据类型 描述 LPSTR PAnsiChar 字符串指针 LPCSTR PAnsiChar 字符串指针 DWORD LongWord 整数 BOOL Long ...
- Windows Azure Virtual Network (10) 使用Azure Access Control List(ACL)设置客户端访问权限
<Windows Azure Platform 系列文章目录> 本文介绍的是国内由世纪互联运维的China Azure. 我们在创建完Windows Azure Virtual Machi ...
- 获取windows进程信息及CListCtrl控件(List Control)练习
环境:VS2010/MFC/对话框 效果图: 目录: 1. 关于windows进程信息获取 2. CListCtrl的使用 ------------------------------------ ...
- 针对Windows 64位系统中Matlab没有LED Control Activex控件的解决方法
Win 10 64bits系统中Matlab 64位软件没有LED Control Activex控件,LED ActiveX Control控件位于Gauges Blockset模块中,而Gauge ...
- [Angular2 Form] Create custom form component using Control Value Accessor
//switch-control component import { Component } from '@angular/core'; import { ControlValueAccessor, ...
随机推荐
- Android应用性能优化之使用SQLiteStatement优化SQLite操作
平常在做Android数据库操作时,都是用的execSQL之个方法. 今天偶然发现了SQLiteStatement这个类.让我想起了在做Java Web开发写JDBC的代码时Prestatement这 ...
- Asp.net 访问数据库的几种方式
ASP.NET中连接数据库的各种方法 连接SQL数据库的方法:(一).在Web.Config中创建连接字符串:1.<add name="ConnectionString" c ...
- nsDATA 转结构体
很多时候需要将c,c++形式的struct转换为 NSData来处理.但是怎么转换呢? 假设有这么一个结构体: struct MYINFO { int a; long b; char c ...
- 分段统计与Oracle的分析函数、逻辑判断等知识点的综合运用
重点部分:TOTAL层 项目要求: 统计每个巡检员(USER_ID)当前月的签到率及查询相关字段 签到率公式:以巡检员为单位, (当月至今天为止签到的所有点/该月巡检点的总个数)=(b.Point/a ...
- Spring框架入门:(非原著,转载)
1.1. 耦合性和控制反转: 对象之间的耦合性就是对象之间的依赖性.对象之间的耦合越高,维护成本越高.因此,对象的设计应使类和构件之间的耦合最小. 例: public interface I ...
- 求职基础复习之冒泡排序c++版
代码中在第一层循环中增加一个bool值,是为了防止在排序完成后还继续无谓的比较,最多会有(n-1)*(n-2)/2次循环. #include<iostream> using namespa ...
- 该不该将变量设为 null ?
该不该将变量设为 null ? 对于引用类型的变量,在什么时候需要将其显式设为 null ,在什么时候不需要呢? 局部变量 对于局部变量,在方法结束的时候,变量就会失效,变量指向的对象引用也会减少一个 ...
- effective c++:资源管理
对象管理资源 createInvestment 函数作用时创建一个invest对象: void f() { Investment *pInv = createInvestment(); // call ...
- Linux下的GitHub安装与简单配置教程
1.GitHub简介 Git是一个分布式版本控制系统,与其相对的是CVS.SVN等集中式的版本控制系统. 2.Git的安装 1)安装Git a.查看与使用 在ubuntu下可以使用如下命令进行查看系统 ...
- PHP强大的内置filter (二) 完
<?php #Sanitize filters #Sanitize filters 可以清理掉不规范的字符 # FILTER_SANITIZE_EMAIL 可以清理除了 字母和数字 以及 !#$ ...