AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Eigenes globales Andockprogramm - Warum flimmert es?
Thema durchsuchen
Ansicht
Themen-Optionen

Eigenes globales Andockprogramm - Warum flimmert es?

Ein Thema von MisterNiceGuy · begonnen am 15. Mai 2005 · letzter Beitrag vom 16. Mai 2005
Antwort Antwort
Benutzerbild von MisterNiceGuy
MisterNiceGuy

Registriert seit: 1. Jul 2003
Ort: Mannheim
919 Beiträge
 
Delphi 7 Personal
 
#1

Eigenes globales Andockprogramm - Warum flimmert es?

  Alt 15. Mai 2005, 21:42
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;
Angehängte Dateien
Dateityp: exe dssnap_419.exe (429,5 KB, 14x aufgerufen)
Jonas
Wenn mich jemand sucht, ich bin im Kühlschrank!

Informationen über das Duale Studium
www.jofre.de
  Mit Zitat antworten Zitat
Benutzerbild von alcaeus
alcaeus

Registriert seit: 11. Aug 2003
Ort: München
6.537 Beiträge
 
#2

Re: Eigenes globales Andockprogramm - Warum flimmert es?

  Alt 15. Mai 2005, 22:24
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
Andreas B.
Die Mutter der Dummen ist immer schwanger.
Ein Portal für Informatik-Studenten: www.infler.de
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#3

Re: Eigenes globales Andockprogramm - Warum flimmert es?

  Alt 16. Mai 2005, 07:40
Zitat von alcaeus:
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
Hi,

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
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)
  Mit Zitat antworten Zitat
tommie-lie
(Gast)

n/a Beiträge
 
#4

Re: Eigenes globales Andockprogramm - Warum flimmert es?

  Alt 16. Mai 2005, 08:40
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

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:
  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.
}
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?

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
  Mit Zitat antworten Zitat
Benutzerbild von MisterNiceGuy
MisterNiceGuy

Registriert seit: 1. Jul 2003
Ort: Mannheim
919 Beiträge
 
Delphi 7 Personal
 
#5

Re: Eigenes globales Andockprogramm - Warum flimmert es?

  Alt 16. Mai 2005, 09:20
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:
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;
@mirage228: Das ist der ganze Code, der Rest ist nur noch das Schließen der Form.

@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.
Jonas
Wenn mich jemand sucht, ich bin im Kühlschrank!

Informationen über das Duale Studium
www.jofre.de
  Mit Zitat antworten Zitat
tommie-lie
(Gast)

n/a Beiträge
 
#6

Re: Eigenes globales Andockprogramm - Warum flimmert es?

  Alt 16. Mai 2005, 09:41
Zitat von MisterNiceGuy:
@Tommie-lie: Wieso wird r noch ein kleiner Rand nach oben und links angehängt??? Das wusste ich nicht.
Es wird kein Rand angehangen. Aber r ist doch die Position des Fensters, bevor du sie änderst. Es enthält also das Fenster mit kleinem Rand zum linken und oberen Bildschirmrand, denn r änderst du ja später nicht mehr. Wenn nur eine der if-Abfragen durchlaufen wird, stimmt alles. Sobald du aber zwei if-Abfragen durchläufst, benutzt du beim ersten Mal r, beim zweiten Mal aber auch, und dadurch änderst du die Position zweimal auf zwei unterschiedliche Werte, das Fenster springt also hin und her. Und das ist vermutlich, was du als Flackern wahrnimmst.

Zitat von MisterNiceGuy:
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.
Ich hab' mal den Quellcode rausgekramt:
Delphi-Quellcode:
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;
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.
  Mit Zitat antworten Zitat
Benutzerbild von MisterNiceGuy
MisterNiceGuy

Registriert seit: 1. Jul 2003
Ort: Mannheim
919 Beiträge
 
Delphi 7 Personal
 
#7

Re: Eigenes globales Andockprogramm - Warum flimmert es?

  Alt 16. Mai 2005, 09:52
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?
Jonas
Wenn mich jemand sucht, ich bin im Kühlschrank!

Informationen über das Duale Studium
www.jofre.de
  Mit Zitat antworten Zitat
tommie-lie
(Gast)

n/a Beiträge
 
#8

Re: Eigenes globales Andockprogramm - Warum flimmert es?

  Alt 16. Mai 2005, 10:42
Zitat von MisterNiceGuy:
Was ist den PRect für ein Typ?
Ein Pointer auf ein TRect: PRect = °TRect;
Mag sein, daß es nicht in der Hilfe steht, aber es sollte in den Stnadard-Units deklariert sein.

Zitat von MisterNiceGuy:
Jetzt wüsste ich gerne noch, wie ich die Windowsmessage hooke.
Hier im Forum suchenhook und im Zweifelsfall http://www.assarbad.org
  Mit Zitat antworten Zitat
Antwort Antwort


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 11:33 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