首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >正确覆盖WndProc

正确覆盖WndProc
EN

Stack Overflow用户
提问于 2018-04-26 10:54:52
回答 2查看 2.5K关注 0票数 3

一天前,我开始重写我的一个旧组件,我决定提高它的可读性。我的组件是一个典型的TWinControl,它覆盖了WndProc来处理我自己的许多消息。每条消息都有太多的代码,而我读代码就成了一个问题。

因此,为了寻找一种改进WndProc内部代码的解决方案,我组织了这些大型代码片段,每次在WndProc中传递适当的消息时都会调用这些代码。这就是现在的样子:

代码语言:javascript
复制
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;

不幸的是,这些程序中的Inherited单词不再有效了!

重要注意事项:在一些消息中,我没有调用Inherited来执行自己对此类消息的处理,因此下面所示的代码将打破我为实现某些特性所做的努力。

代码语言:javascript
复制
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

代码语言:javascript
复制
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,使其能够使用在过程中分组的代码,并且能够只对某些消息调用原始窗口过程?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-26 18:26:17

正如RM的回答所述,您的消息处理方法可以调用inherited WndProc(Message),而不仅仅是inherited,这将很好。

但是,通过引入与它们正在处理的消息的名称相同的方法,您将公开正在处理的特定消息的知识。因此,您可能会发现只使用消息方法而不是覆盖WndProc比较容易,例如:

代码语言:javascript
复制
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 (或不调用),例如:

代码语言:javascript
复制
procedure TMyControl.WMWindowPosChanged(var Message: TMessage);
begin
  inherited;
  //...
end;
票数 5
EN

Stack Overflow用户

发布于 2018-04-26 12:24:47

从WMWINDOWPOSCHANGED调用继承的WndProc将调用继承的一个。所以你可以这样做:

代码语言:javascript
复制
procedure WMWINDOWPOSCHANGED(var Message: TMessage)
begin
  // call inherited WndProc if you need to
  inherited WndProc(Message);
  .. do you own processing
end;
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50041183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档