Newsgroup: it.comp.lang.delphi
Titolo: snap form

Ciao a tutti!
Come faccio a fare in modo che alcune form siano snappabili tra di loro? Per
snappabili intendo che si "appoggino" come fa la prorprietà SCREENSNAP delle
form sui bordi dello schermo.
Grazie.

form sui bordi dello schermo.
Penso che non ci siano proprietà dei form che ti
permettano di ottenere questa funzionalità ...
Per ottenere un risultato del genere dovresti fare dei
conti sulle cordinate del form che vuoi "snappare"
rispetto ai form fissi ...
Per provare quanto detto ho scritto questa semplice
procedura che, certamente, può essere migliorata ma fa
quello che vuoi tu ...
procedure SnapForm(MovingForm, FixedForm: TForm;
  const Limit: Integer);
begin
  //Aggancia il MovingForm a destra del FixedForm
  //se il limite sinistro del MovingForm è più vicino di Limit
  //all'estremo destro del FixedFom
  If Abs(MovingForm.Left-(FixedForm.Left+FixedForm.Width))<Limit Then
    MovingForm.Left:=(FixedForm.Left+FixedForm.Width);
  //Aggancia il MovingForm al limite inferiore del FixedForm
  //se il limite superiore del MovingForm è più vicino di Limit
  //al limite inferiore del FixedFom
  If Abs(MovingForm.Top-(FixedForm.Top+FixedForm.Height))<Limit Then
    MovingForm.Top:=(FixedForm.Top+FixedForm.Height);
  //Sinistra ...
  If Abs(FixedForm.Left-(MovingForm.Left+MovingForm.Width))<Limit Then
    MovingForm.Left:=(FixedForm.Left-MovingForm.Width);
  //Alto ...
  If Abs(FixedForm.Top-(MovingForm.Top+MovingForm.Height))<Limit Then
    MovingForm.Top:=(FixedForm.Top-MovingForm.Height);
end;
per provarla ho creato e reso visibili tre form: Form1,
form2, form3: poi ho settato la proprietà DockSite, del
form2, a true e la prorpietà GragKind a dkDock per
poter avere abilitato l'evento OnEndDock del form, in
questo evento ho scritto una chiamata a SnapForm per
ogni form a cui voglio agganciare il Form2 in questo
caso solo due: una per form1 e l'altra per form3 ...
procedure TForm2.FormEndDock(Sender, Target: TObject;
X, Y: Integer); begin
  SnapForm(Self,Form1,20);
  SnapForm(Self,Form3,20);
end;
il risultato è discreto ma questo codice implica che
ogni form da agganciare "veda" (uses) tutti i form a
cui si deve agganciare.
Per evitare questo brutto livello di information hiding
e indipendenza delle form, potresti dare, al form
principale, il compito di agganciare i vari form; in
questo modo è il form principale che divene il gestore
delle posizioni degli altri form; poi negli eventi
OnEndDock dei vari form da agganciare richiami un
metodo del formMain che esegue l'agganciamento mediante
la procedura SnapForm.
Il form principale diventerebbe una cosa del genere
  TForm1 = class(TForm)
  private
    { Private declarations }
    procedure SnapForm(MovingForm,FixedForm: TForm;Const Limit: Integer);
  public
    Procedure SnapFormToAtherForm(SenderForm: TForm);
  end;
[...]
procedure TForm1.SnapFormToAtherForm(SenderForm: TForm);
begin
  SnapForm(SenderForm,Self,20);
  If SenderForm = Form2 Then
    SnapForm(SenderForm,Form3,20);
  If SenderForm = Form3 Then
    SnapForm(SenderForm,Form2,20);
end;
e l'eveto EndDock dei from2, e Form3 diventerebbe
procedure TForm2.FormEndDock(Sender, Target: TObject; X, Y: Integer);
begin
  Form1.SnapFormToAtherForm(Self);
end;
in questa maniera solo il form principale (Form1) deve
vedere gli altri per agganciarli, mentre i secondari
(Form2, Form3) devono vedere solo il Form principale
(Form1).
Il tutto può essere migliorato ed ottimizzato con una
lista dei form secondare etc, etc ... ma già così
funziona :)
 >Grazie.
Spero di essere stato chiaro e di esserti di aiuto ...
soprattutto vista l'ora ;)
	Ciao
	MassimoB
 
---------------------------
http:\\
www.massimobeschi.it