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,我接受了这个答案,因为它在现实中很优雅。谢谢你的有用想法!(对我来说)以这种方式处理信息是一个真正的诀窍。昨天给了我一个使用相同技术的链接。不幸的是,他没有提供评论作为回答,所以我会接受你的回答。非常感谢。