Last active
October 15, 2022 13:22
-
-
Save omonien/4e43c3d63a90be10d1ac8e481178c7ef to your computer and use it in GitHub Desktop.
Accessing VCL controls by name, using Generics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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