Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war (https://www.delphipraxis.net/214709-exception-beim-schliessen-der-ide-wenn-meine-erweiterung-vorher-aktiv-war.html)

mattia72 25. Feb 2024 11:10

Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war
 
Hallo zusammen,

ich arbeite an eine Erweiterung, damit man RipGrep Suche in der IDE benutzen kann.
Das Projekt ist hier verwaltet: https://github.com/mattia72/DRipGrepper

Ich habe ein Package erstellt, den Such-Form aus der IDE aufrufen zu können. Der Form ist dockable, stammt aus TfmIdeDockForm von GExpert und Docking funktioniert auch ohne Probleme.

Das einzige Problem ist, diese Exception, wenn ich die IDE schließe:
Code:
[6BEEB79F]{designide280.bpl} DeskUtil.TDesktopFormClassItem.SaveWindow (Line 299, "DeskUtil.pas" + 3) + $8
[6C3903DD]{vcl280.bpl } Vcl.Controls.TWinControl.CMInvalidate (Line 12738, "Vcl.Controls.pas" + 10) + $4
[6C38802E]{vcl280.bpl } Vcl.Controls.TControl.WndProc (Line 7591, "Vcl.Controls.pas" + 91) + $6
[69BCB1C2]{coreide280.bpl} Desktop.GetFieldAddress (Line 2061, "Desktop.pas" + 1) + $B
[6BEEB77D]{designide280.bpl} DeskUtil.TDesktopFormClassItem.SaveWindow (Line 297, "DeskUtil.pas" + 1) + $3
[6BEEBA20]{designide280.bpl} DeskUtil.SaveDesktopFormClasses (Line 404, "DeskUtil.pas" + 2) + $10
[69BC7747]{coreide280.bpl} Desktop.SaveDeskState (Line 833, "Desktop.pas" + 9) + $5
[69BC7A88]{coreide280.bpl} Desktop.SaveDeskFile (Line 891, "Desktop.pas" + 35) + $7
[69BC94A1]{coreide280.bpl} Desktop.SaveProjectGroupDesktop (Line 1334, "Desktop.pas" + 2) + $21
[0046B5D1]{bds.exe    } AppMain.TAppBuilder.WindowCloseQuery (Line 4137, "AppMain.pas" + 43) + $1A
[6C4CFCB4]{vcl280.bpl } Vcl.Forms.TCustomForm.CloseQuery (Line 7785, "Vcl.Forms.pas" + 8) + $14
[5393ED50]{DDevExtensionsD110.dll} Unbekannte Funktion bei __dbk_fcall_wrapper + $3D390
[5393EE1E]{DDevExtensionsD110.dll} Unbekannte Funktion bei __dbk_fcall_wrapper + $3D45E
[6B48CE53]{vclwinx280.bpl} Vcl.TitleBarCtrls.TCustomTitleBarPanel.TitleButtonCloseClick (Line 1534, "Vcl.TitleBarCtrls.pas" + 2) + $7
[6C388587]{vcl280.bpl } Vcl.Controls.TControl.Click (Line 7707, "Vcl.Controls.pas" + 9) + $8
[6C51FE30]{vcl280.bpl } Vcl.Buttons.TCustomSpeedButton.Click (Line 1963, "Vcl.Buttons.pas" + 0) + $0
[6C51FE1A]{vcl280.bpl } Vcl.Buttons.TCustomSpeedButton.MouseUp (Line 1956, "Vcl.Buttons.pas" + 25) + $C
[6C3889B8]{vcl280.bpl } Vcl.Controls.TControl.DoMouseUp (Line 7835, "Vcl.Controls.pas" + 2) + $25
[6C388A46]{vcl280.bpl } Vcl.Controls.TControl.WMLButtonUp (Line 7848, "Vcl.Controls.pas" + 9) + $6
[6C38802E]{vcl280.bpl } Vcl.Controls.TControl.WndProc (Line 7591, "Vcl.Controls.pas" + 91) + $6
[5D27A9B1]{cxLibraryRS28.bpl} Dxhooks. + $0
[5D27A7C5]{cxLibraryRS28.bpl} Dxhooks. + $0
[6C387C64]{vcl280.bpl } Vcl.Controls.TControl.Perform (Line 7369, "Vcl.Controls.pas" + 10) + $8
[6C38CA25]{vcl280.bpl } Vcl.Controls.TWinControl.IsControlMouseMsg (Line 10408, "Vcl.Controls.pas" + 25) + $29
[6C493338]{vcl280.bpl } Vcl.Themes.TStyleManager.HandleMessage (Line 5872, "Vcl.Themes.pas" + 11) + $11
[6C38D03A]{vcl280.bpl } Vcl.Controls.TWinControl.WndProc (Line 10586, "Vcl.Controls.pas" + 112) + $6
[6C38C700]{vcl280.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 10321, "Vcl.Controls.pas" + 3) + $6
[6C8A5C1C]{rtl280.bpl } System.Classes.StdWndProc (Line 18517, "System.Classes.pas" + 8) + $0
[6C794B78]{rtl280.bpl } System.@FinalizeRecord (Line 33223, "System.pas" + 81) + $2
[6C4D5263]{vcl280.bpl } Vcl.Forms.TApplication.ProcessMessage (Line 11488, "Vcl.Forms.pas" + 23) + $1
[6C4D52A6]{vcl280.bpl } Vcl.Forms.TApplication.HandleMessage (Line 11518, "Vcl.Forms.pas" + 1) + $4
[6C4D55E5]{vcl280.bpl } Vcl.Forms.TApplication.Run (Line 11657, "Vcl.Forms.pas" + 27) + $3
[004B80A2]{bds.exe    } bds.bds (Line 227, "" + 16) + $2
In der Liste taucht mein Expert gar nicht auf :?
Form und Expert destructor wird erst nach dieser Exception aufgerufen...
Wenn ich mein Expert deinstalliere, kommt der Fehler nicht.
Wenn ich den Expert installiere, aber den Form nicht öffne, kommt der Fehler auch nicht.
Hat jemand eine Idee, was der Fehler ist, oder wie ich weiter analysieren könnte?
Übrigens: ich bin mit Delphi 11 unterwegs.

Uwe Raabe 25. Feb 2024 13:20

AW: Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war
 
Bau es zurück bis der Fehler nicht mehr auftritt.

Zu TfmIdeDockForm kann ich nichts sagen, da ich in meinen Plugins nur noch INTACustomDockableForm verwende.

dummzeuch 25. Feb 2024 14:15

AW: Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war
 
Ich habe gerade gesucht, woher dieser Code in GExperts überhaupt stammt. Vermutlich aus einem Blog-Artikel von Allan Bauer zu Borland Zeiten (um 2000 herum), der längst aus dem nomalen Internet verschwunden ist. Glücklicherweise gibt es ja das Internet Achive: Opening Doors: Getting Inside the IDE
Blöderweise sind die zugehörigen Dateien auf Borland CodeCentral nicht archiviert worden, aber vielleicht funktioniert ja die Nummer noch im cc von Embarcadero:
http://cc.embarcadero.com/Item/14529
(Vorausgesetzt der Server funktioniert irgendwann wieder, aktuell liefert er Gateway Timeout)
(und eigentlich sollte Code Central ja komplett entfernt werden.)

Keine Ahnung, ob das weiterhilft.

@Uwe: Danke für den Hinweis, dieses INTACustomDockableForm Interface war komplett an mir vorbeigegangen. Unpraktischerweise gibt es das aber erst ab Delphi 2010.

Uwe Raabe 25. Feb 2024 14:55

AW: Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war
 
Zitat:

Zitat von dummzeuch (Beitrag 1533864)
Unpraktischerweise gibt es das aber erst ab Delphi 2010.

Einer der Gründe, warum ich mit meinen Tools auch mal gnadenlos alte Zöpfe abschneide. Mal ehrlich, einen Großteil der Zeit zur Maintenance verbringt man doch eh schon mit der Anpassung an neue Versionen, seien es Styles, High-DPI, Multiline-Strings oder was auch immer. Je einfacher ich mir das mache, desto mehr Zeit bleibt für neue Features. Wenn jemand unbedingt eine ältere Delphi-Version einsetzen will oder muss, bleibt ihm ja immer noch die ältere Version des Tools (natürlich nur wenn es das damals schon gab, aber andernfalls hätte er es ja auch gar nicht erst).

dummzeuch 25. Feb 2024 16:29

AW: Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1533865)
Zitat:

Zitat von dummzeuch (Beitrag 1533864)
Unpraktischerweise gibt es das aber erst ab Delphi 2010.

Einer der Gründe, warum ich mit meinen Tools auch mal gnadenlos alte Zöpfe abschneide. Mal ehrlich, einen Großteil der Zeit zur Maintenance verbringt man doch eh schon mit der Anpassung an neue Versionen, seien es Styles, High-DPI, Multiline-Strings oder was auch immer. Je einfacher ich mir das mache, desto mehr Zeit bleibt für neue Features. Wenn jemand unbedingt eine ältere Delphi-Version einsetzen will oder muss, bleibt ihm ja immer noch die ältere Version des Tools (natürlich nur wenn es das damals schon gab, aber andernfalls hätte er es ja auch gar nicht erst).

Solange ich selbst noch Delhi 2007 einsetze, habe ich irgendwie einen Grund, diese Version weiter zu supporten. ;-)

Aber Du hast recht: Alles < Delphi 2007 nervt mich allmählich nur noch. Meine Delphi 6 Installation ist inzwischen so kaputt, dass ich nur noch den commandline Compiler benutze. Debugging entfällt oder findet mit Delphi 7 statt. Meine Delphi 2005 Installation will neu registriert werden, also auch da nur noch commandline Compiler und kein debugging mehr. Spätestens wenn ich mal wieder einen neuen Rechner aufsetzen muss, dann fliegt alles < Delphi 2007 raus. Wenn sich dann niemand findet, dem GExperts Support für die älteren Delphi Versionen wichtig genug ist, dass er sich selbst drum kümmert (ich rechne nicht damit), war's das.

mattia72 25. Feb 2024 17:18

AW: Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1533863)
Bau es zurück bis der Fehler nicht mehr auftritt.

Zu TfmIdeDockForm kann ich nichts sagen, da ich in meinen Plugins nur noch INTACustomDockableForm verwende.

Danke für den Hinweis. Ich probiere mit INTACustomDockableForm weiterzukommen...

Update: TfmIdeDockForm war schuldig, wenn ich die Unit nicht verwende, kommt der Fehler nicht.

mattia72 15. Mär 2024 18:03

AW: Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war
 
Könnte jemand erklären, wie man die INTACustomDockableForm Schnittstelle benutzen soll?

Ich habe so probiert:
Alle UI Komponente habe ich in TMyFrame kopiert, und die originale Form enthält jetzt nur diesen Frame:

Delphi-Quellcode:
   
TMyForm = class(TDockableForm)
var
   MyFrame1 : TMyFrame;
...
end;
...
{$R *.dfm}
Meine Form ist von dieser Klasse abgeleitet:
Delphi-Quellcode:
TDockableForm = class(TForm, INTACustomDockableForm)
...
/// <summary>
/// Returns the class of the frame that you want embedded in the dockable form
/// </summary>
function GetFrameClass : TCustomFrameClass; virtual; abstract;
/// <summary>
/// Called when an instance of the specified frame class is created
/// </summary>
procedure FrameCreated(AFrame : TCustomFrame); virtual;
...
end;

GetFrameClass gibt die Klasse TMyFrame zurück.

Wenn ich die Erweiterung aus Menü aufrufe, wird (nach ein Paar Exception) die Form korrekt angezeigt, aber FrameCreated wird nicht aufgerufen, und mein OutputDebugString Meldungen aus TMyFrame werden auch nicht angezeigt...

Wie sollte das gemacht werden? Hat jemand vielleicht ein Beispiel?

Uwe Raabe 15. Mär 2024 23:35

AW: Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war
 
Hier ein ziemlich rudimentäres Beispiel. Man muss lediglich beim Start/Beenden das CreateInstance/DestroyInstance aufrufen. Wenn es ein Expert (.dll) wird, kann das DestroyInstance entfallen.
Eine Form-Instanz erhält man mit CreateDockableForm. Damit kann auch eine existierende Instanz wieder sichtbar gemacht werden.

Die Rückgabe bei GetFrameClass sollte natürlich die passende Klasse sein.

Delphi-Quellcode:
unit DockableFormUnit;

interface

uses
  System.IniFiles, System.Classes,
  Vcl.ActnList, Vcl.ComCtrls, Vcl.Forms, Vcl.ImgList, Vcl.Menus,
  ToolsAPI, DesignIntf, DockForm;

type
  TMyDockableForm = class(TInterfacedPersistent, INTACustomDockableForm)
  private
  class var
    FInstance: TMyDockableForm;
  protected
    procedure CustomizePopupMenu(PopupMenu: TPopupMenu);
    procedure CustomizeToolBar(ToolBar: TToolBar);
    function EditAction(Action: TEditAction): Boolean;
    procedure FrameCreated(AFrame: TCustomFrame);
    function GetCaption: string;
    function GetEditState: TEditState;
    function GetFrameClass: TCustomFrameClass;
    function GetIdentifier: string;
    function GetMenuActionList: TCustomActionList;
    function GetMenuImageList: TCustomImageList;
    function GetToolBarActionList: TCustomActionList;
    function GetToolBarImageList: TCustomImageList;
    procedure LoadWindowState(Desktop: TCustomIniFile; const Section: string);
    procedure SaveWindowState(Desktop: TCustomIniFile; const Section: string; IsProject: Boolean);
  public
    class procedure CreateInstance;
    class procedure DestroyInstance;
    class function CreateDockableForm: TDockableForm;
  end;

implementation

class procedure TMyDockableForm.CreateInstance;
begin
  FInstance := TMyDockableForm.Create;
  (BorlandIDEServices as INTAServices).RegisterDockableForm(FInstance);
end;

class procedure TMyDockableForm.DestroyInstance;
begin
  (BorlandIDEServices as INTAServices).UnregisterDockableForm(FInstance);
  FInstance.Free;
end;

class function TMyDockableForm.CreateDockableForm: TDockableForm;
begin
  Result := (BorlandIDEServices as INTAServices).CreateDockableForm(FInstance) as TDockableForm;
end;

procedure TMyDockableForm.CustomizePopupMenu(PopupMenu: TPopupMenu);
begin
end;

procedure TMyDockableForm.CustomizeToolBar(ToolBar: TToolBar);
begin
end;

function TMyDockableForm.EditAction(Action: TEditAction): Boolean;
begin
  Result := False;
end;

procedure TMyDockableForm.FrameCreated(AFrame: TCustomFrame);
begin
end;

function TMyDockableForm.GetCaption: string;
begin
  Result := 'My Dockable Form';
end;

function TMyDockableForm.GetEditState: TEditState;
begin
  Result := [];
end;

function TMyDockableForm.GetFrameClass: TCustomFrameClass;
begin
  Result := TFrame;
end;

function TMyDockableForm.GetIdentifier: string;
begin
  Result := 'MyDockableForm';
end;

function TMyDockableForm.GetMenuActionList: TCustomActionList;
begin
  Result := nil;
end;

function TMyDockableForm.GetMenuImageList: TCustomImageList;
begin
  Result := nil;
end;

function TMyDockableForm.GetToolBarActionList: TCustomActionList;
begin
  Result := nil;
end;

function TMyDockableForm.GetToolBarImageList: TCustomImageList;
begin
  Result := nil;
end;

procedure TMyDockableForm.LoadWindowState(Desktop: TCustomIniFile; const Section: string);
begin
end;

procedure TMyDockableForm.SaveWindowState(Desktop: TCustomIniFile; const Section: string; IsProject: Boolean);
begin
end;

end.
Edit: Die Parent-Klasse muss natürlich TInterfacedPersistent sein, wenn man davon eine Instanzvariable füllt.

Solange die Klasse keine weitere Funktion erfüllt, könnte man die Instanzvariable als INTACustomDockableForm deklarieren oder sogar ganz darauf verzichten.
Allerdings sollte bei einem Designtime-Package die Möglichkeit in Betracht gezogen werden, dass es im laufenden Betrieb entladen wird und das Unregister dann besser durchgeführt werden sollte.

dummzeuch 16. Mär 2024 16:59

AW: Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war
 
Das Beispiel für einen Debug-Visualizer für TStrings, das mit Delphi kommt, benutzt diese API. Vielleicht hilft das ja weiter? Diese Beispiele liegen im Unterverzeichnis Source\Visualizers der Delphi Installation.

mattia72 20. Mär 2024 14:13

AW: Exception beim Schließen der IDE, wenn meine Erweiterung vorher aktiv war
 
Danke für beide Antwort.
Mit dem rudimentären Beispiel konnte ich weiter machen. Das Ergebnis ist noch nicht makellose, aber hoffnungsvoll ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz