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 Problem: SetWindowPos (https://www.delphipraxis.net/91594-problem-setwindowpos.html)

Z32 7. Mai 2007 14:55


Problem: SetWindowPos
 
Hallo,

Ich habe ein Problem mit der Formstyle bei meinem Project. Und zwar möchte ich nur, dass man in einem extra Fenster in meinem Programm die Einstellung vornehmen kann: "Fenster immer im Vordergrund" oder "Fenster Normal". Dazu benutze ich eine Checkbox.

Der Code für die Checkbox sieht so aus und liegt auf dem "Übernehmen" Button:

Delphi-Quellcode:
if checkbox1.checked=true then
begin
  SetWindowPos(Form1.Handle ,HWND_TOPMOST,0,0,0,0,SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
  showmessage('Die Anwendung ist nun im Vordergrund');
end
else
begin
  SetWindowPos(Form1.Handle ,HWND_NOTOPMOST,0,0,0,0,SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
  showmessage('Die Anwendung ist nun wieder im Hintergrund');
end;
So, jetzt zu meinem Problem.
Ich kann meine Anwendung in den Vordergrund bringen, das klappt. Aber wenn ich den Haken wieder aus der Checkbox rausnehme, geht die Anwednung nicht wieder in den Hintergrund zurück. Besser gesagt, die Anwednung geht nur solange in den Hintergrund, wie das Einstellungsfenster offen ist. Sobald ich das Einstellungsfenster wieder schließe, geht die Anwednung wieder in den Vordergrund.

Ich habe den Code schon hudertmal durchgeguckt, ich finde keine Stelle die sowas verursachen könnte. Außerdem kann ich meine Anwednung ja in den Vordergrund bringen, und das Einstellungsfesnter dann schließen, ohne dass die Anwendung wieder in den Hintergrund geht.

Was stimmt da nicht :gruebel:

daddy 8. Mai 2007 08:42

Re: Problem: SetWindowPos
 
Beim Ablegen in den Hintergrund solltest Du nicht HWND_NOTOPMOST sondern HWND_BOTTOM senden, damit sollte es funktionieren.

Gruß

Daddy

Z32 9. Mai 2007 15:15

Re: Problem: SetWindowPos
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

Ich fummel da jetzt schon etwas länger dran rum. Solangsam weiß ich nicht mehr woran es noch liegen kann. Der Tipp mit hwnd_bottom hat leider auch nichts geändert.

Deshalb habe ich jetzt mal ein Miniprojekt geschrieben mit zwei Forms. Vom Form2 aus, soll man steuern können, ob Form1 im Vordergrund oder halt "normal" ist.

Das Problem war ja, dass die Anwendung nur in den Vordergrund kommt, aber nicht wieder zurück.

Währe echt super nett, wenn wer mal gucken könnte, wo ich das das Brett vorm Kopf habe. :wall:

Schonmal danke fürs gucken... :thumb:

bitsetter 9. Mai 2007 17:46

Re: Problem: SetWindowPos
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,

das Verhalten ist wirklich eigenartig, es hängt anscheinend mit
Delphi-Quellcode:
form2.ShowModal
zusammen.

Wenn man
Delphi-Quellcode:
form2.Show
aufruft funktioniert alles bestens.

Den Code habe ich jetzt mal hinter
Delphi-Quellcode:
form2.ShowModal;
gesetzt dann funktioniert es anscheinend. Der Code wird ja erst aufgerufen wenn das 2. Fenster wieder geschlossen wird.

Guido Eisenbeis 10. Mai 2007 03:54

Re: Problem: SetWindowPos
 
Hallo Marvin.

Zitat:

Zitat von Z23
Der Tipp mit hwnd_bottom hat leider auch nichts geändert.

Das stimmt soweit. HWND_NOTOPMOST ist in diesem Fall schon richtig.

Zitat:

Zitat von Z23
Ich fummel da jetzt schon etwas länger dran rum. Solangsam weiß ich nicht mehr woran es noch liegen kann.

Tja, wo soll ich anfangen? :gruebel: Das liegt unter anderem daran, dass für die Mainform andere Regeln gelten, dass es ein unsichtbares Fenster für die Application gibt, dass die Application als Mama auf ihre Kinderchen aufpasst und ihnen sagt was sie tun sollen, auch wenn Marvin was anderes sagt, am Wetter :wink: und was weiß ich noch.

Deshalb spielt auch das ShowModal eine Rolle, wie bitsetter sagte. (Hier ein Gruß an bitsetter, der mir schon öfter wertvolle Hilfe geleistet hat!)

Da du ein Demoprojekt angehängt hast, hab ich mir die Sache auch angesehen. :-D Ist nämlich wirklich ein komplexes Thema mit diesem Topmost. Eine mögliche Lösung ist die Verwendung von "Mamas" (Application) NormalizeAllTopMosts:

Delphi-Quellcode:
if checkbox1.Checked=true then
begin
  SetWindowPos(Form1.Handle, HWND_TOPMOST, 0, 0, 0, 0,
    SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
  showmessage('Form1 ist nun im Vordergrund');
end
else
begin
  SetWindowPos(Form1.Handle, HWND_NOTOPMOST, 0, 0, 0, 0,
    SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
  showmessage('Form1 ist nun nicht mehr im Vordergrund');
end;

Application.NormalizeAllTopMosts;
Mögliche Nebenwirkungen musst du selbst abchecken!

Gruß,
Guido.


Edit: NormalizeTopMosts ersetzt durch NormalizeAllTopMosts = incl. Mainform.

daddy 10. Mai 2007 09:51

Re: Problem: SetWindowPos
 
Hallo Z32,

Also das Problem ist relativ einfach lösbar. Du darfs Deinen Befehl zur Veränderung des Fensters nicht in FORM2 ausführen, da ja anschließend FORM1 realktiviert wird, wenn Du Form2 schließt und dadurch automatisch wieder in den Vordergrund gelangt. Stattdessen musst Du in FORM2 letztendlich gar nichts machen und in FORM1 den Code wie folgt ändern:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var L, T : Integer;
begin
  L := Left;
  T := Top;
  Form2.ShowModal;
  if Form2.CheckBox1.Checked then
    SetWindowPos(Form1.Handle,HWND_TOPMOST,L,T,0,0,SWP_NOSIZE)
  else SetWindowPos(Form1.Handle ,HWND_BOTTOM,L,T,0,0,SWP_NOSIZE);
end;
L und T habe ich eingeführt, damit die Position von FORM1 erhalten bleibt

Gruß Daddy

teebee 10. Mai 2007 10:23

Re: Problem: SetWindowPos
 
Zitat:

Zitat von daddy
L und T habe ich eingeführt, damit die Position von FORM1 erhalten bleibt

Dafür gibt es doch SWP_NOMOVE :wink:

daddy 10. Mai 2007 11:06

Re: Problem: SetWindowPos
 
@teebee

Stimmt :) , das funktionierte bei dem vorgegebenen Formular aber nicht. Vermutlich, weil es im Design-Modus oben links lag und die Eigenschaft "Position" auf "poScreenCenter" stand. Das habe ich aber nicht näher untersucht.

Gruß Daddy

Z32 10. Mai 2007 12:35

Re: Problem: SetWindowPos
 
Ah...Vielen Dank für die viele Hilfe :-D

Da werd ich mich doch direkt an die Arbeit machen.

Ich weiß nur noch nicht genau für welche Lösung ich mich entscheiden soll.

Die von Daddy verstehe ich ein bisschen besser, deshalb werde ich glaube ich erst mal die probieren.

Aike 10. Mai 2007 13:00

Re: Problem: SetWindowPos
 
Wenn du aus dem Hauptformular ein Fenster mit "ShowModal" aufrufst, ist das im Vordergrund und kein anderes Fenster lässt sich anklicken (von deinem Programm). Show zeigt nur einfach das andere Formular, lässt aber Klicks auf andere Formularfenster zu.

Ich benutze für das "In den Vordergrund setzen" (bzw. in den Hintergrund) diese Prozeduren:
Delphi-Quellcode:
procedure SetWindowPosToFront(handle:HWND);
begin
  SetWindowPos(Handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE);
end;

procedure SetWindowPosToBack(handle:HWND);
begin
  SetWindowPos(Handle,HWND_NOTOPMOST,0,0,0,0,SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
end;

//Aufruf:
procedure TForm1.Button1Click(Sender: TObject);
begin
  SetWindowPosToFront(self.Handle); //Setzt die Form1 in den Vordergrund
  SetWindowPosToBack(self.Handle); //Setzt die Form1 in den Hintergrund
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:55 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