![]() |
Eigenes globales Andockprogramm - Warum flimmert es?
Liste der Anhänge anzeigen (Anzahl: 1)
Hi ich hab ein Programm angefangen, dass das Fenster, das den Focus hat an den Bildschirmrand andocken soll. An den Rändern klappt es schon, aber will ich es in die Ecke verschieben, dann
"flimmert" es, er verändert seine Position also immer sehr schnell. Bein manchen Fenstern wird die Breite verändert, was ich ebenfalls nicht verstehe. Hier der QT
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var hWindow: HWnd; r: TRect; begin if checkbox1.Checked = false then exit; hWindow := GetForegroundWindow; GetWindowRect(hWindow, r); //Linker Rand if (r.Left <= spinedit1.Value) AND (r.Left >= -spinedit1.Value) then MoveWindow(hwindow,0,r.Top,screen.Width-r.left-(screen.Width-r.right),screen.Height-r.top-(screen.Height-r.Bottom),True); //Rechter Rand if (r.Right >= (screen.Width-spinedit1.Value)) AND (r.Right <= (screen.Width + spinedit1.Value)) then MoveWindow(hwindow,screen.Width-(screen.Width-r.left-(screen.Width-r.right)),r.Top,screen.Width-left-(screen.Width-r.right),screen.Height-r.top-(screen.Height-r.Bottom),True); //Oben if (r.Top <= spinedit1.Value) AND (r.Top >= -spinedit1.Value) then Movewindow(hwindow,r.Left,0,screen.Width-r.left-(screen.Width-r.right),screen.Height-r.top-(screen.Height-r.Bottom),True); //Unten if (r.Bottom >= (screen.height-spinedit1.Value)) AND (r.Bottom <= (screen.Height + spinedit1.Value)) then MoveWindow(hwindow,r.Left,screen.Height-(screen.Height-r.top-(screen.Height-r.bottom)),screen.Width-left-(screen.Width-r.right),screen.Height-r.top-(screen.Height-r.Bottom),True); end; |
Re: Eigenes globales Andockprogramm - Warum flimmert es?
Hallo MisterNiceGuy,
also dein Programm macht bei mir ueberhaupt nichts. Ich hab kurz ein Form gesehn, und das war anschliessend auch schon wieder weg. Der Prozess war nachher auch nicht mehr da. Eventuell solltest du mal sehn was da los ist. Greetz alcaeus |
Re: Eigenes globales Andockprogramm - Warum flimmert es?
Zitat:
dieses Phänomen kann ich bestätigen. Vielleicht kannst Du uns etwas mehr Source zur Verfügung stellen - der Fehler liegt wohl wo anders. mfG mirage228 |
Re: Eigenes globales Andockprogramm - Warum flimmert es?
Also wenn mir in einem Delphi-vs-C++-Flameware nochmal irgendjemand mit dem Argument "Delphicode ist viel übersichtlicher" ankommen sollte, kriegt er diesen Link hier rechts und links um die Ohren gehauen :mrgreen:
So, schau'n mer ma', wat det hier iss. Man nehme an, du willst das Fenster oben links andocken und es befindet sich gerade im Schwellwertbereich.
Delphi-Quellcode:
Also ich weiß ja nicht, wie oft dein Timer aufgerufen wird, aber wenn du mehrere Mal pro Sekunde die Position auf zwei völlig verschiedene Werte setzt, meinst du da nicht auch, daß es flackert? :zwinker:
hWindow := GetForegroundWindow;
GetWindowRect(hWindow, r); { Hier ist in r also die Position des Fensters, noch mit kleinem Rand nach oben und nach links. } //Linker Rand if (r.Left <= spinedit1.Value) AND (r.Left >= -spinedit1.Value) then MoveWindow(hwindow,0,r.Top, { Die neue X-Position ist 0, die Y-Position bleibt so. Erstma nix falsches. } //Oben if (r.Top <= spinedit1.Value) AND (r.Top >= -spinedit1.Value) then Movewindow(hwindow,r.Left,0 { Nanu, r.Left enthält doch nicht 0. Hier setzt du die X-Position also wieder etwas vom Rand weg, dafür aber die Y-Position auf 0. } By the way: 'n Hook auf WM_MOVING wäre vielleicht etwas eleganter als ein Timer, der sich jedes Mal das Fenster zu Fuß holt. Ich habe das damals mal für eigene Fenster geschrieben, die an anderen Fenstern der gleichen Anwendung andocken sollten. Dabei habe ich das in lParam enthaltene Rect solange verändert, bis es mir gefiel und dann an die Message zurückgegeben. Windows hat davon also mehr oder weniger gar nichts mitgekriegt, und geflimmert hat's daher auch nicht ;-) |
Re: Eigenes globales Andockprogramm - Warum flimmert es?
Hi also erstmal hab ich das noch ein bisschen übersichtlicher gemacht indem ich die Breite und Höhe des Fensters vorher zu berechne.
Delphi-Quellcode:
@mirage228: Das ist der ganze Code, der Rest ist nur noch das Schließen der Form.
procedure TForm1.Timer1Timer(Sender: TObject);
var hWindow : HWnd; r : TRect; Breite : Integer; Hoehe : Integer; begin //Wenn nicht aktiviert, dann verlasse if checkbox1.Checked = false then exit; //Holfe Handle und Position des aktiven Fensters hWindow := GetForegroundWindow; GetWindowRect(hWindow, r); //Berechnen von Breite und Höhe Breite := screen.Width-r.left-(screen.Width-r.right); Hoehe := screen.Height-r.top-(screen.Height-r.Bottom); //Linker Rand if (r.Left <= spinedit1.Value) AND (r.Left >= -spinedit1.Value) then MoveWindow(hwindow,0,r.Top,Breite,Hoehe,True); //Rechter Rand if (r.Right >= (screen.Width-spinedit1.Value)) AND (r.Right <= (screen.Width + spinedit1.Value)) then MoveWindow(hwindow,screen.Width-Breite,r.Top,Breite,Hoehe,True); //Oben if (r.Top <= spinedit1.Value) AND (r.Top >= -spinedit1.Value) then Movewindow(hwindow,r.Left,0,Breite,Hoehe,True); //Unten if (r.Bottom >= (screen.height-spinedit1.Value)) AND (r.Bottom <= (screen.Height + spinedit1.Value)) then MoveWindow(hwindow,r.Left,screen.Height-Hoehe,Breite,Hoehe,True); end; @alcaeus: Tut mir leid, das kann ich absolut nicht nachvollziehen. @Tommie-lie: Wieso wird r noch ein kleiner Rand nach oben und links angehängt??? Das wusste ich nicht. P.S. Darauf, dass ich lParam verändern muss hab ich schon rausgefunden, aber mir hat keiner sagen können wie ich das mache, deswegen bin ich auf die Timermethode umgestiegen. |
Re: Eigenes globales Andockprogramm - Warum flimmert es?
Zitat:
Zitat:
Delphi-Quellcode:
Du siehst, lParam enthält den Pointer und ich ändere das Rect, was dahinter ist, und kehre dann einfach zurück. Windows bearbeitet dann die WM_MOVING-Message weiter, und zwar mit den von mir korrigierten Werten, als ob nichts gewesen ist.
type
TfrmPlaylist = TForm... private LastPosition: TRect; RealPosition: TRect; Position: PRect; procedure FormMoving(var Message: TMessage); message WM_MOVING; end; procedure TfrmPlaylist.FormMoving(var Message: TMessage); begin Position := PRect(Message.lParam); // tracking of the window's real position RealPosition.Left := RealPosition.Left + (Position.Left - LastPosition.Left); RealPosition.Top := RealPosition.Top + (Position.Top - LastPosition.Top); RealPosition.Right := RealPosition.Left + Width; RealPosition.Bottom := RealPosition.Top + Height; // make changes from the last event undone Position.Top := RealPosition.Top; Position.Left := RealPosition.Left; DockingSite := dsNone; // do we have to do something? if RectIntersect(frmMain.RealPosition, RealPosition, 20) then begin // first we look at the single edges if Abs(RealPosition.Left - (frmMain.RealPosition.Right)) <= 20 then begin Position.Left := frmMain.RealPosition.Right; DockingSite := dsVertEdge; end; if Abs(RealPosition.Top - (frmMain.RealPosition.Bottom)) <= 20 then Position.Top := frmMain.RealPosition.Bottom; DockingSite := dsHorzEdge; end; if Abs(RealPosition.Right - (frmMain.RealPosition.Left)) <= 20 then begin Position.Left := frmMain.RealPosition.Left - Width; DockingSite := dsVertEdge; end; if Abs(RealPosition.Bottom - (frmMain.RealPosition.Top)) <= 20 then begin Position.Top := frmMain.RealPosition.Top - Height; DockingSite := dsHorzEdge; end; // Eigentlich kamen hier noch andere Feinheiten, die aber nix mit dem Problem zu tun hatten. Eye candy also ;-) // Am Ende wird natürlich noch die Größe des Rects an mein Fenster angepasst, weil ich nur die Top/Left-Werte verändere end; end; |
Re: Eigenes globales Andockprogramm - Warum flimmert es?
Was ist den PRect für ein Typ? Die DelphiHilfe kennt das nicht. Ich habs jetzt so gelöst, dass ich nach jedem Andocken die Werte der Applikation erneut abfrage.
Jetzt wüsste ich gerne noch, wie ich die Windowsmessage hooke. WM_MOVING oder WM_POSITIONCHANGED ist bestimmt am besten, nur wie mache ich das? |
Re: Eigenes globales Andockprogramm - Warum flimmert es?
Zitat:
Mag sein, daß es nicht in der Hilfe steht, aber es sollte in den Stnadard-Units deklariert sein. Zitat:
![]() ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:27 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