![]() |
Fenster einer DLL in den Vordergrund
Hallo zusammen!
Habe das Problem, dass ich aus meiner Applikation aus in einer bestimmten Routine eine DLL starte. In der Applikation ist ein weiteres Fenster geöffnet und wird somit als inaktives Fenster gekennzeichnet. Alles schön und gut. Jetzt wird in der DLL ein anderes Fenster geöffnet und hier ist das Problem. Das Fenster ist zwar aktiv, aber es läßt sich nicht mit den Befehlen "BringToFront()" oder "SetForeGroundWindow()" in den Vordergrund setzen. Ebenso ist das bei Messages die dann im Hintergrund sind. :wall: Ich hoffe mir kann da jemand weiterehelfen. Gruß, moony |
Re: Fenster einer DLL in den Vordergrund
poste bitte mal den code der dll wo das fenster erzeugt und angezeigt wird
|
Re: Fenster einer DLL in den Vordergrund
Die DLL wird statisch aus der Applikation aus aufgerufen und nach Rückgabe des Wertes direkt wieder freigegeben:
Delphi-Quellcode:
Das Fenster wird ja dann normal mit dem Laden der DLL erzeugt. Aufgerufen wird das Fenster hier:
function DLLLaden(dllname, functionname: String):Boolean;stdcall;export;
type Tcustfunction=function (var Names,Values:pchar):boolean;stdcall; var cfunction : tcustfunction; custhdl : Thandle; Func : TFarProc; begin ... custhdl := LoadLibrary(PChar(extractfilepath(application.exename) + dllname)); custfunc := GetProcAddress(custhdl,pchar(functionname)); if custfunc <> nil then begin @cfunction := custfunc; result:=true; end else begin result := false; FreeLibrary(custhdl); exit; end; result := cfunction(...,...); FreeLibrary(custhdl); ... end;
Delphi-Quellcode:
dann...
Procedure DLL.FormShow();
begin ... Fenster.ShowModal; if Fenster.ModalResult := mrCancel then Exit; ... end;
Delphi-Quellcode:
Ich hoffe das kann dir weiterhelfen. Das sind die wichtigsten Aufrufe.
Procedure Fenster.FormShow();
begin Fenster.BringToFront; end; gruß, moony |
Re: Fenster einer DLL in den Vordergrund
Nach meinem Wissensstand muss ich dich leider enttäuschen: So geht es nicht. Scheinbar liegt es daran, das das Eltern-Fenster sein "neues Kind" nicht als VCL-Fenster anerkennt und es deshalb auch nicht so behandelt. Du könntest eventuell versuche, das Kind-Fenster als Objekt zu übergeben und es von den Eltern erzeugen zu lassen (wie das in Natur ebenfalls gemacht wird :stupid: )
|
Re: Fenster einer DLL in den Vordergrund
Verstehe ich nich! :gruebel:
Es wird doch in der Applikation Fenster1 über ShowModal geöffnet. Während das Fenster1 gezeigt wird, wird von der Applikation eine DLL statisch geladen. In der DLL wird das Fenster2 als Übergang aufgerufen. In diesem Fenster2 wird ein weiteres Fenster3 aufgerufen. Das kann doch nicht so schwer sein die Fenster aus der DLL in den Vordergrund bringen zu können. Fenster1 hat ja überhaupt keine Ahnung davon dass es Fenster2 & Fenster3 gibt. |
Re: Fenster einer DLL in den Vordergrund
Vielleicht kann ich ja nur nicht richtig lesen, aber wo wird in dem Code denn überhaupt das Fenster erzeugt?
|
Re: Fenster einer DLL in den Vordergrund
Die Fenster von der Applikation werden beim Starten der Applikation unter
Delphi-Quellcode:
erstellt.
begin
... Applikation.CreateFrom(TFenster1, Fenster1); ... end. Die Fenster werden von der DLL unter
Delphi-Quellcode:
erstellt.
begin
... Applikation.CreateFrom(TFenster2, Fenster2); Applikation.CreateFrom(TFenster3, Fenster3); ... end. Also wird das Erstellen der Formen von der Applikation und DLL selbst übernommen. |
Re: Fenster einer DLL in den Vordergrund
Du schreibst, die DLL wäre statisch eingebunden. Trotzdem lädst du sie mit LoadLibrary und gibst sie sogar anschließend wieder frei. Eins von beidem geht doch aber nur.
Wo genau ist der Aufruf, der das Fenster anzeigen soll? Passiert das in irgendeiner Art und Weise in der cfunction? |
Re: Fenster einer DLL in den Vordergrund
Hallo Moony,
Du kannst deiner Funktion den Application Handle übergeben:
Delphi-Quellcode:
Der Aufruf aus der Anwendung sollte so aussehen:
type Tcustfunction=function (AHandle: THandle; var Names,Values:pchar):boolean;stdcall;
Delphi-Quellcode:
In der DLL die Funktion custfunction ändern:
result := cfunction(Application.Handle,...,...);
Delphi-Quellcode:
hoffe, das hilft dir weiter.
Application.Handle := AHandle;
Gruß, Ianis |
Re: Fenster einer DLL in den Vordergrund
Hast du es eigentlich schonmal mit Form2.Perform versucht? Ihm also quasi eine Message "vorgegaukelt"?
|
Re: Fenster einer DLL in den Vordergrund
Also,
@tigerman: wenn du das so siehst, dann wird die DLL dynamisch eingebunden. Ich versuche das ganze Verfahren noch mal zu erläutern: Das Fenster1, welches im Vordergrund bleibt, wird irgendwann von der Applikation aus mit Show() aufgerufen. Im weiteren Verlauf, also solange das Fenster1 noch gezeigt wird, wird dann die DLL geladen. In der DLL wird über ein Hilfsfenster Fenster2 (ist uninteressant) das Fenster3 in der Fenster2.FormShow() über die Funktion Fenster3.ShowModal() aufgerufen. Nun wird in der Funktion Fenster3.OnShow() dieses Fenster in den Vordergrund gestellt mit Fenster3.BrintToFront(). Aber das macht er nicht! Alle Fenster werden jeweils in den DPR-Files zu Beginn erstellt mit Application.CreateFrom(TForm, Form). Als zusätzliche Info: Das passiert ja nicht nur bei Fenstern. Auch wenn ich in einer DLL eine Message ausgebe ist diese dann auch im Hintergrund und man denkt die Applikation ist abgeschmiert, weil ja nichts passiert. Die Message aber ist hinter dem Fenster1. @Ianis: Die Sache mit der Handleübergabe funktioniert auch nicht. :( gruß, moony |
Re: Fenster einer DLL in den Vordergrund
Sehr rätselhaft. Hast du schonmal probiert Fenster2 und/oder Fenster3 nicht automatisch am Anfang erzeugen zu lassen, sondern von Hand, dynamisch zu erzeugen?
Zitat:
|
Re: Fenster einer DLL in den Vordergrund
Fenster2 ist ja total irrelevant, da dieses Fenster nur Mittel zum Zweck ist und dort verwendete KADAO Komponenten gelagert werden. Fenster3 wird ja in der Fenster2.OnShow aufgerufen. Dort habe ich auch versucht dann erst Fenster3 mit
Delphi-Quellcode:
zu erstellen und bei der Fenster3.OnClose() das Fenster wieder mit
Fenster3 := TFenster3.Create(Fenster3);
Delphi-Quellcode:
freizugeben. Aber irgendwie will mich hier jemand ärgern. Wie gesagt, das Problem besteht nicht nur bei Fenstern sondern auch bei popeligen Showmessages. Die lassen sich auch nicht in den Vordergrund setzen!
Fenster3.Release;
Ich glaub das ist hoffnungslos.... :cry: Was dein Verständnis von Fenster1 betrifft, NEIN das Fenster soll nicht im Vordergrund bleiben. Das ist ja mein Problem. Es bleibt nämlich im Vordergrund, obwohl das Fenster ja in diesem Moment inaktiv ist. |
Re: Fenster einer DLL in den Vordergrund
Es würde helfen, wenn du nochmal ein bisschen mehr vom Code posten würdest. Vor allem dem, was in der DLL steht.
|
Re: Fenster einer DLL in den Vordergrund
So wirklich viel mehr bringt es nicht zu posten, da das Programm bereits zu komplex aufgebaut ist und viel zu viele Ereignisse durchgeführt werden. Aber ich versuche es ein wenig übersichtlicher zu gestalten:
In der Applikation sieht das ganze so aus: In der Projektdatei werden die Formulare erstellt:
Delphi-Quellcode:
Anschließend wird beim klicken auf eine Schaltfläche das Fenster1 aufgerufen:
Projekt.dpr
uses ... begin Application.Initialize; ... // Erstellung des Fenster1 zur Laufzeit Application.CreateForm(TFenster1, Fenster1); ... Application.Run; end.
Delphi-Quellcode:
Innerhalb der DLL wird dann folgendermaßen verfahren:
unit Applikation;
... procedure Schaltfläche.OnClick(); type TmyFunc = function :boolean;stdcall; var CustFunc : TFarProc; CustHdl : THandle; myFunc : TmyFunc; DllName, Funktion : String; begin ... // Das Fenster der Applikation wird geöffnet Fenster1.Show; ... // Dynamischer Aufruf der DLL CustHdl := LoadLibrary(PChar(extractfilepath(application.exename) + DLLName)); CustFunc := GetProcAddress(CustHdl, PChar(Function)); if CustFunc <> nil then begin @myFunc := CustFunc; Result := myFunc; end; // DLL wieder freigeben FreeLibrary(CustHdl); end;
Delphi-Quellcode:
Innerhalb der geladenen DLL wird das Hauptfenster Fenster2 geöffnet. Hier wird in der Prozedur Fenster2.FormShow() der folgende Aufruf getätigt:
library DLLName;
uses ... begin Application.initialize; Application.CreateForm(TFenster2, Fenster2); Application.CreateForm(TFenster3, Fenster3); end.
Delphi-Quellcode:
Anschließend wird in der Prozedur Fenster3.FormShow() der folgende Aufruf gesetzt:
unit Fenster2;
... procedure Fenster2.FormShow(); begin ... Fenster3.ShowModal; if Fenster3.ModalResult = mrCancel then Exit; ... end;
Delphi-Quellcode:
So ist der Stand wie zu Anfang beschrieben. Jedoch bringt das ja nicht.
unit Fenster3;
... procedure Fenster3.FormShow(); begin Fenster3.BringToFront; end; Habe ebenfalls versucht die Fenster2/3 dynamisch zu erstellen, das hat aber auch nichts gebracht. Ich hatte zuerst gedacht das geht, aber nach der nächsten Kompillierung wurden alle Fenster wieder hinter Fenster1 gesetzt. Showmessages zeigen den gleichen Effekt wie Fenster2 & 3, nämlich dass sie hinter dem Fenster1 bleiben und nicht im Vordergrund gezeigt werden können. Sehr blöd, wenn die Message kleiner als das Fenster1 ist. So, hoffe jetzt ist das übersichtlicher und eine Lösung findet sich. gruß, moony |
Re: Fenster einer DLL in den Vordergrund
Steht die Application-Variable denn innerhalb einer DLL überhaupt zur Verfügung? Die DLL könnte ja von mehreren Anwendungen gleichzeitig benutzt werden, auf welche davon verweist dann Application? Ich vermute mal, dass die DLL eine eigene Application-Variable hat. Wenn hierfür nun Fenster erstellt werden und deine Haupt-Anwendung gerade den Fokus hat, sind diese DLL-Fenster natürlich im Hintergrund.
Versuch doch mal, die Fenster explizit in einer Prozedur zu erstellen, der du die Application-Variable der Hauptanwendung übergibst. Mit dieser erstellst du dann die Fenster. (Oder du machst es gleich mit TFenster2.Create(Fenster1) ) Funktioniert das? |
Re: Fenster einer DLL in den Vordergrund
Zitat:
Zitat:
Zitat:
Zitat:
Eigenständig erstellt hab ich diese auch, hat aber recht wenig genutzt. Zumindest hat er das beim ersten Kompillieren nach vorne gesetzt und bei jedem weiteren nicht mehr. Zitat:
Das ist doch alles nicht wahr. :wall: Es muß doch eine Möglichkeit geben diese dämlichen Fenster in den Vordergrund zu setzen. Und vor allem kann es ja nicht an dem Aufruf der Fenster liegen, weil normale Showmessages ebenfalls im Hintergrund bleiben! |
Re: Fenster einer DLL in den Vordergrund
Du hast mich ein wenig falsch verstanden.
Dass das gleichzeitige Benutzen einer DLL durch mehrere Programme eine Schutzverletzung zur Folge haben soll ist mir neu. Wieso sollte das so sein? Dass die Application-Variable innerhalb der DLL eine andere ist als innerhalb der Applikation hatte ich vermutet (die meisten meiner Fragen waren eher rethorischer Natur). Deswegen ja auch mein Vorschlag:
Delphi-Quellcode:
Das ist untested, aber ich erhoffe mir davon, dass es das Problem löst, da die beiden Fenster von der Anwendung erzeugt werden, die auch tatsächlich gerade den Fokus hat, und nicht von der DLL selbst.
// In der DLL:
procedure CreateFenster(const AnAplication: TApplication); begin AnApplication.CreateForm (TFenster2, Fenster2); AnApplication.CreateForm (TFenster3, Fenster3); end; // Dann Aufruf aus dem Hauptprogramm: CreateFenster (Application); |
Re: Fenster einer DLL in den Vordergrund
Hallo,
hab das jetzt anders gelöst. die Form, welche in der ersten Applikation immer im Vordergrund ist, war auf StayOnTop gesetzt. Es hatte auch einen bestimmten Grund, aber ich habs jetzt entfernt. Danke für alles. Gruß, Moony |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:07 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