AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Modales Fenster in DLL, Taskleiste

Ein Thema von Dalai · begonnen am 23. Feb 2015 · letzter Beitrag vom 18. Mär 2015
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#1

Modales Fenster in DLL, Taskleiste

  Alt 23. Feb 2015, 15:27
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 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: 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
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#2

AW: Modales Fenster in DLL, Taskleiste

  Alt 28. Feb 2015, 20:08
Hat noch keiner ein solches Problem gehabt?

Ich fasse nochmal zusammen:
  • TForm.Create(nil) bringt einen zusätzlichen Button in der Taskleiste - will ich nicht.
  • 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 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
  Mit Zitat antworten Zitat
mm1256

Registriert seit: 10. Feb 2014
Ort: Wackersdorf, Bayern
640 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

AW: Modales Fenster in DLL, Taskleiste

  Alt 2. Mär 2015, 09:56
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?
Gruss Otto
Wenn du mit Gott reden willst, dann bete.
Wenn du ihn treffen willst, schreib bei Tempo 220 eine SMS
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#4

AW: Modales Fenster in DLL, Taskleiste

  Alt 2. Mär 2015, 13:57
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 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

Geändert von Dalai ( 2. Mär 2015 um 17:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#5

AW: Modales Fenster in DLL, Taskleiste

  Alt 17. Mär 2015, 15:41
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 inherited Create; . AFAIK sollte man es ja vermeiden, vor dem inherited eines Konstruktors irgendwas anderes zu machen.

MfG Dalai
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#6

AW: Modales Fenster in DLL, Taskleiste

  Alt 17. Mär 2015, 15:58
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
42
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#7

AW: Modales Fenster in DLL, Taskleiste

  Alt 17. Mär 2015, 16:22
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
  Mit Zitat antworten Zitat
Edelfix

Registriert seit: 6. Feb 2015
Ort: Stadtoldendorf
213 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Modales Fenster in DLL, Taskleiste

  Alt 17. Mär 2015, 20:04
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?
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#9

AW: Modales Fenster in DLL, Taskleiste

  Alt 17. Mär 2015, 20:45
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
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#10

AW: Modales Fenster in DLL, Taskleiste

  Alt 18. Mär 2015, 15:54
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. override; kann ich ja nicht verwenden, weil die Methode eine andere Signatur hat.

MfG Dalai
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:23 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