Delphi-替换控件WindowProc并发送消息



从TMessage问题获得控制句柄的方法开始,我创建了自己的实现,以便用自己的实现替换Windowproc,以便在按下鼠标左键时进行一些处理。

  TOverrideMessage = class
  public
    FControl: TWinControl;
    FOldWndProc: TWndMethod;
    procedure OverrideWindowProc(var Message: TMessage);
  end;

实现:

procedure TOverrideMessage.OverrideWindowProc(var Message: TMessage);
begin
  if Message.Msg = WM_NCLBUTTONDOWN then
    begin
      FOldWndProc(Message);
      if FControl is TSomeCustomControl then
        ShowMessage(TSomeCustomControl(FControl).Caption);//this property exists
    end
  else
   Dispatch(Message);
end;

并用我的类实例替换我想要的每个控件的windowproc:

  LOverrideMessage := TOverrideMessage.Create;
  LOverrideMessage.FControl := TSomeCustomControl(lControl4);
  LOverrideMessage.FOldWndProc := TWinControl(lControl4).WindowProc;
  TWinControl(lControl4).WindowProc := LOverrideMessage.OverrideWindowProc;

我遇到的问题是,消息没有正确地进一步发送到控件,因此控件没有正确绘制,等等。此外,我在类实现中没有收到WM_NCLBUTTONDOWN消息。怎么了?

您的主要问题是调用FOldWndProc失败。您需要调用它,而不是Dispatch。当您调用Dispatch时,您将获得基本的TObject处理,它什么也不做。

procedure TOverrideMessage.OverrideWindowProc(var Message: TMessage);
begin
  FOldWndProc(Message);
  if Message.Msg = WM_NCLBUTTONDOWN then
    if FControl is TSomeCustomControl then
      ShowMessage(TSomeCustomControl(FControl).Caption);//this property exists
end;

如果WM_NCLBUTTONDOWN没有到达,则消息不会发送到您的控制。

我很关心你的选角。当你写:

LOverrideMessage.FControl := TSomeCustomControl(lControl4);  
LOverrideMessage.FOldWndProc := TWinControl(lControl4).WindowProc;
TWinControl(lControl4).WindowProc := LOverrideMessage.OverrideWindowProc;

你为什么需要这些石膏?如果lControl4是从TWinControl派生的,那么就不需要这些强制转换。如果lControl4具有较少派生的编译时类型,则至少包括is检查。

最新更新