The man of the day in this case is Heinz Z. (Heinz, if you want, I can make public your full name 🙂 ) which on my latest post about different techniques to extend the functionality of a class which we cannot control, gave a very simple and effective solution. Rather than leaving his answer there I think that’s appropriate to make a special post here giving him the pen:… (Note: I slightly adapted his example – comments and other miscellanea at the end)
after I read your idea here I have an other that use normal inheritance so all the problems you describe are gone. I have tested it with Delphi 2006 but I think it should work in every Delphi versions. The base idea is to replace a type like TLabel from StdCtrls with an other TLabel defined by myself. The Designer only knows StdCtrls.TLabel but the compiler see only my own definition of TLabel and create the desired instance. Have a look at the source:
unit LabelHelper; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TLabel = class(StdCtrls.TLabel) private FLines: TStrings; protected function GetLabelText: string; override; procedure LinesChanged(Sender: TObject); public constructor Create(AComponent: TComponent); override; destructor Destroy; override; property Lines: TStrings read FLines write FLines; end; implementation constructor TLabel.Create(AComponent: TComponent); begin inherited; FLines := TStringList.Create; TStringList(FLines).OnChange := LinesChanged; end; destructor TLabel.Destroy; begin FLines.Free; FLines := nil; inherited; end; function TLabel.GetLabelText: string; begin Result := FLines.Text; end; procedure TLabel.LinesChanged(Sender: TObject); begin AdjustBounds; end; end.
…and to use it one must be aware of Delphi’s unit precedence (ie. right to left in the uses clause) so you must put your helper unit after the unit of the helped class:
unit MainFormU; interface uses ...StdCtrls,...LabelHelper...; //etc.
I think that’s really nice.
So what was left is a compiler warning (which of course is needed not only for this case) saying that “The ‘TLabel’ definition from LabelHelper.pas hides the definition from StdCtrls.pas” Also perhaps a keyword (something like
TLabel = class helper for (StdCtrls.TLabel)… 🙂 ) will suppress the warning. Hmmm… I’m wondering if the class helpers doesn’t work exactly in this way…
Or perhaps I’m missing something?