IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

[CEdit] Centrer le texte verticalement


Sujet :

MFC

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 45
    Par défaut [CEdit] Centrer le texte verticalement
    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.

  2. #2
    NairodDorian
    Invité(e)
    Par défaut
    Regarde les propriétés de ton contrôle dans le l'éditeur de resource.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 45
    Par défaut
    Citation Envoyé par NairodDorian Voir le message
    Regarde les propriétés de ton contrôle dans le l'éditeur de resource.
    Justement, il n'y a aucune propriete d'alignement vertical (alors qu'il y en a pour l'alignement horizontal d'ou le "trivial" ).

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    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.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 45
    Par défaut
    J'imagine qu'en réécrivant la fonction OnDraw dans un CEdit custom je dois pouvoir le faire mais bon bof quoi ...

  6. #6
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    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

    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;
    };
    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
    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));
    }
    c'est juste un exemple, il reste à calculer m_TopMargin et m_BottomMargin (dans PreSubclassWindow() si ton CEdit est dans un dialog)
    ç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

    @+

  7. #7
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    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.
    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 ?

    Merci d'avance.

  8. #8
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    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 ?

  9. #9
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    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

  10. #10
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    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é.

  11. #11
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    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é

  12. #12
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    J'aurai besoin d'un petite précision : où calculer dynamiquement m_TopMargin et m_BottomMargin ?

    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;
    }
    Les marges dépendent de la taille du texte et de la taille du controle

    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 ...

    @+

  13. #13
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    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.


  14. #14
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    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 ...
    effectivement, dans ce cas là, oublie OnCreate() et surcharge la fonction virtuelle PreSubclassWindow()

    ça devrait marcher dans tous les cas ...

    @+

  15. #15
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    le CRect renvoyé par GetWindowRect ne peut pas contenir une valeur correcte, car l'affichage n'est pas encore créé ...
    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 !!!)).
    Ç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 ...

  16. #16
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    Ç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)

    le CRect renvoyé par GetWindowRect ne peut pas contenir une valeur correcte, car l'affichage n'est pas encore créé ...
    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 !!!)).
    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 fenetre

    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 )

  17. #17
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    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 ...

    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 )
    utilise SetWindowPos() avec le flag SWP_FRAMECHANGED

    ça devrait le faire...

    PS: la technique, elle est expliquée aussi quelque part sur codeguru ou codeproject. à chercher sur le net ...

    @+

  18. #18
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    et dans OnSize() c'est pas plus simple ???
    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.

    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.

  19. #19
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    Le soucis c'est que le CRect sur lequel se fait les calculs de la marge n'est pas mis à jour
    ben tu l'as en paramètre : lpncsp->rgrc[???]

    la MSDN n'est pas très clair sur le sujet ... un des trois RECT en fonction du wparam

    @+

  20. #20
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    Héhéhé bien vu

    Dans UpdateMargins
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CRect rect;
    GetWindowRect(rect);
    à oublier donc ^^ Il suffit de passer lpncsp->rgrc[0] en paramètre de UpdateMargins lors de son appel dans OnNcCalcSize.

    Et finalement on a même plus besoin de PreSubclassWindow

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [CR10] Centrer le texte verticalement
    Par Cirdek dans le forum SAP Crystal Reports
    Réponses: 5
    Dernier message: 18/06/2008, 10h38
  2. ASP.net centrer un text verticalement au milieu d'un LinkButton
    Par zitoun dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 07/05/2007, 10h08
  3. [Word] centrer un texte verticalement
    Par mzt.insat dans le forum Word
    Réponses: 1
    Dernier message: 22/02/2007, 12h52
  4. Réponses: 2
    Dernier message: 20/11/2006, 09h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo