Get all classes registered on a form (Views: 705)
Problem/Question/Abstract: How can I get all classes that are currently registered in my application? Example: If I have a form with no components on it and I do something like ReadComponentRes and that *.dfm has a TEdit in it, I get an exception that TEdit is of unknown class. If I put one TEdit on that form and do ReadComponentRes again, everything goes OK. So, I guess TEdit is registered somewhere. Now I would like to find all registered classes so I would know which classes I can use in my *.dfm. Answer: There is no way to get at classes registered via RegisterClasses, since the list holding these is private to the classes unit. You can get at the classes registered on a form, however, since those use a table connected to the form classes class record. The following is based on some spelunking in the classes unit: {defined in classes.pas} type PFieldClassTable = ^TFieldClassTable; TFieldClassTable = packed record Count: Smallint; Classes: array[0..8191] of ^TPersistentClass; end; function GetFieldClassTable(AClass: TClass): PFieldClassTable; assembler; asm MOV EAX, [EAX].vmtFieldTable OR EAX, EAX JE @@1 MOV EAX, [EAX + 2].Integer @@1: end; {end of quote from classes.pas} procedure TForm1.Button1Click(Sender: TObject); procedure Display(const S: string); begin memo1.lines.add(S); end; var pFCT: PFieldClassTable; aClass: TClass; i: SmallInt; begin memo1.clear; aClass := Classtype; while aClass < > TPersistent do begin Display('Registered classes for class ' + aClass.Classname); pFCT := GetFieldClasstable(aClass); if not Assigned(pFCT) then Display(' No classes registered') else begin Display(format(' %d classes registered', [pFCT^.Count])); for i := 0 to pFCT^.Count - 1 do Display(' ' + pFCT^.Classes[i]^.ClassName); end; aClass := aClass.ClassParent; end; end; |