Delphi-PRAXiS
Seite 1 von 2  1 2      

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 Modales Fenster in DLL, Taskleiste (https://www.delphipraxis.net/184066-modales-fenster-dll-taskleiste.html)

Dalai 23. Feb 2015 15:27

Modales Fenster in DLL, Taskleiste
 
Hallo *.*

auch wenn mein Thema mit dieser kürzlich gestellten Frage verwandt ist, so liegt die Sache doch anders.

Ich habe eine DLL (meine eigene), die in einem Host läuft (hier Total Commander). Ich erzeuge ein VCL-Fenster in meiner DLL und möchte dieses modal anzeigen. Benutze ich hierfür
Delphi-Quellcode:
fmPluginSettings:= TfmPluginSettings.Create(nil);
try
    fmPluginSettings.Init;
    fmPluginSettings.ShowModal;
finally
    fmPluginSettings.Free;
end;
wird ein neuer Button auf der Taskleiste erzeugt - unschön. Also muss ich auf irgendeine Weise das Parentfenster setzen. Mache ich das mit
Delphi-Quellcode:
fmPluginSettings:= TfmPluginSettings.CreateParented(AhParent);
verschwindet zwar der Button auf der Taskleiste, aber man kann das Fenster von Total Commander nicht mehr durch Klick auf die Taskleiste nach vorn holen, wenn eine andere Anwendung im Vordergrund ist und mein Dialog gerade angezeigt wird - ebenfalls unschön.

Was ich bisher benutzt habe, muss ich aus anderen Gründen vermeiden:
Delphi-Quellcode:
Application.Handle:= AhParent;
denn das gibt eine Access Violation beim Anzeigen von Tooltips oder der Verwendung von TActionList, aber lustigerweise nur unter 64 Bit.

Ein solches oder ähnliches Problem hatte doch bestimmt schon einmal irgendjemand, oder?

Ich bringe die Frage nochmal auf den Punkt: Wie kann ich einen modalen Dialog in einer DLL erzeugen, ohne einen Eintrag in der Taskleiste zu erzeugen und zwar so, dass die Host-Anwendung durch Klick auf die Tasleiste in den Vordergrund kommt, auch wenn der modale Dialog gerade angezeigt wird?

MfG Dalai

Dalai 28. Feb 2015 20:08

AW: Modales Fenster in DLL, Taskleiste
 
Hat noch keiner ein solches Problem gehabt?

Ich fasse nochmal zusammen:
  • Delphi-Quellcode:
    TForm.Create(nil)
    bringt einen zusätzlichen Button in der Taskleiste - will ich nicht.
  • Delphi-Quellcode:
    TForm.CreateParented
    lässt den Button in der Taskleiste verschwinden, aber die Anwendung lässt sich nicht über die Taskleiste in den Vordergrund bringen - funktioniert also ebenfalls nicht so, wie ich will.
  • Setzen von
    Delphi-Quellcode:
    Application.Handle
    führt zu Access Violations bei WIN64-Kompilaten, sobald in der DLL Tooltips oder TActionList benutzt werden - ist also auch nicht benutzbar.
Welche andere(n Möglichkeit(en) gibt's noch?

MfG Dalai

mm1256 2. Mär 2015 09:56

AW: Modales Fenster in DLL, Taskleiste
 
Sind alle so planlos, oder geht es nur mir so. Das Einzige was ich mir dazu vorstellen kann ist die Lösung des Win64 Problems. Welche (XE-)Version verwendest du denn, denn mit D5 kann's ja wohl nicht gehen?

Dalai 2. Mär 2015 13:57

AW: Modales Fenster in DLL, Taskleiste
 
Zitat:

Zitat von mm1256 (Beitrag 1292000)
Das Einzige was ich mir dazu vorstellen kann ist die Lösung des Win64 Problems.

Da kann ich leider nichts lösen, weil der Fehler nach meiner Beurteilung nicht in meinem Code liegt (ist natürlich derselbe für Win32 und Win64), und der Debugger beim Auftreten der AV auch nicht in irgendeinen Code springt. Sobald ich Application.Handle setze und bei irgendeinem Button oder einer anderen Komponente
Delphi-Quellcode:
ShowHint:= True;
und Hint auf irgendwas setze, tritt die AV auf, sobald der Hint angezeigt werden soll. Dasselbe passiert, wenn ich eine TActionList mit einem TPopupMenu verknüpfe und letzteres angezeigt werden soll (manuelles Popup beim Klick auf einen Button).

Zitat:

Welche (XE-)Version verwendest du denn, denn mit D5 kann's ja wohl nicht gehen?
Das ist völlig unabhängig von der Delphi-Version. Ich habe XE2 und XE5 probiert und bei beiden liefert mir der TC exakt denselben Stacktrace:
Code:
---------------------------
Total Commander 8.51a
---------------------------
Access violation.
Access violation
Windows XP Pro x64 SP2 5.2 (Build 3790)

Please report this error to the Author, with a description
of what you were doing when this error occurred!

Stack trace (x64):4AC25F
4364F2 436372 436191 40F40D 8CDC28 814EB9 8D7E72 77C43ABC

Press Ctrl+C to copy this report!
Continue execution?
---------------------------
Ja  Nein  
---------------------------
Nur kann weder ich noch der TC-Autor damit etwas anfangen. Es ist auch unabhängig von der Windows-Version. Ich habe XP64, Win7 x64 und IIRC auch Win8.1 x64 probiert und bei allen tritt dasselbe Problem mit demselben Stacktrace auf.

Offenbar mag es Delphi (die VCL oder die RTL) nicht, wenn man Application.Handle in einer DLL auf ein fremdes Fenster setzt. Naja, das an sich funktioniert ja, hat aber eben Nebenwirkungen. Und deshalb frag(t)e ich nach Alternativen.

MfG Dalai

Dalai 17. Mär 2015 15:41

AW: Modales Fenster in DLL, Taskleiste
 
Mittlerweile habe ich eine Lösung gefunden, auf die mich dieser Beitrag bei StackOverflow gebracht hat.

Delphi-Quellcode:
type
  TfmPluginSettings = class(TForm)
  [...]
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  [...]
  end;

implementation

var hwndTotalCmd: HWND;

procedure TfmPluginSettings.CreateParams(var Params: TCreateParams);
begin
    inherited;
    Params.WndParent:= hwndTotalCmd;
end;

procedure PluginShowForm(const AhParent: HWND);
var
    fmPluginSettings: TfmPluginSettings;
begin
    hwndTotalCmd:= AhParent;
    fmPluginSettings:= TfmPluginSettings.Create(nil);
    try
        fmPluginSettings.Init;
        fmPluginSettings.ShowModal;
    finally
        fmPluginSettings.Free;
    end;
end;
Gibt's da noch eine Möglichkeit, die unitglobale Variable zu vermeiden und stattdessen z.B. in eine Feldvariable von TfmPluginSettings zu verwandeln? Das CreateParams wird ja nicht direkt gerufen, aber sofort ausgelöst, wenn der Konstruktor arbeitet, z.B. durch ein
Delphi-Quellcode:
inherited Create;
. AFAIK sollte man es ja vermeiden, vor dem
Delphi-Quellcode:
inherited
eines Konstruktors irgendwas anderes zu machen.

MfG Dalai

oki 17. Mär 2015 15:58

AW: Modales Fenster in DLL, Taskleiste
 
Und wenn du den Constructor überlädst und das Handle mit übergibts? Das entsprechende Handle in ein privates Feld speichern (vor dem inherited) und der Rest bleibt so (Params.WndParent wird mit privatem Member bedient). Warum sollte man private Member der eigenen Klasse im Konstruktor nicht vor dem inherited setzen dürfen? Imho passiert da nichts schlimmes.

Gruß oki

Dalai 17. Mär 2015 16:22

AW: Modales Fenster in DLL, Taskleiste
 
Zitat:

Zitat von oki (Beitrag 1293803)
Und wenn du den Constructor überlädst und das Handle mit übergibts? Das entsprechende Handle in ein privates Feld speichern (vor dem inherited) und der Rest bleibt so (Params.WndParent wird mit privatem Member bedient).

Ja, genau so hatte ich das temporär, empfand es aber als unsauber, weil ich mir nicht sicher bin/war, was mit dem privaten Feld passiert bzw. ob das Fehler/Zugriffsverletzungen hagelt, weil das Objekt noch nicht vollständig erzeugt wurde.

Zitat:

Warum sollte man private Member der eigenen Klasse im Konstruktor nicht vor dem inherited setzen dürfen? Imho passiert da nichts schlimmes.
Tja, ich wäre mir gern sicher, bevor ich das auf die Menschheit loslasse ;).

MfG Dalai

Edelfix 17. Mär 2015 20:04

AW: Modales Fenster in DLL, Taskleiste
 
Ich verstehe deine Code Schnipsel nicht so ganz.

Verstehe ich das richtig dass du mit FindWindow das Handle für dein dll Formular hollst und dann keine Ahnung wie auf fmPluginSettings überträgst.

Also wie gelangt das Formular aus der dll in dein Programm ohne einen neuen Task Eintrag?

Dalai 17. Mär 2015 20:45

AW: Modales Fenster in DLL, Taskleiste
 
Zitat:

Zitat von Edelfix (Beitrag 1293820)
Verstehe ich das richtig dass du mit FindWindow das Handle für dein dll Formular hollst und dann keine Ahnung wie auf fmPluginSettings überträgst.

Nein. Das Handle des Parent bekomme ich in der Interface-Funktion FsExecuteFile vom Host (hier Total Commander). Innerhalb dieser Funktion wird die oben angegebene Funktion PluginShowForm gerufen, die das Handle dann weiterreicht; FsExecuteFile und PluginShowForm sind logischerweise in unterschiedlichen Units.

Zitat:

Also wie gelangt das Formular aus der dll in dein Programm ohne einen neuen Task Eintrag?
Fast. Das Formular ist in der DLL vorhanden und das soll im Host (nicht mein Programm) ohne neuen Taskbar-Button angezeigt werden.

MfG Dalai

Dalai 18. Mär 2015 15:54

AW: Modales Fenster in DLL, Taskleiste
 
Jetzt weiß ich wieder, warum ich diese Variante verworfen hatte:
Delphi-Quellcode:
type
  TfmPluginSettings = class(TForm)
  [...]
  private
    FParent          : HWND;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  public
    constructor Create(AOwner: TComponent; const AParent: HWND = 0); overload;
  [...]
  end;

procedure PluginShowForm(const AhParent: HWND);
var
    fmPluginSettings: TfmPluginSettings;
begin
    fmPluginSettings:= TfmPluginSettings.Create(nil, AhParent);
    try
        fmPluginSettings.Init;
        fmPluginSettings.ShowModal;
    finally
        fmPluginSettings.Free;
    end;
end;

constructor TfmPluginSettings.Create(AOwner: TComponent; const AParent: HWND = 0);
begin
    FParent:= AParent;
    inherited Create(AOwner);
end;

procedure TfmPluginSettings.CreateParams(var Params: TCreateParams);
begin
    inherited;
    Params.WndParent:= FParent;
end;
Bekommt man die Warnung
Zitat:

[Warnung] guiPluginSettings.pas(57): Methode 'Create' verbirgt virtuelle Methode vom Basistyp 'TCustomForm'
irgendwie weg? Oder ginge das nur, wenn man die Warnung für den Bereich abschaltet? Das scheint aber nur für die gesamte Klassendeklaration zu funktionieren, nicht für die Deklaration des Konstruktors selbst.
Delphi-Quellcode:
override;
kann ich ja nicht verwenden, weil die Methode eine andere Signatur hat.

MfG Dalai


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:35 Uhr.
Seite 1 von 2  1 2      

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