如何在不修改原始类的情况下将代码插入类中?

时间:2012-06-29 21:52:05

标签: delphi oop vcl delphi-2006

我已经创建了一个例程来使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;

1 个答案:

答案 0 :(得分:2)

在运行时存在修改类的构造或hack,例如参见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;

但要注意控制娱乐,这种情况发生的时间超出了你的想象。例如,更改编辑的BorderStyle属性会导致重新创建撤消修改的编辑。在这些情况下重做修改,让您可以全部跟踪它们。