让你的Delphi非窗口自定义控件接收Windows消息

本文介绍如何使从TObject继承的类能够接收并处理Windows消息,即使该类没有关联的窗口。通过使用AllocateHWnd和DeallocateHWnd方法,可以为这类对象创建和销毁隐藏窗口,从而实现接收特定消息的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:http://delphi.about.com/od/windowsshellapi/a/receive-windows-messages-in-custom-delphi-class-nonwindowed-control.htm


Windows消息用来在Windows系统与应用程序之间,或应用程序与应用程序之间进行交互通迅。例如:当用户关闭应用程序窗口时,WM_CLOSE消息就会发送到相应的窗口。

对于一个接收Windows消息的应用来说,必须提供一个窗口来接收消息。通常它会是应用程序的主窗口,你写一个过程处理特定消息,比如WM_NCHitTest,那么就可以处理该消息 。但是如果没有窗口来接收消息,你要一个从TObject继承的类来处理消息,又该怎么办呢?


在类TMyObject = class(TObject)中处理Windows消息


一个从TWinControl继承的Delphi控件是可以接收Windows消息的。TObject类并没有提供一个窗口句柄,因此,从TObject继承的类是没有办法处理Windows消息 的,至少默认情况下是这样的。为了接收Windows消息 ,你需要为你的自定义类提供一个窗口句柄来接收Windows消息。关键是使用classes.pas中定义的下面介绍的方法:

AllocateHWnd(WndMethod : TWndMethod).

AllocateHWnd用来创建一个不与窗口控件关联的窗口 

WndMethod : TWndMethod

用来指定生成的窗口响应消息的窗口过程。

DeallocateHWnd

DeallocateHWnd 用来销毁AllocateHWnd创建的窗口。


下面的TMsgReceiver是从TObject继承的类,并且能处理Windows消息。


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;

在WndMethod过程中(就是隐藏窗口的窗口过程)你可以处理你感兴趣的窗口消息。对于其它消息需要调用默认的消息处理过程DefWindowProc。


处理来自其它应用的消息

通过上面的代码,假设其它应用使用RegisterWindowMessage注册了Windows消息,你现在也能处理来自其它应用的消息。RegisterWindowMessage通常用来注册互相协作的应用程序间的消息.

发送消息的应用可能有如下代码:

WM_MY_APP_MESSAGE := RegisterWindowMessage('MSG_MY_APP_MESSAGE');

当消息发送到其它窗口时,WM_MY_APP_MESSAGE是一个无符号整数,假设我们在一个事件中发送该消息:

procedure TClickSendForm.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  PostMessage(HWND_BROADCAST, WM_MY_APP_MESSAGE, x, y);
end;

HWND_BROADCAST参数确保WM_MY_APP_MESSAGE消息被发送到所有的顶层窗口,包括禁用或不可见的窗口,层叠窗口,弹出窗口,当然也包括我们的TMsgReceiver隐藏窗口,为了处理该消息TMsgReceiver的WndMethod如下:

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;

"Point"是TMsgReceiver的一个字段. TMsgReceiver接收到其它的应用程序用户在窗口的哪里点击了鼠标。WM_MY_UNIQUE_MESSAGE也需要在TMsgReceiver中进行注册。


源代码下载:http://delphi.about.com/library/code/tmsgreceiver.zip

Creating Windows CreateMDIWindow CreateWindow CreateWindowEx RegisterClass RegisterClassEx UnregisterClass Message Processing BroadcastSystemMessage CallNextHookEx CallWindowProc DefFrameProc DefMDIChildProc DefWindowProc DispatchMessage GetMessage GetMessageExtraInfo GetMessagePos GetMessageTime GetQueueStatus InSendMessage PeekMessage PostMessage PostQuitMessage PostThreadMessage RegisterWindowMessage ReplyMessage SendMessage SendMessageCallback SendMessageTimeout SendNotifyMessage SetMessageExtraInfo SetWindowsHookEx TranslateMessage UnhookWindowsHookEx WaitMessage Window Information AnyPopup ChildWindowFromPoint ChildWindowFromPointEx EnableWindow EnumChildWindows EnumPropsEx EnumThreadWindows EnumWindows FindWindow FindWindowEx GetClassInfoEx GetClassLong GetClassName GetClientRect GetDesktopWindow GetFocus GetForegroundWindow GetNextWindow GetParent GetProp GetTopWindow GetWindow GetWindowLong GetWindowRect GetWindowText GetWindowTextLength IsChild IsIconic IsWindow IsWindowEnabled IsWindowUnicode IsWindowVisible IsZoomed RemoveProp SetActiveWindow SetClassLong SetFocus SetForegroundWindow SetParent SetProp SetWindowLong SetWindowText WindowFromPoint Processes and Threads CreateEvent CreateMutex CreateProcess CreateSemaphore CreateThread DeleteCriticalSection DuplicateHandle EnterCriticalSection ExitProcess ExitThread GetCurrentProcess GetCurrentProcessId GetCurrentThread GetCurrentThreadId GetExitCodeProcess GetExitCodeThread GetPriorityClass GetThreadPriority GetWindowThreadProcessId InitializeCriticalSection InterlockedDecrement InterlockedExchange InterlockedIncrement LeaveCriticalSection OpenEvent OpenMutex OpenProcess OpenSemaphore PulseEvent ReleaseMutex ReleaseSemaphore ResetEvent ResumeThread SetEvent SetPr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值