一天前,我开始重写我的一个旧组件,并决定提高其可读性。
我的组件是一个典型的 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/