Einzelnen Beitrag anzeigen

tommie-lie
(Gast)

n/a Beiträge
 
#6

Re: Eigenes globales Andockprogramm - Warum flimmert es?

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