【问题标题】:How to insert code to a class without modify the original class?如何在不修改原始类的情况下将代码插入类?
【发布时间】:2012-07-01 10:29:58
【问题描述】:

我创建了一个例程来使 Delphi 可视控件的角变圆。

现在我要做的是确保每个可视对象(如 TMemoTEditTPanel)都被舍入,而不必在创建表单时为每个人调用函数。

如何从我的代码(表单单元)为这些类中的每一个扩展 create 方法,以便它们保留类的名称和其他单元上的正常行为?

procedure RoundCornersOf(Control: TWinControl) ;
var
   R: TRect;
   Rgn: HRGN;
begin
   with Control do
   begin
     R := ClientRect;
     rgn := CreateRoundRectRgn(R.Left, R.Top, R.Right, R.Bottom, 20, 20) ;
     Perform(EM_GETRECT, 0, lParam(@r)) ;
     InflateRect(r, - 4, - 4) ;
     Perform(EM_SETRECTNP, 0, lParam(@r)) ;
     SetWindowRgn(Handle, rgn, True) ;
     Invalidate;
   end;
end;

【问题讨论】:

  • 告诉我们更多关于你是如何做到这一点的。您将需要挂钩一些 gdi 消息处理程序方法。
  • 完成。过程 RoundCornerOf(Control)...
  • 我的问题有什么问题?它是合法的并且在起作用。
  • 这不适用于许多控件。
  • 只有那些重要的,比如EditPanelMemoImage,它会创建一个更好看的界面。 Delphi 2006 缺乏良好的界面原生控件...

标签: delphi oop vcl delphi-2006


【解决方案1】:

存在在运行时修改类的构造或技巧,例如参见Replacing a component class in delphiChanging component class at run-time on demand。但是,据我了解,您必须声明所有出现的控件类型的单独类型。

另一种方法是在创建表单后遍历所有控件,使用ControlsControlCount 属性:

  public
    procedure AfterConstruction; override;
  end;

procedure ModifyControls(Window: TWinControl);
var
  I: Integer;
begin
  for I := 0 to Window.ControlCount - 1 do
    if Window.Controls[I] is TWinControl then
    begin
      ModifyControls(TWinControl(Window.Controls[I]));
      RoundCorners(TWinControl(Window.Controls[I]));
    end;
end;

procedure TForm1.AfterConstruction;
begin
  inherited AfterConstruction;
  ModifyControls(Self);
end;

但要小心控制游戏,它发生的次数比你想象的要多。例如,更改 Edit 的 BorderStyle 属性会导致重新创建撤消修改的 Edit。在这些情况下重做修改,前提是您可以全部跟踪。

【讨论】:

  • 您的观察意味着I 使用的每个控件的索引如果我 RoundCorner() 它们可能会改变?
  • 嗯?不,索引I 不会改变;它只是一个循环控制变量。
  • 这个答案完成了将方法应用于所有控件的工作,但它没有回答修改类本身的主要问题,就像class helper 一样。我会继续寻找方法,如果我没有找到,我会使用你的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
  • 2020-02-13
  • 2011-10-31
  • 1970-01-01
相关资源
最近更新 更多