http://blog.csdn.net/c3poo/article/details/25551545

让自己写的Delphi控件具备接收windows消息的能力

标签: delphi
 分类:

原理:该效果的实现主要是使用AllocateHwnd函数(可以查阅Delphi的帮助)生成一个非可视的窗口来响应消息,该函数的返回值既是非可视窗口的句柄。然后就可以在你的类中响应Windows的消息了。该函数只有一个参数就是要创建的非可视窗口的WinProc函数(就是处理该窗口消息的函数),当然你也可以在这个函数中处理你要处理的消息了。最后在类销毁时一定要DeallocateHWnd这个非可视窗口。

这些在翻看Delphi ScktComp单元的Socket类时得到。原因在于好奇这些类如何能得到Windows发给它们的关于Socket的消息。

以下是从TCustomWinSocket类摘出来源码(可以响应消息): 

 

 

[delphi] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. unit uClass;  
  2.   
  3. interface  
  4.   
  5. uses Messages, Classes, Dialogs;  
  6.   
  7. const  
  8. WM_MYTEST = WM_USER + $1000; // 测试用  
  9.   
  10. type  
  11. TMyClass = class  
  12. private  
  13. FHandle: THandle;  
  14. procedure WinProc(var Msg: TMessage);  
  15. procedure WMMyTest(var Msg: TMessage); message WM_MYTEST; // 测试用  
  16. public   
  17. constructor Create;  
  18. destructor Destroy; override;  
  19. property Handle: THandle read FHandle;  
  20. end;  
  21.   
  22. implementation  
  23.   
  24. { TMyClass }  
  25.   
  26. constructor TMyClass.Create;  
  27. begin  
  28. if FHandle = then  
  29. FHandle := AllocateHwnd(WinProc);  
  30. end;  
  31.   
  32. destructor TMyClass.Destroy;  
  33. begin  
  34. if FHandle <> then  
  35. DeallocateHWnd(FHandle);  
  36. end;  
  37.   
  38. procedure TMyClass.WinProc(var Msg: TMessage);  
  39. begin  
  40. try  
  41. //if Msg.Msg = WM_MYTEST then  
  42. // ShowMessage('I''m the first get the message "WM_MYTEST"');  
  43. Dispatch(Msg);  
  44. except  
  45. if Assigned(ApplicationHandleException) then  
  46. ApplicationHandleException(Self);  
  47. end;  
  48. end;  
  49.   
  50. procedure TMyClass.WMMyTest(var Msg: TMessage);  
  51. begin  
  52. ShowMessage('Test OK!' + #10  
  53. 'I''m coming from Class "TMyClass" with message "WM_MYTEST"!');  
  54. end;  
  55.   
  56. end.  

后记:这样,这个类就具有了一个句柄,发个消息WM_MYTEST看看。还能执行。呵呵,以后再写需要响应消息的类的时候,直接继承它就可以了,记得要把 WMMyTest过程删掉,它只是一个测试。

测试:
var 
mc: TMyClass;
begin
mc := TMyClass.Create; 
PostMessage(mc.Handle, WM_MYTEST, 0, 0); 
end;