Solved

How to get a list of registered classes?

Posted on 1998-04-20
7
1,099 Views
Last Modified: 2013-11-23
I have registered a load of persistent classes using RegisterClass.  Is there a way to get a list of the names of the classes that have been registered?

It would save hassle, as the subsequent code (in descendant objects) would only need to call RegisterClass to register itself.  Basically I'm trying to avoid keeping my own list of the names, to save RAM and (more importantly) to keep code complexity down.
0
Comment
Question by:bcrotaz
  • 4
  • 3
7 Comments
 
LVL 1

Accepted Solution

by:
extreme earned 100 total points
Comment Utility
Unfortunally there's no a direct way to access the list of registered classes. In fact they are stored in a list named ClassList in the classes unit that is in declared in the implementation part of this unit. The two functions you have to access the items in this list are:

function FindClass(const ClassName: string): TPersistentClass;
function GetClass(const ClassName: string): TPersistentClass;

and as you see this both functions needs as a parameter a class name. That's don't what you want, by sure you want to access the classes in some iteration bucle or something like that. With the tools that delphi gives you in the VCL as is you can't do it. But, you can write a simple unit that overrides the standard RegisterClass procedure declared in the classes unit.

procedure RegisterClass(AClass: TPersistentClass);

you have to declare your custom procedure excactly as it is declared originallt, but you should write a proc like this:

unit MyRegisterClass;

interface

uses
  Classes;

var
  ClassesList : TStringList;

procedure RegisterClass(AClass: TPersistentClass);

implementation

uses
  Classes;

procedure RegisterClass(AClass: TPersistentClass);
begin
  Classes.RegisterClass (AClass);
  ClassesList.Add (AClass.ClassName, AClass);
end;

initialization
  ClassesList := TStringList.Create;
finalization
  ClassesList.Free;
end.

This a very simplified example on how you can do that work. You can add some control in the validity of the parameters if you want, and you can also override the proc RegisterClasses too... The code will not add too much overhead to you app, don't worry about the memory, sure will not be so much. The cost of this is only to add this new unit last in your uses clause. Doing do Delphi will use your custom function and not the one declared in the classes unit.
Of course, if you want to by more sure that your unit is used just add:

MyRegisterClass.RegisterClass instead of the sole RegisterClass call.

It's important to make you note that this will work only with the units that you register, if delphi in some place register some class, that class will be registered using the original REgisterClass, not yours. Anyway, I guess that no classes are automatically registered by delphi, the best approach is to register all standard classes you want in one place.

Well, I hope that this serve you.

Cheers

PS: If you still want to access this implementation variable, there's a way modifing the classes.pas code that will not cause problems with the rest of the units. This means, that will not force re-compiling the rest of the units. Modifing the interface part will cause that, and if you have DCU or package components you will not use it anymore. We can make some modifications to the implementation part to let you access this var, but is not trivial and is a little tricky.. i guess that is better and cleaner the approach I suggest you.
0
 
LVL 1

Author Comment

by:bcrotaz
Comment Utility
Love it - thanks.
0
 
LVL 1

Expert Comment

by:extreme
Comment Utility
Thanks bcrotaz. Do you want to modify the classes.pas file? If you want I'll show you how here, please post a comment for that.

Cheers
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 1

Author Comment

by:bcrotaz
Comment Utility
Yes please -
but how can you publicise a variable without altering the interface part?  I guess I'm about to find out...
0
 
LVL 1

Expert Comment

by:extreme
Comment Utility
Ok, here is the easy way. Using a helper or secondary unit. First you should backup your original classes.pas files. Then write this very simple unit (for now):

unit UnitClassList;

interface

uses
  Classes;

const
  ClassList : TList = nil;

implementation

end.


That unit will basically serve you to access the variable with the List of registered classes. So, if you want to access this var you should include this unit in your uses clause. You have to know that the classes list contains pointers to TPersistentClass classes.

Now go to the classes unit. This are the steps to modify it:

1st: Add to the uses clause in the implementation part of it the name of the newly created unit: UnitClassList.

2nd: In the initialization part of the classes.pas modify this part as following:

initialization
  ClassList := TList.Create;
  UnitClassList.ClassList := ClassList; // This line is added
  ClassAliasList := TStringList.Create;
  IntConstList := TList.Create;
  GlobalFixupList := TList.Create;
  MainThreadID := GetCurrentThreadID;
  GlobalLists := TList.Create;

3rd: And modify now the finalization part of the classes.pas unit as following:

finalization
  ClassList.Free;
  UnitClassList.ClassList := nil; // this is the line added, mainly for safety
  ClassAliasList.Free;
  FreeIntConstList;
  RemoveFixupReferences(nil, '');
  GlobalFixupList.Free;
  GlobalLists.Free;

end.

Well, I showed you here only the basic steps for know about the registered class list. You can add more functionality, like know when a class is registered, unregistered, when a list of classes is registered or unregistered, or catch when someone try to get or search for a registered class. All you have to do is create events for all this, and catch the appropiate procedure in the classes units that will call the right event handler. You can do this using a component, a component declared in UnitClassList for example, that declared properties for all these events. I don't know if you need this, so, if you need it notice me.

Hope this simple trick serve you.

Cheers!
0
 
LVL 1

Author Comment

by:bcrotaz
Comment Utility
Brilliant.

Why are such simple things so hard to figure out?

Thanks.
0
 
LVL 1

Expert Comment

by:extreme
Comment Utility
1st: Thanks.
2nd: You are welcome.

3rd: Answer:
I don't know... I guess life is that way...:)
I guess that we, humans, are smart animals that like to complicate our lifes to justify it as something interesting. The most of the times we don't see that the most beautiful things in life are the simple ones. Don't you think?

Topic changed...
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now