delphi - 正确重写 WndProc

标签 delphi controls wndproc

一天前,我开始重写我的一个旧组件,并决定提高其可读性。 我的组件是一个典型的 TWinControl,它已重写 WndProc 来处理我自己的大量消息。每条消息都有很多代码,阅读代码成了一个问题。
因此,为了寻找改进 WndProc 内部代码的解决方案,我将这些大段代码组织在每次在 WndProc 中传递适当消息时调用的过程中。这就是现在的样子:

procedure TMyControl.WndProc(var Message: TMessage);
begin
  case Message.Msg of        
    WM_WINDOWPOSCHANGED: 
      WMWINDOWPOSCHANGED(Message);
    WM_DESTROY: 
      WMDESTROY(Message);
    WM_STYLECHANGED: 
      WMSTYLECHANGED(Message);
    //  lots of the same procedures for Windows messages
    //  ...
    MM_FOLDER_CHANGED: 
      MMFOLDERCHANGED(Message);
    MM_DIRECTORY_CHANGED: 
      MMDIRECTORYCHANGED(Message);
    //  lots of the same procedures for my own messages
    //  ...
  else
    Inherited WndProc(Message);
  end;
end;

不幸的是,这些过程中的“继承”一词不再起作用!

重要说明:在某些 WM_XXX 消息中,我没有调用 Inherited 来执行我自己对此类消息的处理,因此下面显示的代码将破坏我的努力实现一些功能。

procedure TMyControl.WndProc(var Message: TMessage);
begin
  Inherited WndProc(Message);
  case Message.Msg of        
    WM_WINDOWPOSCHANGED: 
      WMWINDOWPOSCHANGED(Message);
    //  further messages
    //  ...
  end;
end;

我还想避免在每个消息 ID 之后插入 Inherited ,如下所示,因为它看起来很糟糕,而且我认为存在更优雅的方法来重写 WndProc

procedure TMyControl.WndProc(var Message: TMessage);
begin      
  case Message.Msg of        
    WM_WINDOWPOSCHANGED: 
    begin
      Inherited WndProc(Message);
      WMWINDOWPOSCHANGED(Message);
    end;
    //  further messages
    //  ...
  end;
end;

所以我的问题是:
如何正确重写WndProc,以便能够使用过程中分组的代码,并能够仅针对某些消息调用原始窗口过程?

最佳答案

正如 RM 的回答所述,您的消息处理方法可以调用继承的 WndProc(Message) 而不仅仅是继承,这样就可以正常工作。

但是,通过引入与正在处理的消息同名的方法,您将暴露正在处理的特定消息的知识。因此,您可能会发现使用 Message Methods 更容易而不是覆盖 WndProc,例如:

type
  TMyControl = class(...)
  private
    procedure WMWindowPosChanged(var Message: TMessage); message WM_WINDOWPOSCHANGED;
    procedure WMDestroy(var Message: TMessage); message WM_DESTROY;
    procedure WMStyleChanged(var Message: TMessage); message WM_STYLECHANGED;
    // and so on ...
  end;

您的message方法可以根据需要调用inherited(或不调用),例如:

procedure TMyControl.WMWindowPosChanged(var Message: TMessage);
begin
  inherited;
  //...
end;

关于delphi - 正确重写 WndProc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50041183/

相关文章:

forms - 带有系统阴影的圆形形式

delphi - 如果路径中有空格则 ShellExecute 失败

javascript - 用Javascript代码控制损失

c++ - 使用 map 时 WinAPI WndProc 静默失败

winapi - Win32 在父窗口中捕获子窗口消息

winforms - 如何使用 Windows 窗体在窗口标题栏中绘制自定义按钮?

delphi - Delphi中如何查找并关闭弹出菜单?

delphi - FreeMM 与 ShareMem

WPF 图层控制

php - 如何控制单选按钮?从数据库、PHP、MYSQL 回显数据