cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 13 sept. 2006 à 13:19
non, justement c'est le problème.
ClientToScreen se base sur ClientOrigine. et ClientOrigine retourne toujours (0,0).
Mais quand je dock un panel(width=20) sur le côté gauche, mon MDIChild.Left = 0 alors qu'il devrait être à 20.
le problème est que l'origine pour les forms MDI est différent de celui pour le ClientArea. (oui c'est zarbe).
cs_Forman
Messages postés600Date d'inscriptionsamedi 8 juin 2002StatutMembreDernière intervention 6 avril 20101 12 sept. 2006 à 20:02
Peut-être que ClientOrigin ou CLientToScreen sont des pistes pour régler le problème?
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 12 sept. 2006 à 16:33
salut,
alors, l'idée de base c'était de récuperer le parent, mais comme tu le dit, c'est pas toujours possible. Je me suis donc orienté sur une solution moins propre, mais qui marche pour mon cas, j'utilise la var global de ma MainMDIForm (oui, c'est moche).
juste pour que tu saches:
Le seul problème que j'ai eut est lié aux converstions de position:
Les fenêtre MDI peuvent se position dans le client area de la main form. soit de 0,0 à X,Y.
MAIS si tu met un Panel avec alLeft, ton "(0,0)" de tes MDIChild serront en fait à (20,0) du ClientAre de ta form principal. Cependant, MDIChild.Left est toujours égal à 0 et ce même si c'est 20 du client are.
et donc, quand tu fais un MainMDI.ClientToScreen(MDIChild.TopLeft), t'as un resultat faux. (de la largeur du panel)
tu doit calculer la vrai origine de ta zone MDI (relative to screen) et l'ajouter.
Perso, j'utilise la position d'une image en alClient (le nb et la position de mes panels sur les côté étant paramétrable)
voilà. je vois pas de façon d'implementer ça de manière générique, a part en parcourant les tableau de composant.
je te remercie pour tes réponses, et si je fais des modif intéressante, je te dirais.
bon code,
cs_Forman
Messages postés600Date d'inscriptionsamedi 8 juin 2002StatutMembreDernière intervention 6 avril 20101 12 sept. 2006 à 16:04
Oui c'est vrai qu'on peut faire comme tu dis. Pour les MDIChild, essaie aussi de penser à traiter le cas où la Form a un Parent ou un ParentHandle, c'est pareil.
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 12 sept. 2006 à 15:26
merci,
c'est plus clair. Mais je ne voit pas pourquoi on applerais pas "à la main" UpdateButtonsPos. ça ne marcherais pas?
En passant, tu n'as pas prévu le cas des MDIChild. Les TPoint sont pas juste. Dans les function ClientToNC et ScreenToNC tu supposes que la form est positionée relativement à screen. ce qui n'est pas le cas en MDIChild. Je vais implementer ça sous peu...
cs_Forman
Messages postés600Date d'inscriptionsamedi 8 juin 2002StatutMembreDernière intervention 6 avril 20101 12 sept. 2006 à 13:15
Salut,
le composant qui crée les bouttons sur la form remplace la WindowProc de celle-ci par une autre. Ce remplacement peut intervenir après que la form ait déjà créé son Handle. Or, le composant a besoin du message WM_NCCREATE (envoyé par Windows juste au moment de la création du Handle) pour positionner les boutons la première fois. Donc, si le Handle est déjà créé, lors du remplacement de la WindowProc, le composant oblige la form a le recréer pour que ce fameux message WM_NCCREATE soit de nouveau envoyé, tout simplement.
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 12 sept. 2006 à 10:00
salut,
j'ai regarder ta source, elle est bien. C'est du joli boulot.
Y a des systèmes que je connaissait pas, genre TTrackMouseEvent.
mais, plus particulièrement, je comprend pas dans
procedure TTitleBarButtonsManager.SetForm(const Value: TCustomForm);
pourquoi tu fais ça:
if FForm.HandleAllocated then
TCustomFormHack(FForm).RecreateWnd;
POurquoi le recreer seulement si il exist deja.
d'ailleur, la lib test que l'handle exist avant de le recreer.
de plus, le handle est créer si necessaire lorsque tu le demande (Form.Handle)
pourrais-tu m'éclairer?
merci,
cs_Forman
Messages postés600Date d'inscriptionsamedi 8 juin 2002StatutMembreDernière intervention 6 avril 20101 7 juil. 2006 à 16:43
C'est bizarre je croyais avoir posté un commentaire mais il a disparu...
À Emandhal:
oui le composant peut s'adapter au thème courant: par défaut le composant ne peint rien sur le bouton. Donc, c'est à toi lorsque tu définis l'événement OnPaint de le faire ;) ;) ;)
Comment? je ne sais pas, mais je pense qu'en étudiant l'unité Themes de Delphi on devrait pouvoir trouver comment faire...
Mon composant ne fait rien d'autre que de remplacer la WindowProc de la Form associée, et de rederiger les messages de souris et de raffraichissement dans les événements concernés via celle-ci.
À Hendrix:
Merci!
cs_hendrix
Messages postés65Date d'inscriptionlundi 30 décembre 2002StatutMembreDernière intervention18 novembre 20081 7 juil. 2006 à 16:19
excellent cette idée de bouton sur la barre de titre... va falloir que je teste ce code !!!!
@+
Emandhal
Messages postés194Date d'inscriptiondimanche 2 mars 2003StatutMembreDernière intervention10 octobre 20063 7 juil. 2006 à 12:38
Salut, ca m'interesse, mais pas encore eut le temps de tester. Mais j'aimerai savoir si le composant s'adapte aussi au thème utilisé par windows?
Continue de coder ^^
bye
cs_Forman
Messages postés600Date d'inscriptionsamedi 8 juin 2002StatutMembreDernière intervention 6 avril 20101 7 juil. 2006 à 01:56
Oups, j'ai programmé tout ça vite fait et je viens de me rendre compte que j'ai oublié d'implémenter le comportement "disabled" des bouttons (c'est à dire qu'ils recevront quand même les clicks de souris même avec Enabled=False). Je corrigerai cela dans une prochaine mise à jour...
13 sept. 2006 à 13:19
ClientToScreen se base sur ClientOrigine. et ClientOrigine retourne toujours (0,0).
Mais quand je dock un panel(width=20) sur le côté gauche, mon MDIChild.Left = 0 alors qu'il devrait être à 20.
le problème est que l'origine pour les forms MDI est différent de celui pour le ClientArea. (oui c'est zarbe).
12 sept. 2006 à 20:02
12 sept. 2006 à 16:33
alors, l'idée de base c'était de récuperer le parent, mais comme tu le dit, c'est pas toujours possible. Je me suis donc orienté sur une solution moins propre, mais qui marche pour mon cas, j'utilise la var global de ma MainMDIForm (oui, c'est moche).
juste pour que tu saches:
Le seul problème que j'ai eut est lié aux converstions de position:
Les fenêtre MDI peuvent se position dans le client area de la main form. soit de 0,0 à X,Y.
MAIS si tu met un Panel avec alLeft, ton "(0,0)" de tes MDIChild serront en fait à (20,0) du ClientAre de ta form principal. Cependant, MDIChild.Left est toujours égal à 0 et ce même si c'est 20 du client are.
et donc, quand tu fais un MainMDI.ClientToScreen(MDIChild.TopLeft), t'as un resultat faux. (de la largeur du panel)
tu doit calculer la vrai origine de ta zone MDI (relative to screen) et l'ajouter.
Perso, j'utilise la position d'une image en alClient (le nb et la position de mes panels sur les côté étant paramétrable)
voilà. je vois pas de façon d'implementer ça de manière générique, a part en parcourant les tableau de composant.
je te remercie pour tes réponses, et si je fais des modif intéressante, je te dirais.
bon code,
12 sept. 2006 à 16:04
12 sept. 2006 à 15:26
c'est plus clair. Mais je ne voit pas pourquoi on applerais pas "à la main" UpdateButtonsPos. ça ne marcherais pas?
En passant, tu n'as pas prévu le cas des MDIChild. Les TPoint sont pas juste. Dans les function ClientToNC et ScreenToNC tu supposes que la form est positionée relativement à screen. ce qui n'est pas le cas en MDIChild. Je vais implementer ça sous peu...
12 sept. 2006 à 13:15
le composant qui crée les bouttons sur la form remplace la WindowProc de celle-ci par une autre. Ce remplacement peut intervenir après que la form ait déjà créé son Handle. Or, le composant a besoin du message WM_NCCREATE (envoyé par Windows juste au moment de la création du Handle) pour positionner les boutons la première fois. Donc, si le Handle est déjà créé, lors du remplacement de la WindowProc, le composant oblige la form a le recréer pour que ce fameux message WM_NCCREATE soit de nouveau envoyé, tout simplement.
12 sept. 2006 à 10:00
j'ai regarder ta source, elle est bien. C'est du joli boulot.
Y a des systèmes que je connaissait pas, genre TTrackMouseEvent.
mais, plus particulièrement, je comprend pas dans
procedure TTitleBarButtonsManager.SetForm(const Value: TCustomForm);
pourquoi tu fais ça:
if FForm.HandleAllocated then
TCustomFormHack(FForm).RecreateWnd;
POurquoi le recreer seulement si il exist deja.
d'ailleur, la lib test que l'handle exist avant de le recreer.
de plus, le handle est créer si necessaire lorsque tu le demande (Form.Handle)
pourrais-tu m'éclairer?
merci,
7 juil. 2006 à 16:43
À Emandhal:
oui le composant peut s'adapter au thème courant: par défaut le composant ne peint rien sur le bouton. Donc, c'est à toi lorsque tu définis l'événement OnPaint de le faire ;) ;) ;)
Comment? je ne sais pas, mais je pense qu'en étudiant l'unité Themes de Delphi on devrait pouvoir trouver comment faire...
Mon composant ne fait rien d'autre que de remplacer la WindowProc de la Form associée, et de rederiger les messages de souris et de raffraichissement dans les événements concernés via celle-ci.
À Hendrix:
Merci!
7 juil. 2006 à 16:19
@+
7 juil. 2006 à 12:38
Continue de coder ^^
bye
7 juil. 2006 à 01:56