I have a few OpenTools API things which I just can't seem to figure out, so I'm hoping there will be an expert in here who could help me.
I have a few OpenTools API things which I just can't seem to figure out, so I'm hoping there will be an expert in here who could help me.
If created a few TCustomModule descendants and registered them correctly within the Delphi IDE. Everything is working fine on that end.
Now I was wondering how I could use the OpenTools API to get one of my TCustomModule descendants in the current project.
I have looped over all IOTAModule interfaces in my project, used OpenModule to get the corresponding IOTAModule, even used that to get the IOTAFormEditor and tried using the IOTAFormEditor.GetRootComponent approach. Sadly ... I can't seem to find any of my TCustomModules like that.
What I am trying to do is find all Form instances which descend from my very own TCustomForm variant. Is that actually possible at all ?
If created a few TCustomModule descendants and registered them correctly within the Delphi IDE. Everything is working fine on that end.
Now I was wondering how I could use the OpenTools API to get one of my TCustomModule descendants in the current project.
I have looped over all IOTAModule interfaces in my project, used OpenModule to get the corresponding IOTAModule, even used that to get the IOTAFormEditor and tried using the IOTAFormEditor.GetRootComponent approach. Sadly ... I can't seem to find any of my TCustomModules like that.
What I am trying to do is find all Form instances which descend from my very own TCustomForm variant. Is that actually possible at all ?
Have you looked at the resources form David Hoyle?
ReplyDeletedavidghoyle.co.uk - The Delphi Open Tools API Book – Dave's Development Blog
Bill Meyer Checked there before Posting here, but it didn't offer any help for my specific case :-(
ReplyDeleteDavid Hoyle Thomas Mueller Uwe Raabe
ReplyDeleteI'm not at a Delphi installation but a quick look in ToolsAPI.pas doesn't provide a direct route to getting a form's inherited classname. I think you would need to parser either the .pas file or more easily the .dfm as the information you require is on the first line.
ReplyDeleteI can look more when I get home.
Just guessing (no Delphi here at the moment): have you tried (IOTAFormEditor.GetRootComponent as INTAComponent).GetComponent?
ReplyDeleteSorry, no idea, and I can't look it up right now either.
ReplyDeleteDavid Hoyle if that is needed, Stefaan Lesage should look into DelphiAST by Roman Yankovsky at https://github.com/RomanYankovsky/DelphiAST
ReplyDeletegithub.com - RomanYankovsky/DelphiAST
Now at home looking through the ToolsAPI.pas file there is the following...
ReplyDeleteINTAComponent - This is the native component interface. You can get this interface by checking if IOTAComponent supports it.
...So I think Ondrej Kelle's idea has merit but I would probably do...
IF Supports(FormEditorInstance.GetRootComponent, INTAComponent, Out) THEN
Out.ClassName
...or something similar.
Ondrej Kelle Yes, I did try that, but somehow it didn't give the expected results. I will try to give it another go.
ReplyDeleteDavid Hoyle I actually tried that approach, but could not get it working ... will have a look at it right now.
ReplyDeleteYesterday, I had a 'temporary but dodgy solution'
ReplyDelete{$IFDEF CODESITE}
CodeSite.SendString( 'aModuleInfo.FormName' , aModuleInfo.FormName );
CodeSite.SendString( 'aModuleInfo.DesignClass', aModuleInfo.DesignClass );
{$ENDIF}
{ Apparently this also returns us units and other stuff. Checking on
the ModuleType doesn't seem to work, since it always returned 0, so
I had to check for the FormName and DesignClass :-( }
// if ( aModuleInfo.ModuleType = omtForm ) or
// ( aModuleInfo.ModuleType = omtDataModule ) then
if ( aModuleInfo.FormName <> '' ) and
( aModuleInfo.DesignClass <> '' ) then
begin
// aModule := aModuleInfo.OpenModule;
if ( aModuleInfo.DesignClass = 'TCoreController' ) then
begin
cbBaseController.Properties.Items.Add( 'T' + aModuleInfo.FormName );
end
else if ( aModuleInfo.DesignClass = 'TCoreAgent' ) then
begin
cbBaseAgent.Properties.Items.Add( 'T' + aModuleInfo.FormName );
end
else if ( aModuleInfo.DesignClass = 'TCoreListView' ) then
begin
cbBaseListView.Properties.Items.Add( 'T' + aModuleInfo.FormName );
end
else if ( aModuleInfo.DesignClass = 'TCoreRecordView' ) then
begin
cbBaseRecordView.Properties.Items.Add( 'T' + aModuleInfo.FormName );
end;
But this isn't 100% accurate, since simply changing the comment in the project source / DesignClass in the DPROJ file might mess this up. One advantage though ... it doesn't have to actually open the modules so it's pretty fast.
Will have another go at the INTAComponent approach.
Ondrej Kelle and David Hoyle the INTAComponent.GetComponent was my missing link. It seems to be working perfectly. A bit slow in big projects, but it's working.
ReplyDeleteStefaan Lesage so what was your final solution?
ReplyDelete