原理:该效果的实现主要是使用AllocateHwnd函数(能够查阅Delphi的帮助)生成一个非可视的窗口来响应消息,该函数的返回值既是非可视窗口的句柄。而后就能够在你的类中响应Windows的消息了。该函数只有一个参数就是要建立的非可视窗口的WinProc函数(就是处理该窗口消息的函数),固然你也能够在这个函数中处理你要处理的消息了。最后在类销毁时必定要DeallocateHWnd这个非可视窗口。
这些在翻看Delphi ScktComp单元的Socket类时获得。缘由在于好奇这些类如何能获得Windows发给它们的关于Socket的消息。ide
如下是从TCustomWinSocket类摘出来源码(能够响应消息):函数
unit uClass;测试
interfacespa
uses Messages, Classes, Dialogs;orm
const
WM_MYTEST = WM_USER + $1000; // 测试用继承
type
TMyClass = class
private
FHandle: THandle;
procedure WinProc(var Msg: TMessage);
procedure WMMyTest(var Msg: TMessage); message WM_MYTEST; // 测试用
public
constructor Create;
destructor Destroy; override;
property Handle: THandle read FHandle;
end;get
implementation源码
{ TMyClass }it
constructor TMyClass.Create;
begin
if FHandle = 0 then
FHandle := AllocateHwnd(WinProc);
end;io
destructor TMyClass.Destroy;
begin
if FHandle <> 0 then
DeallocateHWnd(FHandle);
end;
procedure TMyClass.WinProc(var Msg: TMessage);
begin
try
//if Msg.Msg = WM_MYTEST then
// ShowMessage('I''m the first get the message "WM_MYTEST"');
Dispatch(Msg);
except
if Assigned(ApplicationHandleException) then
ApplicationHandleException(Self);
end;
end;
procedure TMyClass.WMMyTest(var Msg: TMessage);
begin
ShowMessage('Test OK!' + #10
+ 'I''m coming from Class "TMyClass" with message "WM_MYTEST"!');
end;
end.
后记:这样,这个类就具备了一个句柄,发个消息WM_MYTEST看看。还能执行。呵呵,之后再写须要响应消息的类的时候,直接继承它就能够了,记得要把 WMMyTest过程删掉,它只是一个测试。
测试:
var
mc: TMyClass;
begin
mc := TMyClass.Create;
PostMessage(mc.Handle, WM_MYTEST, 0, 0);
end;
个人程序以下 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Unit2, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } FPluginRegistry : TPluginRegistry; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin FPluginRegistry := TPluginRegistry.Create; RegisterWindowMessage('WM_DESERIALIZATION'); end; procedure TForm1.Button1Click(Sender: TObject); begin //若是我用这句就能够接收到自定义的消息 // PostMessage(FPluginRegistry.WindowHandle,WM_DESERIALIZATION,0,0); //若是用这句就不行,怎么样才能实现广播呢? PostMessage(HWND_BROADCAST,WM_DESERIALIZATION,0,0); end; end. unit Unit2; interface uses Classes, Windows, Messages,Dialogs; const WM_DESERIALIZATION = WM_USER + 100; type TPluginRegistry = class(TPersistent) private FWindowHandle: HWND; procedure WndProc(var Msg: TMessage); protected procedure ProcessSaveProperty; virtual; public constructor Create; destructor Destroy; override; property WindowHandle : HWND read FWindowHandle; end; implementation uses Forms; { TPluginRegistry } constructor TPluginRegistry.Create; begin inherited Create; FWindowHandle := Classes.AllocateHWnd(WndProc); end; destructor TPluginRegistry.Destroy; begin Classes.DeallocateHWnd(FWindowHandle); inherited; end; procedure TPluginRegistry.ProcessSaveProperty; begin Showmessage('Received'); end; procedure TPluginRegistry.WndProc(var Msg: TMessage); begin with Msg do if Msg = WM_DESERIALIZATION then try ProcessSaveProperty; except Application.HandleException(Self); end else Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam); end; end.