Just a question ... would it be possible to at design time get a list of specific TForm descendants in a project to use in a property editor? I can achieve something similar with a 'Registered' property which would do a register class call when set at design time, but I'm wondering if it would be possible to achieve the same thing without that?

Just a question ... would it be possible to at design time get a list of specific TForm descendants in a project to use in a property editor? I can achieve something similar with a 'Registered' property which would do a register class call when set at design time, but I'm wondering if it would be possible to achieve the same thing without that?

Any other way to trigger the Class Registration thing without the need for having to set a property at design time ?

Comments

  1. In runtime modern RTTI can easily do that. Not sure about design time.

    ReplyDelete
  2. At design time, you can use the ToolAPI to list all of the modules in a project, and for each module the designer (if available) and get to the form... however, the specific form class doesn't really exist at design time, the designer has a proxy of the actual runtime form (because it hasn't been compiled). So depending on what you are actually looking for, this might be tricky

    ReplyDelete
  3. Marco Cantù The idea was to have a PropertyEditor for a certain property which would list all available descendants for a specific FormClass so that I can instantiate them at runtime using the Class / ClassName.

    Everyone of those Forms / DataModules will be a descendant from a common new type of Form or Datamodule and will have it's own Custom Module. The idea is to allow the developer to choose a specific type of Datamodule (or From for another property) to be used in the application.

    ReplyDelete
  4. Should be doable... now if the question is how, I'll have to dig out some fairly old code I have somewhere (but don't know where)

    ReplyDelete
  5. Marco Cantù Well, I tried a few things out with the OpenTols API and have been getting a bit closer. This is what I did so far in the GetValues of my Property Editor :

    aActiveProject := GetActiveProject;

    if ( Assigned( aActiveProject ) ) then
    begin
    {$IFDEF USE_CODESITE}
    CodeSite.SendMsg( 'ActiveProject Found' );
    {$ENDIF}
    for iModule := 0 to Pred( aActiveProject.GetModuleCount ) do
    begin
    aModuleInfo := aActiveProject.GetModule( iModule );

    // if ( Assigned( aModuleInfo ) ) and
    // ( Ord( aModuleInfo.ModuleType ) = omtDataModule ) then

    if ( Assigned( aModuleInfo ) ) and
    ( aModuleInfo.DesignClass = 'TDataModule' ) and
    ( FileExists( aModuleInfo.FileName ) ) then

    // ( ( aModuleInfo.ModuleType = omtDataModule ) or
    // ( aModuleInfo.ModuleType = omtForm ) or
    // ( aModuleInfo.ModuleType = omtCustom ) ) then
    begin
    {$IFDEF USE_CODESITE}
    CodeSite.SendMsg( 'Found a Datamodule' );
    CodeSite.Send('aModuleInfo.Name', aModuleInfo.Name);
    CodeSite.Send('aModuleInfo.FileName', aModuleInfo.FileName);
    CodeSite.Send('aModuleInfo.FormName', aModuleInfo.FormName);
    CodeSite.Send('aModuleInfo.DesignClass', aModuleInfo.DesignClass);
    CodeSite.Send('aModuleInfo.ModuleType', aModuleInfo.ModuleType);
    {$ENDIF}

    aModule := aModuleInfo.OpenModule;

    for iEditors := 0 to Pred( aModule.ModuleFileCount ) do
    begin
    aEditor := aModule.ModuleFileEditors[ iEditors ];

    if ( Supports( aEditor, IOTAFormEditor, aFormEditor ) ) then
    begin
    if ( Supports( aFormEditor.GetRootComponent, INTAComponent, aComponent ) ) then
    begin
    if ( aComponent.GetComponent is TCoreController ) then
    begin
    Proc( aComponent.GetComponent.ClassName );
    end;
    end;
    end;
    end;
    end;
    end;
    end;

    Couple of issues I've found. IOTAModuleInfo.ModuleType doesn't seem to return omtDataModule for all my TDataModule descendants. The second problem I have is that it has to Open the Module in order to go get the Editor and work with that, which seems to trigger exceptions for all Classes which descend from another base TDataModule (something about ancestor not found).

    Also, this seems to be a rather slow process as well, so having to do that every time you drop down or select something from the property editor might not be such a good idea. Could be that my code needs some optimising though.

    ReplyDelete
  6. I don't think you can have details about a module and its root class unless the IDE opens it, but it's been some time since I last dug into this. And you might want to cache the info, clearly not redo the analysis each time...

    ReplyDelete

Post a Comment