Skip to content

Instantly share code, notes, and snippets.

@omonien
Last active October 15, 2022 13:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omonien/4e43c3d63a90be10d1ac8e481178c7ef to your computer and use it in GitHub Desktop.
Save omonien/4e43c3d63a90be10d1ac8e481178c7ef to your computer and use it in GitHub Desktop.
Accessing VCL controls by name, using Generics
object FormBase: TFormBase
Left = 0
Top = 0
Caption = 'FormBase'
ClientHeight = 441
ClientWidth = 624
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
TextHeight = 15
object Label1: TLabel
Left = 136
Top = 128
Width = 34
Height = 15
Caption = 'Label1'
end
object Button1: TButton
Left = 136
Top = 160
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
end
unit Forms.Base;
interface
uses
System.SysUtils, System.Variants, System.Classes, System.TypInfo, System.Rtti,
Winapi.Windows, Winapi.Messages,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TFormBase = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
function GetControlByName<T: TControl>(const AControlName: string): T;
end;
var
FormBase: TFormBase;
implementation
{$R *.dfm}
{ TFormBase }
function TFormBase.GetControlByName<T>(const AControlName: string): T;
begin
result := nil;
for var i := 0 to self.ControlCount - 1 do
begin
if SameText(Controls[i].Name, AControlName) then
begin
if not(Controls[i] is T) then
begin
var
LContext := TRttiContext.Create;
try
raise Exception.CreateFMt('%s is not a %s.', [AControlName, LContext.GetType(T).QualifiedName]);
finally
LContext.Free;
end;
end;
result := T(Controls[i]);
break;
end;
end;
if result = nil then
raise Exception.CreateFMt('%s not found.', [AControlName]);
end;
procedure TFormBase.Button1Click(Sender: TObject);
begin
GetControlByName<TLabel>('Label1').Caption := 'Hello World'; // Works
GetControlByName<TLabel>('Button1').Caption := 'Hello World'; // Exception "Button1 is not a TLabel"
GetControlByName<TLabel>('Edit1').Caption := 'Hello World'; // Exception "Edit1 not found"
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment