Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Chromium - Anwendung schließen->Systemfehler. Code: 1400. Ungültiges Fensterhandle (https://www.delphipraxis.net/199844-chromium-anwendung-schliessen-systemfehler-code-1400-ungueltiges-fensterhandle.html)

Hobbycoder 25. Feb 2019 09:36

Chromium - Anwendung schließen->Systemfehler. Code: 1400. Ungültiges Fensterhandle
 
Hi,
ich versuche schon eine geraume Zeit den Fehler zu finden, aber es gelingt mir nicht.

Mit folgender Procedure erstelle ich ein TabSheet mit einer Chromium-Componente drauf. Das funktioniert fehlerfrei.

Delphi-Quellcode:
procedure TLMCClientForm.LoadPageInNewTab(TargetTabIndex: Integer; Url: string);
var
  TempWindowParent: TCEFWindowParent;
  TempChromium    : TChromium;
  pgc: TPageControl;
  ts: TTabSheet;
  Panel: TPanel;
  Button: TButton;
begin
  if FindPageControl(pgcClient.Pages[TargetTabIndex], pgc) then
  begin
      ts:=TTabSheet.Create(self);
      ts.Caption:='Auftrag';
      ts.PageControl:=pgc;
      //pgc.ActivePage:=ts;
      Panel:=TPanel.Create(ts);
      Panel.Parent:=ts;
      Panel.Caption:='';
      Panel.Align:=alTop;
      Button:=TButton.Create(ts);
      Button.Parent:=Panel;
      Button.Width:=Panel.Height-2;
      Button.Align:=alRight;
      Button.Caption:='X';
      Button.Tag:=ts.PageIndex;
      Button.OnClick:=TabCloseButtonClick;

      TempWindowParent:=TCEFWindowParent.Create(ts);
      TempWindowParent.Parent:=ts;
      TempWindowParent.Align:=alClient;
      TempChromium:=TChromium.Create(ts);
      TempChromium.DefaultUrl:=Url;
      TempChromium.OnAfterCreated:=Chromium_OnAfterCreated;
      TempChromium.CreateBrowser(TempWindowParent, '');
  end;
end;
Beim Beenden jedoch erhalte ich folgende Fehlermeldung:

"Systemfehler. Code: 1400. Ungültiges Fensterhandle"

Kommentiere ich der erzeugen von TempWindowParent und TempChromium aus, so kommt diese Fehlermeldung nicht. Ich habe auch schon versucht als Owner self zu verwenden, was aber zum gleichen Ergebnis führt.

Das oben genannte TabSheet wird auf das PageControl gesetzt, welches ich in dieser Procedure erzeuge:
Delphi-Quellcode:
procedure TLMCClientForm.CreateTabBrowser(GUID: TGUID; Name: string);
var
  ts: TTabSheet;
  pgc: TPageControl;
  TempWindowParent: TCEFWindowParent;
  TempChromium    : TChromium;
begin
      ts:=TTabSheet.Create(Self);
      ts.Caption:=Name;
      ts.PageControl:=self.pgcClient;

      pgc:=TPageControl.Create(ts);
      pgc.Parent:=ts;
      pgc.Align:=alClient;

      ts:=TTabSheet.Create(pgc);
      ts.Caption:='Kalender';
      ts.PageControl:=pgc;

      TempWindowParent:=TCEFWindowParent.Create(ts);
      TempWindowParent.Parent:=ts;
      TempWindowParent.Align:=alClient;
      TempChromium:=TChromium.Create(ts);
      TempChromium.CreateBrowser(TempWindowParent, '');

      ts:=TTabSheet.Create(pgc);
      ts.Caption:='Map';
      ts.PageControl:=pgc;

      TempWindowParent:=TCEFWindowParent.Create(ts);
      TempWindowParent.Parent:=ts;
      TempWindowParent.Align:=alClient;
      TempChromium:=TChromium.Create(ts);
      TempChromium.CreateBrowser(TempWindowParent, '');
end;
das pdcClient ist bereits zur Entwurfszeit vorhanden.

Interessanterweise passiert der Fehler nicht bei den beiden Chromium-Componenten, die in der Procedure CreateTabBrowser erzeugt werden. Solange ich die Procedure LoadPageInNewTab nicht aufrufe erhalte ich auch keinen Fehler.

Aber wo ist der Unterschied? Bzw. wo mach ich den Fehler?

Nochmal zur Erklärung: Das PageControl pgcClient ist zur Entwurfzeit bereits vorhanden. Darin sollen TabSheet zu verschiedenen Themen erzeugt werden (z.B: "Opel","Ford","VW"), die selbst wiederum jeweils ein PageControl enthalten, welches 2 automatisch erzeugte Tabs "Kalender" und "Maps" enthalten. Das wird in der Procedure CreateTabBrowser erzeugt. Soweit funktioniert alles.
Um nun weitere Tabs z.B. "Auftrag" unter "Opel" oder "Ford" zu erzeugen dient die Procedure LoadPageInNewTab . Ab da entsteht o.g. Fehlermeldung.

Delphi-Version: 10.1 Berlin

peterbelow 25. Feb 2019 11:08

AW: Chromium - Anwendung schließen->Systemfehler. Code: 1400. Ungültiges Fensterhandl
 
Füge mal ein

ts.HandleNeeded;

vor der

TempWindowParent:=TCEFWindowParent.Create(ts);

Zeile ein, vielleicht hilft das.

Die VCL erzeugt Windows-Handles erst, wenn ein Handle wirklich gebraucht wird, also spätestens, wenn ein TWinControl angezeigt wird. Das kann manchmal zu Problemen mit externen Componenten führen, die ursprünglich nicht für die VCL gedacht waren.

Du solltest auch konsequent darin sein, welche Komponente Du als Owner für im Kode erzeugte Komponenten verwendest. Das hat einen Einfluß darauf, in welcher Reihenfolge die Komponenten später zerstört werden. Versuch mal, immer das Hostform als Owner zu verwenden, vielleicht funktioniert das besser.

Falls Du den Fehler so nicht in den Griff bekommst könnte es notwendig sein, die Chromium-Komponenten explizit zu free-en, bevor das Form geschlossen wird. Du hast da eine ziemlich tiefe Staffelung von Controls, da kann die Sequenz des Abbaus etwas unintuitiv werden :?

Hobbycoder 26. Feb 2019 08:39

AW: Chromium - Anwendung schließen->Systemfehler. Code: 1400. Ungültiges Fensterhandl
 
Tja, das HandleNeeded hats leider nicht gebracht.

Zitat:

Zitat von peterbelow (Beitrag 1426375)
Du solltest auch konsequent darin sein, welche Komponente Du als Owner für im Kode erzeugte Komponenten verwendest. Das hat einen Einfluß darauf, in welcher Reihenfolge die Komponenten später zerstört werden. Versuch mal, immer das Hostform als Owner zu verwenden, vielleicht funktioniert das besser.

Normalerweise verwende ich schon immer wo es geht die Hostform als Owner. Im Falle von TabSheets ist es aber durchaus sinnvoll, allen darin enthaltenen Komponente als Owner dieses zu gehen. Wenn man dann das Tabscheet freigibt, werden alle darin enthaltenen Komponenten ebenfalls freigegeben.

Aber ich habe es auch mit Self probiert.

Zitat:

Zitat von peterbelow (Beitrag 1426375)
Falls Du den Fehler so nicht in den Griff bekommst könnte es notwendig sein, die Chromium-Komponenten explizit zu free-en, bevor das Form geschlossen wird. Du hast da eine ziemlich tiefe Staffelung von Controls, da kann die Sequenz des Abbaus etwas unintuitiv werden :?

Ja, das denke ich auch. Diese Art der Hierarchie der verschiedenen PageControls ist leider notwendig, um die benötigte Darstellung zu realisieren. Leider ist das Beispiel TabbedBrowser, was den Demos der CEF4 beiliegt stark darauf ausgelegt, dass es eben nur ein PageControl gibt. Ich habe bereits versucht, das dahingehend umzubauen, aber das endet in einem heillosen Durcheinander, da immer das passsende PageControl gesucht werden muss. Eine richtig gute Möglichkeit fällt mir da zur Zeit nicht ein.

Im Moment überlege ich, den ganzen Chromium in einer Klasse zu kapseln, und alle entsprechenden Events darin unterzubringen. Der Vorteil wäre, dass alle notwendigen Referenzen dann in der Klasse zu finden wären, und ein "SearchChromium" oder "SearchWindowParent" möglicherwiese entfallen bzw. einfacher zu händeln wären.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:52 Uhr.

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