Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 正确覆盖WndProc_Delphi_Controls_Wndproc - Fatal编程技术网

Delphi 正确覆盖WndProc

Delphi 正确覆盖WndProc,delphi,controls,wndproc,Delphi,Controls,Wndproc,一天前,我开始重写我的一个旧组件,我决定提高它的可读性。 我的组件是一个典型的TWinControl,它重写了WndProc,以处理我自己的许多消息。每条消息都有很多代码,阅读代码对我来说成了一个问题。 因此,为了寻找一种改进WndProc内部代码的解决方案,我将这些大块代码组织在过程中,每次在WndProc中传递适当的消息时都会调用这些过程。这就是它现在的样子: procedure TMyControl.WndProc(var Message: TMessage); begin case

一天前,我开始重写我的一个旧组件,我决定提高它的可读性。 我的组件是一个典型的
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;
不幸的是,这些过程中继承的word不再有效

重要提示:在一些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
,以便能够使用过程中分组的代码,并且能够仅为某些消息调用原始窗口过程?

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

procedure WMWINDOWPOSCHANGED(var Message: TMessage)
begin
  // call inherited WndProc if you need to
  inherited WndProc(Message);
  .. do you own processing
end;

正如RM的回答所述,您的消息处理方法可以调用
继承的WndProc(message)
,而不仅仅是
继承的
,这将很好地工作

但是,通过引入与正在处理的消息同名的方法,您可以公开正在处理的特定消息的知识。因此,您可能会发现它更易于使用,而不是重写
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;
然后,您的
消息
方法可以根据需要调用
继承的
(或不调用),例如:

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

要么使用嵌套函数,要么使用
消息
指令。
不幸的是,这些过程中继承的单词不再工作了
您还记得
覆盖
WndProc吗?这不是@Vasek。Asker想打电话给WndProc。从重写的WndProc中可以看出这一点,但从其他方法中则不行。我想说,调用
DefaultHandler
应该就足够了。@Victoria,答案已经在这里了,但您建议使用
DefaultHandler
使我能够获得有关Delphi中消息处理的更多信息。非常感谢。是的,你的解决方案成功了。但对不起,RM,我接受了这个答案,因为它在现实中很优雅。谢谢你的有用想法!(对我来说)以这种方式处理信息是一个真正的诀窍。昨天给了我一个使用相同技术的链接。不幸的是,他没有提供评论作为回答,所以我会接受你的回答。非常感谢。