如何拦截和抑制 TFrame 子组件的消息?

How to intercept and suppress a message for a TFrame's subcomponent?

我需要 intercept the WM_PASTE message 用于放置在 TFrame 的后代 class 中的 TEdit 组件。

如果条件不满足,我想通过粘贴操作。

有没有办法在帧级别执行此操作? (我的意思是,没有声明 TEdit 的后代)

Is there a way to do this at the frame level? (I mean, without declaring a TEdit's descendant)

WM_PASTE直接发给TEditwindow,TFrame是看不到的,所以必须subclassTEdit 直接为了拦截消息。您可以:

  • TFrameTEditWindowProc 属性 分配一个处理程序。如果你只有几个 TEdits 到 subclass,这是一个简单的方法,但是你想要 subclass 的 TEdits 越多,它就会变得越复杂:

    type
      TMyFrame = class(TFrame)
        Edit1: TEdit;
        ...
        procedure FrameCreate(Sender: TObject);
        ...
      private
        PrevWndProc: TWndMethod;
        procedure EditWndProc(var Message: TMessage);
        ...
      end;
    
    procedure TMyFrame.FrameCreate(Sender: TObject);
    begin
      PrevWndProc := Edit1.WindowProc;
      Edit1.WindowProc := EditWndProc;
      ...
    end;
    
    procedure TMyFrame.EditWndProc(var Message: TMessage);
    begin
      if Message.Msg = WM_PASTE then
      begin
        if SomeCondition then
          Exit;
      end;
      PrevWndProc(Message);
    end;
    
  • 编写并安装派生自 TEdit 的新组件,类似于 TMemo example you presented.

  • 定义一个仅对 TFrame 单元本地的插入器 class,在 TFrame class 声明之上,它将拦截WM_PASTE 对于 每个 TEdit 在框架上:

    type
      TEdit = class(Vcl.StdCtrls.TEdit)
        procedure WMPaste(var Message: TMessage); message WM_PASTE;
      end;
    
      TMyFrame = class(TFrame)
        Edit1: TEdit;
        Edit2: TEdit;
        ...
      end;
    
    procedure TEdit.WMPaste(var Message: TMessage);
    begin
      if not SomeCondition then
        inherited;
    end;