关键函数:Classes.DeallocateHwnd;Classes.AllocateHwnd
原理:该效果的实现主要是使用AllocateHwnd函数(可以查阅Delphi的帮助)生成一个非可视的窗口来响应消息,该函数的返回值既是非可视窗口的句柄。然后就可以在你的类中响应Windows的消息了。该函数只有一个参数就是要创建的非可视窗口的WinProc函数(就是处理该窗口消息的函数),当然你也可以在这个函数中处理你要处理的消息了。最后在类销毁时一定要DeallocateHWnd这个非可视窗口。这些在翻看DelphiScktComp单元的Socket类时得到。原因在于好奇这些类如何能得到Windows发给它们的关于Socket的消息。
以下是从TCustomWinSocket类摘出来源码(可以响应消息):
unit uClass;
interface
uses Messages, Classes,Dialogs;
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 readFHandle;
end;
implementation
{ TMyClass }
constructor TMyClass.Create;
begin
if FHandle = 0 then
FHandle :=AllocateHwnd(WinProc);//申请句柄
end;
destructor TMyClass.Destroy;
begin
if FHandle 0 then
DeallocateHWnd(FHandle);//记住要释放
end;
procedure TMyClass.WinProc(var Msg:TMessage);
begin
try
//if Msg.Msg = WM_MYTESTthen
// ShowMessage('I''m the first get themessage "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" withmessage "WM_MYTEST"!');
end;
end.
后记:这样,这个类就具有了一个句柄,发个消息WM_MYTEST看看。还能执行。呵呵,以后再写需要响应消息的类的时候,直接继承它就可以了,记得要把WMMyTest过程删掉,它只是一个测试。
测试:
var
mc: TMyClass;
begin
mc :=TMyClass.Create;
PostMessage(mc.Handle, WM_MYTEST, 0,0);
标签:TObject,AllocateHwnd,飞外