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.