Fenêtre incrustable

Signaler
Messages postés
12
Date d'inscription
dimanche 15 août 2004
Statut
Membre
Dernière intervention
22 septembre 2006
-
Messages postés
814
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
-
Bonjour
Je voudrais obtenir pour une Form (Fenetre2) un peu le même effet aimanté que la propriété "Screensnap"... Seulement je voudrais que ca agisse non pas sur les bords du bureau mais sur les bords d'une autre Form (Fenetre1) de mon application. Finalement, Fenetre2 doit se coller à Fenetre1 des qu'elle s'en approche, et etre déplacée en meme temps si Fenetre1 bouge... On voit souvent ca dans des applis... est-ce possible dans Delphi ?
Merci pour votre aide !

5 réponses

Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
2
Allez, un peu de maieutique :

Ta form1 ( la 2 aussi hein) a une propriété boundRect (un rectangle) qui est sa position en pixel écran et qui recoupe les memes infos que Top, Left, Height,Width (en fait boundrect c'est en gros top,left, top+height, left+width)

Quand tu bouges une form, tu le fais via un evenement onMouseMouse (avec le test du bouton gauche de souris enfoncé)

Tes forms font parties de la meme appli (faisons simple), donc elles peuvent se connaitre. (genre Form2 peut connaitre le boundrect de Form1)

Tu Peux tester si Abs( Form2.Bounrect.Left -Form1.Bounrect.Right ) < 5 {pixels, par exemple.....}

Et dans ce cas, tu peux écrire Form2.Left := Form1.Bounrect.Right {+1}

Evidement, tout ceci marche aussi pour le collage a droite, à gauche, en haut, en bas, voir meme pour de l'auto dimensionnement....

A toi d'être créatif.
Messages postés
12
Date d'inscription
dimanche 15 août 2004
Statut
Membre
Dernière intervention
22 septembre 2006

ok merci donc il faut bien le faire à la mimine.
Par contre j'ai du mal a capter le déplacement de la fenetre avec la bordure.. en effet onMouseMouse n'agit pas si on déplace le souris sur la bordure, pareil pour onMouseDown.
J'ai essayé la procedure WMNCHitTest(var Message: TWMNCHitTest) que j'ai vu sur un topic mais elle agit apres le relachement du bouton seulement
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
2
Ben oui mais là si ta souris est sur la bordure, t'es plus dans l'evenement mouseMove de ta form, t'es dans le form resize, et c'est un autre evenement, ça. Faut le gérer.

Dans le OnMouseMove t'as peut-etre remarqué une var appelée Shift: TShiftState

Un test du genre...... if (ssLeft in Shift) sera à true si le bouton gauche est enfoncé.

Apres libre à toi de tester avec un while (ssLeft in Shift) do Verifie_si_on_se_rapproche_de_l'autre_forme_et si oui_on_s'y_colle ;
Messages postés
12
Date d'inscription
dimanche 15 août 2004
Statut
Membre
Dernière intervention
22 septembre 2006

Oui je suis bien d accord, mais je ne passe pas dans le movemove ni dans le resize si je ne fais que déplacer la bordure... c'est cet événement que j'ai du mal à intercepter car je veux que l autre se déplace en meme temps... pour le reste y a pas de problème
Messages postés
814
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
3
salut,

tu peux ajouter ceci a une class Form (class de base pour tes fenetre avec magnet)

procedure WMEnterSizeMove(var Message: TMessage);message WM_ENTERSIZEMOVE;
procedure WMExitSizeMove(var Message: TMessage);message WM_EXITSIZEMOVE;
procedure WMWINDOWPOSCHANGING(Var Msg: TWMWINDOWPOSCHANGING);message WM_WINDOWPOSCHANGING;


procedure TMDIForm.WMExitSizeMove(var Message: TMessage);
begin
fLastHeight:= Height;
fLastWidth:=Width;
end;

procedure TMDIForm.WMWINDOWPOSCHANGING(var Msg: TWMWINDOWPOSCHANGING);
//this message is sent whenever the window is moved or resized or focused.
// but not DURING the moving process
begin
if not floating then exit; // only when not docked

if (fLastHeight=Height)and(fLastWidth=Width) then
CorrectPosAndSize(
Msg.WindowPos^.x,
Msg.WindowPos^.y,
Msg.WindowPos^.cx,// largeur
Msg.WindowPos^.cy,//hauteur
rsMove)
else
CorrectPosAndSize(
Msg.WindowPos^.x,
Msg.WindowPos^.y,
Msg.WindowPos^.cx,
Msg.WindowPos^.cy,
rsResize)
end;

procedure TMDIForm.WMEnterSizeMove(var Message: TMessage);
begin
fLastHeight:= Height;
fLastWidth:=Width;
end;


CorrectPosAndSize te corrige les parametres (donc tu passes les valeurs en "var")

après, comme t'as dit DeltaFx, tu boucle sur tout tes forms et pour toute les TMDIForm tu compares avec les tailles/pos.

pour les "grouper", il te faut ajouter une proriete "MagnetWith : TMDIForm" que tu set dans CorrectPosAndSize.
Après dans Form.OnMove, tu verifie si t aproriete est setée et si oui, tu déplace l'autre fenetre aussi.
Note que tu pourrait aussi juste dépalcer les fenetre qui sont assez proche de celle que tu déplace sans avoir de proriete MagnetWith, mais tu devrais comparer les positions deux fois.

et si tu peux traiter le rectangle gris pendant le deplacement:
procedure WMMOVING(var Msg: TWMMoving); message WM_MOVING;

tu trouve de la doc sur les messages sur el site de la msdn:
http://search.msdn.microsoft.com/search/default.aspx?siteId=0&tab=0&query=wm_move

Voilé, t'as les grandes lignes. Je te conseille de faire des tests siple avant de te lancer dans le codage complet.

bon code!