Einzelnen Beitrag anzeigen

Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#91

Re: Übersetzung Class MagneticWindow

  Alt 15. Okt 2006, 01:30
Habe gerade den Tab hier im FF entdeckt.
Unions code lässt sich ziemlich easy in eine Komponente werfen, die man dan auf ein Form ziehen kann.
Habe das eben mal durchprobiert und es geht eigentlich...
Delphi-Quellcode:
unit uFormMagnet;

interface

uses
  Classes, Forms, Messages, Windows;

type
  TFormMagnet = class(TComponent)
  private
    fPreviousLocation : TPoint;
    fParentsOldWinProc : TWndMethod;
    fParent : TCustomForm;
  protected
    procedure WindowProcHandler(var message: TMessage); virtual;

    procedure OnMove(var msg: TWMMove); message WM_MOVE;
  public
    property Parent : TCustomForm read fParent;
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
  end;

implementation
uses
  Types;

{ TFormMagnet }

procedure TFormMagnet.AfterConstruction;
begin
  inherited;

  if Owner is TCustomForm then
  begin
    fParent := TCustomForm(Owner);
    fParentsOldWinProc := Parent.WindowProc;
    Parent.WindowProc := WindowProcHandler;
    
    fPreviousLocation := Point(Parent.Left, Parent.Top);
  end;
end;

procedure TFormMagnet.BeforeDestruction;
begin
  inherited;

  if Assigned(fParentsOldWinProc) then
    Parent.WindowProc := fParentsOldWinProc;
end;

procedure TFormMagnet.WindowProcHandler(var message: TMessage);
begin
  if message.Msg = WM_MOVE then
    OnMove(TWMMove(message));

  if Assigned(fParentsOldWinProc) then
    fParentsOldWinProc(TMessage(message));
end;

procedure TFormMagnet.OnMove(var msg: TWMMove);
var
   i : Integer;
   form : TCustomForm;
begin
  for i := 0 to Screen.FormCount - 1 do
  begin
    form := Screen.Forms[i];

    if form <> Parent then
    begin
      // Differenz zwischen alter und neuer Position ebenfalls
      // auf die anderen Fenster anwenden

      form.Top := form.Top + (Parent.Top - fPreviousLocation.y);
      form.Left := form.Left + (Parent.Left - fPreviousLocation.x);
    end;
  end;

  fPreviousLocation := Point(Parent.Left, Parent.Top);
end;

end.
Natürlich ist es Blödsinn das ganze von der Seite aufzuwickeln.
Eigentlich sollte derjenige, der sich an ein Fenster gedockt hat, sich in dessen MessageLoop klinken und mitbewegen und beim Abdocken wieder herausklinken.
Die simple Lösung oben würde schon bei einem 2. Form mit der Komponente drauf oder eine weitere auf der gleichen Form aus den Fugen geraten.
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat