Bonjour,
Est il possible de centrer verticalement le texte d'un CEdit ?
L'alignement horizontal est trivial mais je ne trouve rien en ce qui concerne l'alignement vertical.
Cordialement.
Bonjour,
Est il possible de centrer verticalement le texte d'un CEdit ?
L'alignement horizontal est trivial mais je ne trouve rien en ce qui concerne l'alignement vertical.
Cordialement.
Regarde les propriétés de ton contrôle dans le l'éditeur de resource.
salut,
l'alignement dépend de la hauteur de la fonte pas du contrôle...
donc sauf magouille visuelle je ne vois pas comment tu pourrais faire.
Ce qui est affirmé sans preuve peut être nié sans preuve Euclide.
Les conversions numériques en C,C++,C++/CLI
DLL d'extensions : écriture d'un plug-in de classe
Démarrer avec les MFC 2/2
Création d'un ActiveX MFC
Intégration d'une imprimante PDF pour éditions automatisées
Migrer du code de Visual C++ 6.0 vers Visual C++ 2005
Démarrer avec les MFC sous Visual C++1/2
la Faq Visual C++ 500 Q/R,Mon blog
Aide en Ligne MFC
Cours et tutoriels C++ - FAQ C++ - Forum C++.
J'imagine qu'en réécrivant la fonction OnDraw dans un CEdit custom je dois pouvoir le faire mais bon bof quoi ...![]()
salut,
soit tu as un edit multiline et tu peux utiliser EM_SETRECT,
soit tu peux procéder comme ça pour un single line :
dans CMyEdit.h
dans CMyEdit.cpp:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 class CMyEdit : public CEdit { DECLARE_DYNAMIC(CMyEdit); protected: DECLARE_MESSAGE_MAP() afx_msg void OnNcCalcSize(BOOL,NCCALCSIZE_PARAMS*); afx_msg void OnNcPaint(); LONG m_TopMargin; LONG m_BottomMargin; };
c'est juste un exemple, il reste à calculer m_TopMargin et m_BottomMargin (dans PreSubclassWindow() si ton CEdit est dans un dialog)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 IMPLEMENT_DYNAMIC(CMyEdit,CEdit) BEGIN_MESSAGE_MAP(CMyEdit,CEdit) ON_WM_NCCALCSIZE() ON_WM_NCPAINT() END_MESSAGE_MAP void CMyEdit::OnNcCalcSize(BOOL,NCCALCSIZE_PARAMS *lpncsp) { lpncsp->rgrc[0].top+=m_TopMargin; lpncsp->rgrc[0].bottom-=m_BottomMargin; } void CMyEdit::OnNcPaint() { CWindowDC dc(this); CRect rect; GetWindowRect(rect); dc.FillSolidRect(CRect(rect.left,rect.top,rect.right,rect.top+m_TopMargin),RGB(255,255,255)); dc.FillSolidRect(CRect(rect.left,rect.bottom-m_BottomMargin,rect.right,rect.bottom),RGB(255,255,255)); }
ça ne marche pas si ton CEdit à des styles comme WS_BORDER, WS_EX_CLIENTEDGE ...
la couleur du fond est fixe (RGB(255,255,255)) et ne devrait pas l'etre ...
il y a un article sur codeguru ou codeproject sur le sujet ... à chercher
@+
Je suis à la recherche de la même chose, mais je ne trouve pas la surcharge de la classe CEdit très heureuse et je ne trouve pas super claire la méthode évoquée. Est-ce que quelqu'un voit comment on pourrait le faire simplement ?Bonjour,
Est il possible de centrer verticalement le texte d'un CEdit ?
L'alignement horizontal est trivial mais je ne trouve rien en ce qui concerne l'alignement vertical.
Cordialement.
Merci d'avance.
Bien que trouvant la méthode proposée peu convaincante j'ai tenté.
Il s'avère que la zone du CEdit est réduite ... mon soucis c'est que sous certains éléments de ma CDialog je trace des rectangles dans la fonction OnEraseBkgnd : ça me permet d'avoir des bordures autour des ces éléments. Avec la méthode proposée je découvre une plus grande partie du rectangle qui n'a finalement plus l'air d'une bordure mais plutot d'un cache 16/9ème
De plus pour centrer il faut tenir compte de la taille en pixel de la police et on ne peut pas dire que ça soit terrible ...
Quelqu'un a-t-il une méthode plus adaptée à proposer ?
Je ne vois pas d'autre solution.
Il faut jouer avec la zone non-cliente, puisque la zone cliente n'est pas modifiable...
Soit tu mets ton Edit en mode multiline et tu peux dans ce cas utiliser EM_SETRECT, mais avec le comportement du multiline par rapport au singleline ...
Soit tu modifies la zone non-cliente, comme expliquer ci-dessus.
Il faut savoir que la cadre (style WS_BORDER) est déssiné par le controle dans la zone cliente et non dans la zone non-cliente, comme ça aurait du l'etre ... ça impose de redessiner manuellement ce cadre, et ça se complique lorsque il faut tenir compte du Theme ...
mais sinon j'avais testé cette méthode pour faire un InPlace Edit, elle fonctionne bien, mais j'avais dessiné le cadre manuellement ...
@+
edit: les rectangles, il ne faut pas les dessiner dans OnEraseBkGnd, parce que ça ne touche que la zone cliente et non la zone non-cliente
Il faut les dessiner dans OnNcPaint
Mon problème avec cette méthode étant que l'on voit trop du rectangle qui constitue le cadre, j'ai décider de redessiner par dessus un autre rectangle.
J'ai dessine donc 3 éléments dans l'ordre suivant :
- 1 rectangle légèrement plus grand que le CEdit pour faire le cadre
- 1 rectangle de la même taille et même couleur que le fond du CEdit pour couvrir les parties du premier rectangle que je ne veux pas voir
- mon CEdit
Ce n'est peut-être pas très beau, mais ça à au moins le mérite de me fournir le rendu souhaité.
J'aurai besoin d'un petite précision : où calculer dynamiquement m_TopMargin et m_BottomMargin ?
Désolé j'ai eu beau chercher et faire des tests je n'ai pas trouvé![]()
J'aurai besoin d'un petite précision : où calculer dynamiquement m_TopMargin et m_BottomMargin ?
Les marges dépendent de la taille du texte et de la taille du controle
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 void UpdateMargins() { CRect rect; GetWindowRect(rect); CClientDC dc(this); CFont *pOldFont=dc.SelectObject(GetFont()); LONG TextHeight=dc.GetTextExtent(_T(" "),1).cy; dc.SelectObject(pOldFont); LONG delta=rect.Height()-TextHeight; m_TopMargin=delta/2; m_BottomMargin=delta-m_TopMargin; }
donc il faut appeler UpdateMargins() dans :
* OnCreate() : pour l'initialisation
* OnSize() : si le controle change de taille (falcutatif, suivant le besoin)
* OnSetFont() : si le controle change de police (falcutatif, suivant le besoin)
PS : changer RGB(255,255,255) par un GetSysColor(COLOR_WINDOW), ça sera mieux ...
@+
J'ai beau tourner ça dans tous les sens, ça ne marche définitivement pas
En effet, si je passe pas l'interface de VC pour créer le CEdit le OnCreate() ne sera jamais appelé, donc le calcule des marges ne pourra être fait qu'après le OnNcCalcSize ...
Si je fais un Create manuel pour passer dans le OnCreate(), alors le CRect renvoyé par GetWindowRect ne peut pas contenir une valeur correcte, car l'affichage n'est pas encore créé ...
Désolé mais je ne vois vraiment pas comment ça pourrait marcher à moins de fixer "en dur" les marges.
![]()
effectivement, dans ce cas là, oublie OnCreate() et surcharge la fonction virtuelle PreSubclassWindow()En effet, si je passe pas l'interface de VC pour créer le CEdit le OnCreate() ne sera jamais appelé, donc le calcule des marges ne pourra être fait qu'après le OnNcCalcSize ...
ça devrait marcher dans tous les cas ...
@+
la même chose se produit avec PreSubclassWindow() ... le calcul se fait donc avec un CRect bidon (peut-être celui correspondant aux dimensions spécifiées sur l'éditeur graphique, mais ça ne m'intéresse vraiment pas vu que je positionne mes éléments dynamiquement à l'aide de MoveWindow (OnNcCalcSize s'exécutant avant !!!)).le CRect renvoyé par GetWindowRect ne peut pas contenir une valeur correcte, car l'affichage n'est pas encore créé ...
Ça ne serait pas trop gênant si je pouvais appeler OnNcCalcSize quand je le souhaite, mais ça ne me semble pas possible résultat même si je fini par calculer les marges correctes impossible de les appliquer ...
bon j'ai pas trop compris ce que j'ai fait mais à force d'essayer de faire marcher l'affaire ça a fini par fonctionner presque comme ça aurait toujours du (en effet OnNcCalcSize n'est pas appellé aussi souvent que je le voudrais : la marge peut changer sans que la zone soit recalulée, d'où le problème suivant à mon avis)Ça ne serait pas trop gênant si je pouvais appeler OnNcCalcSize quand je le souhaite, mais ça ne me semble pas possible résultat même si je fini par calculer les marges correctes impossible de les appliquer ...![]()
je confirme qu'il s'agit bien des dimensions posées "à la main" via l'éditeur, car OnNcCalcSize passe avant le MoveWindow => je n'obtiens donc un centrage correct que si je m'amuse à redimensionner la fenetrela même chose se produit avec PreSubclassWindow() ... le calcul se fait donc avec un CRect bidon (peut-être celui correspondant aux dimensions spécifiées sur l'éditeur graphique, mais ça ne m'intéresse vraiment pas vu que je positionne mes éléments dynamiquement à l'aide de MoveWindow (OnNcCalcSize s'exécutant avant !!!)).le CRect renvoyé par GetWindowRect ne peut pas contenir une valeur correcte, car l'affichage n'est pas encore créé ...
Tous mes problèmes seraient donc réglés si je pouvais "forcer" d'une façon ou d'une autre OnNcCalcSize. (j'accepte même les feintes super moches)
et dans OnSize() c'est pas plus simple ???
je l'avais indiqué plus haut, si tu redimensionnes le controle dynamiquement, il faut recalculer les marges ...
utilise SetWindowPos() avec le flag SWP_FRAMECHANGEDTous mes problèmes seraient donc réglés si je pouvais "forcer" d'une façon ou d'une autre OnNcCalcSize. (j'accepte même les feintes super moches )
ça devrait le faire...
PS: la technique, elle est expliquée aussi quelque part sur codeguru ou codeproject. à chercher sur le net ...
@+
c'était déjà fait sauf qu'au final ça s'avère inutile je l'ai donc supprimé. Pour m'assurer que UpdateMargins est toujours fait avant OnNcCalcSize je l'ai simplement appelé dedans.et dans OnSize() c'est pas plus simple ???
Le soucis c'est que le CRect sur lequel se fait les calculs de la marge n'est pas mis à jour : en clair je fait un MoveWindow (ou SetWindowPos) qui provoque le OnNcCalcSize de mon CEdit, alors qu'un GetWindowRect dans ce même CEdit au même moment ne renverra pas une valeur à jour du CRect !!! Il ne le sera qu'après OnNcCalcSize ... belle abération, c'est du grand MS ...
En partant de ce constat j'ai réalisé la feinte suivante qui fonctionne : remplacer le MoveWindow par 2 appels successifs et identiques de SetWindowPos avec le flag SWP_FRAMECHANGED. (le 1er fait un calcul de marge bidon puis mets à jour le CRect, le 2eme refait le calcul sur le CRect précédemment mis à jour avec le bonne valeur (car inchangée entre les 2) puis refait un maj inutile du CRect).
Si tu trouves mieux je suis évidemment preneur
Merci pour l'aide en tout cas.
ben tu l'as en paramètre : lpncsp->rgrc[???]Le soucis c'est que le CRect sur lequel se fait les calculs de la marge n'est pas mis à jour
la MSDN n'est pas très clair sur le sujet ... un des trois RECT en fonction du wparam
@+
Héhéhé bien vu
Dans UpdateMargins
à oublier donc ^^ Il suffit de passer lpncsp->rgrc[0] en paramètre de UpdateMargins lors de son appel dans OnNcCalcSize.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 CRect rect; GetWindowRect(rect);
Et finalement on a même plus besoin de PreSubclassWindow![]()
Partager