如何拦截发送到我表单上的任何TWinControl的消息?

Ian*_*oyd 4 delphi delphi-xe6

我面临着一个令人生畏的任务,即WM_GETOBJECT只要将消息发送到TWinControl表单上的任何消息,就必须拦截和处理消息.

  • 每个小组
  • 每个嵌套面板
  • 每个编辑框
  • 每个组合框
  • 每个按钮
  • 每个工具栏
  • 每个日期时间选择器
  • 每一个形象
  • 每个列表视图
  • 每一个树木
  • 每一次胜利控制
  • 在每个表格上

显然,我不希望单独对每个控件进行子类化:

  • 它很难正确完成(当人们想要开始子类化时可能会使用SetWindowSubclass,而当他们完成时会使用RemoveWindowSubclass,并且没有意识到他们刚刚介绍的崩溃)
  • 很难做得很好
  • 它需要单独对每个控件进行子类化,可能是通过子控件迭代函数(如果在创建表单句柄时应用它而导致失败的常见错误,并在表单句柄被销毁时删除它们)

有没有办法参与处理使用SendMessage直接发送到子控件的每个消息

  • 类似于TApplicationEvents.OnMessage如何拦截每个发布的消息
  • 类似于KeyPreview允许表单查看每个发送密钥消息的方式

Rem*_*eau 7

如果您不想为每个单独的控件创建子类(这当然是一个选项,例如可以使用插入器类进行简化),那么您可以通过Win32 API 函数使用特定于线程WH_CALLWNDPROCWH_CALLWNDPROCRET钩子SetWindowsHookEx().钩子将告诉你哪个HWND接收每条消息,并且在与钩子相同的进程中挂钩线程时不需要在DLL中实现钩子.

如果需要TWinControl*给定的指针HWND,可以FindControl()Vcl.Controls单元中使用VCL的功能.