I'm trying to implement an IDE Wizard with ToolsApi and using the GExperts FAQ (http://www.gexperts.org/examples/GXModuleCreator.pas) as reference.
Although the bpl compiles, the unit doesn't shows up on the IDE. I'm Using Delphi 10.3.2 Rio.
unit ModuleCreator;
interface
uses
SysUtils, Windows, Dialogs, ToolsAPI;
type
TJIdeWizardSourceFile = class(TInterfacedObject, IOTAFile)
private
FSource: string;
public
function GetSource: string;
function GetAge: TDateTime;
constructor Create(const Source: string);
end;
TJIdeWizardModuleCreator = class(TInterfacedObject, IOTACreator, IOTAModuleCreator)
public
// IOTACreator
function GetCreatorType: string;
function GetExisting: Boolean;
function GetFileSystem: string;
function GetOwner: IOTAModule;
function GetUnnamed: Boolean;
// IOTAModuleCreator
function GetAncestorName: string;
function GetImplFileName: string;
function GetIntfFileName: string;
function GetFormName: string;
function GetMainForm: Boolean;
function GetShowForm: Boolean;
function GetShowSource: Boolean;
function NewFormFile(const FormIdent, AncestorIdent: string): IOTAFile;
function NewImplSource(const ModuleIdent, FormIdent, AncestorIdent: string): IOTAFile;
function NewIntfSource(const ModuleIdent, FormIdent, AncestorIdent: string): IOTAFile;
procedure FormCreated(const FormEditor: IOTAFormEditor);
end;
implementation
{ TJIdeWizardModuleCreator }
procedure TJIdeWizardModuleCreator.FormCreated(const FormEditor: IOTAFormEditor);
begin
//
end;
function TJIdeWizardModuleCreator.GetAncestorName: string;
begin
Result := 'Form';
end;
function TJIdeWizardModuleCreator.GetCreatorType: string;
begin
Result := sUnit;
end;
function TJIdeWizardModuleCreator.GetExisting: Boolean;
begin
Result := False;
end;
function TJIdeWizardModuleCreator.GetFileSystem: string;
begin
Result := '';
end;
function TJIdeWizardModuleCreator.GetFormName: string;
begin
Result := '';
end;
function TJIdeWizardModuleCreator.GetImplFileName: string;
begin
Result := '';
end;
function TJIdeWizardModuleCreator.GetIntfFileName: string;
begin
Result := '';
end;
function TJIdeWizardModuleCreator.GetMainForm: Boolean;
begin
Result := False;
end;
function TJIdeWizardModuleCreator.GetOwner: IOTAModule;
var
ModuleServices: IOTAModuleServices;
Module: IOTAModule;
NewModule: IOTAModule;
begin
// You may prefer to return the project group's ActiveProject instead
Result := nil;
ModuleServices := (BorlandIDEServices as IOTAModuleServices);
Module := ModuleServices.CurrentModule;
if Module <> nil then
begin
if Module.QueryInterface(IOTAProject, NewModule) = S_OK then
Result := NewModule
else if Module.OwnerModuleCount > 0 then
begin
NewModule := Module.OwnerModules[0];
if NewModule <> nil then
if NewModule.QueryInterface(IOTAProject, Result) <> S_OK then
Result := nil;
end;
end;
end;
function TJIdeWizardModuleCreator.GetShowForm: Boolean;
begin
Result := True;
end;
function TJIdeWizardModuleCreator.GetShowSource: Boolean;
begin
Result := True;
end;
function TJIdeWizardModuleCreator.GetUnnamed: Boolean;
begin
Result := True;
end;
function TJIdeWizardModuleCreator.NewFormFile(const FormIdent, AncestorIdent: string): IOTAFile;
begin
Result := nil;
end;
function TJIdeWizardModuleCreator.NewImplSource(const ModuleIdent, FormIdent, AncestorIdent: string): IOTAFile;
begin
// or Result := nil; for the default unit
Result := nil;
end;
function TJIdeWizardModuleCreator.NewIntfSource(const ModuleIdent, FormIdent, AncestorIdent: string): IOTAFile;
begin
Result := nil;
end;
{ TJIdeWizardSourceFile }
constructor TJIdeWizardSourceFile.Create(const Source: string);
begin
FSource := Source;
end;
function TJIdeWizardSourceFile.GetAge: TDateTime;
begin
Result := -1;
end;
function TJIdeWizardSourceFile.GetSource: string;
begin
result := FSource;
end;
end.
Here is an example of how I´m calling the method "NewImplSource" from IOTAModuleCreator
procedure TfrmMapearObjetoRelacional.btnSimpleORMDaoClick(Sender: TObject);
var
_Mod: TJIdeWizardModuleCreator;
_Str: string;
begin
_Mod := TJIdeWizardModuleCreator.Create;
try
_Str := _Mod.NewImplSource('unit1','','');
ShowMessage(_Str);
finally
FreeAndNil(_Mod);
end;
end;
If you don't have any luck debugging this in a second instance of the IDE like I suggested in a project, I think you should consider changing your code do follow the way I go about implementing something like this.
I implement the OTA interface of interest on a small form. Although the form is, in principle, unnecessary, it is very useful to give a visual sign that the thing's working and there is actually quite a lot of debugging you can do without having to resort to the second-IDE-instance business. You can build quite a lot of debugging facilities into the form by placing a small TMemo on it and using it as a logging facility to record what it does. And, of course, the form can have a MainMenu or whatever to invoke various of the OTA interface's methods to check that they do what they are supposed to do.
The form shouldn't be autocreated. Instead, create and call .Show on it in the `Initialization' section of the form's unit and Free it in its Finalization section.
Once you've compiled the .Dpk containing the form, install it in the IDE using
Install Packages.I always write OTA stuff in a form like this and very rarely get into any major problems that need the second-IDE-instance to investigate and resolve.
Good luck!