正确地覆盖WndProc

Dim*_*ima 3 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;
Run Code Online (Sandbox Code Playgroud)

不幸的是Inherited,这些程序中的单词不再起作用了!

重要提示:在某些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;
Run Code Online (Sandbox Code Playgroud)

我还想避免Inherited在每个消息ID之后插入,如下所示,因为它看起来很糟糕,我认为存在更优雅的覆盖方式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;
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:
如何正确覆盖WndProc以便能够使用在程序中分组的代码并且能够仅为某些消息调用原始窗口过程?

Rem*_*eau 5

正如RM的回答所说,你的消息处理方法可以调用inherited WndProc(Message)而不仅仅是inherited,这样可以正常工作.

但是,通过引入与正在处理的消息具有相同名称的方法,您将了解正在处理的特定消息.因此,您可能会发现使用消息方法而不是覆盖更容易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;
Run Code Online (Sandbox Code Playgroud)

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

procedure TMyControl.WMWindowPosChanged(var Message: TMessage);
begin
  inherited;
  //...
end;
Run Code Online (Sandbox Code Playgroud)