1

I have created a routine to make the corners of Delphi visual controls to be rounded.

Now what I want to do is ensure that every visual object like TMemo, TEdit and TPanel comes rounded without having to call the function for everyone of them at the form creation.

How do I make an extension of the create method for each of these classes from my code (form unit), so they keep the name of the class and the normal behavior on other units?

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;
NGLN
  • 43,011
  • 8
  • 105
  • 200
NaN
  • 8,596
  • 20
  • 79
  • 153
  • Tell us more about how you make it round. You will need to hook some gdi message handler method. – Arnaud Bouchez Jun 29 '12 at 22:45
  • Done. Procedure RoundCornerOf(Control)... – NaN Jun 29 '12 at 22:59
  • What is wrong with my question? It is legit and is in role. – NaN Jun 29 '12 at 23:55
  • This won't work with many controls. – Warren P Jun 30 '12 at 00:10
  • Only with the ones that matter, like `Edit`, `Panel`, `Memo`, `Image` and like those, it will create a better looking interface. Delphi 2006 lacks good interface native controls... – NaN Jun 30 '12 at 00:14
  • XE2 with VCL styles looks a lot nicer than a Windows-themed control with the corners clipped off. – Warren P Jun 30 '12 at 01:02
  • What do you have against the native controls as they are? Did you perhaps forget to enable themes? – David Heffernan Jun 30 '12 at 07:31
  • I have nothing against them. That's why I wanna change them only in this particular project because it demands. i don't have money to buy new Delphi, so I use the 2006 that doesn't have themes yet. I have to find a way to change the OnCreate constructor or OnPaint or whatever that can put these rounded corners. (and I am also a fan of you @David. Your answers have helped me a lot) – NaN Jul 02 '12 at 00:02
  • Delphi 2006 does support themes. But not styles. Did you mean styles? – David Heffernan Jul 02 '12 at 06:22

1 Answers1

2

There exist constructs or hacks to modify classes at runtime, see for example Replacing a component class in delphi and Changing component class at run-time on demand. However, as fas as I understand, you have to declare separate types of all occurring control types.

An alternative is to transverse over all controls after the form's creation, using the Controls and ControlCount properties:

  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;

But beware of control recreation, which happens more then you would think. For instance, changing the BorderStyle property of an Edit results in recreating the Edit which undoes your modification. Redo the modification in those cases, providing you could track them all.

Community
  • 1
  • 1
NGLN
  • 43,011
  • 8
  • 105
  • 200
  • That observation of yours means that the index of each control, used by `I` may change if I RoundCorner() them? – NaN Jun 29 '12 at 23:47
  • Huh? No, index `I` doesn't change; it's just a loop control variable. – NGLN Jun 30 '12 at 00:04
  • 1
    This answer does the job of applying the method to all controls, but it does not answer the main question of modifying the class itself, like with the `class helper`. I will be continue to search for a way and if I don't find, I will use your way. – NaN Jul 02 '12 at 13:54