FAQ VC++ et MFCConsultez toutes les FAQ
Nombre d'auteurs : 20, nombre de questions : 545, dernière mise à jour : 5 avril 2013 Ajouter une question
Cette faq a été réalisée pour répondre aux questions les plus fréquement posées sur le forum Développement Visual C++
Je tiens à souligner que cette faq ne garantit en aucun cas que les informations qu'elle contient sont correctes ; Les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou si vous souhaitez devenir redacteur, lisez ceci.
Sur ce, je vous souhaite une bonne lecture. Farscape
- Comment ajouter un SpinUp automatique à un CEdit numérique ?
- Comment insérer plusieurs lignes dans un CEdit ?
- Comment faire pour que le texte d'un CEdit soit sélectionné en prenant le focus ?
- Comment forcer la saisie en majuscules ou minuscules d'un CEdit?
- Comment donner le focus au contrôle suivant après la touche entrée sur un CEdit ?
- Comment positionner le curseur clavier sur le dernier caractère d'un CEdit ?
- Comment gérer la couleur sur un CEdit ?
- Comment intercepter la touche entrée au niveau d'un CEdit ?
- Comment filtrer les caractères saisis dans un CEdit ?
- Comment changer les caractères en cours de saisie dans un CEdit ?
- Comment ajouter du texte à la fin d'un CEdit ?
- Comment faire apparaître/disparaître les ascenseurs dans un CEdit ?
- Comment enlever la limite des 64K sur un CEdit ?
- Comment simuler un Ctrl+Fin au clavier ?
- Comment modifier le style d'un CEdit dynamiquement ?
Dans la ressource dialogue insérer l'édit et le contrôle SpinUp à côté.
Veiller à régler le tab order (CTRL +D) pour que le spin up soit après le CEdit.
Régler l'édit avec l'option number
Au niveau du SpinUp cocher les options suivantes dans l'onglet styles:
- Auto buddy ;
- Set buddy integer ;
- Alignement right.
Il faut commencer par régler les propriétés de l'édit dans l'éditeur de ressources :
Onglet styles :
Activer la coche Multiline et Want Return.
Pour remplir l'édit plusieurs solutions :
Si l'on dispose d'une variable CString attachée à l'édit il faudra veiller à rajouter les codesCR+LF ("\r\n") à la fin de chaque ligne et faire un UpdateData(FALSE) pour mettre à jour le contrôle
On pourra aussi mettre à jour l'édit avec la fonction SetWindowText.
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 | CString str ,strLine; for(int i=0 ;i<10 ;i++) { str.Format("ligne numéro :%d \r\n" ,i) ; strLine+=str ; } GetDlgItem(IDC_EDIT1)->SetWindowText(strLine); |
Lorsque l'on se déplace par la touche tabulation d'un édit a l'autre la zone texte de l'édit est sélectionnée,
par contre si l'on click directement sur l'édit avec la souris ce n'est pas le cas.
Pour remédier à ce problème il suffira de placer le code suivant dans le message OnSetFocus:
soit dans un édit dérivé de la classe CEdit ,soit en rajoutant une notification EN_SETFOCUS sur la fenêtre parent en sélectionnant l'édit concerné dans ClassWizard .
Exemple implémentation sur la fenêtre parent :
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | BEGIN_MESSAGE_MAP(CTestMdiView, CFormView) //{{AFX_MSG_MAP(CTestMdiView) ON_EN_SETFOCUS(IDC_EDIT1, OnSetfocusEdit1) //}}AFX_MSG_MAP END_MESSAGE_MAP() //----------------------------------------------------------------------------- void CTestMdiView::OnSetfocusEdit1() { // TODO: Add your control notification handler code here GetDlgItem(IDC_EDIT1)->PostMessage(EM_SETSEL,0,-1); } |
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ///////////////////////////////////////////////////////////////////////////// // CMyEdit CMyEdit::CMyEdit(){} CMyEdit::~CMyEdit(){} BEGIN_MESSAGE_MAP(CMyEdit, CEdit) //{{AFX_MSG_MAP(CMyEdit) ON_CONTROL_REFLECT(EN_SETFOCUS, OnSetfocus) //}}AFX_MSG_MAP END_MESSAGE_MAP() void CMyEdit::OnSetfocus() { // TODO: Add your control notification handler code here PostMessage(EM_SETSEL,0,-1); } |
Il suffit de cocher l'option Uppercase ou Lowercase sur les propriétés de l'édit dans l'éditeur de ressources.
Tout d'abord se référer au post : Comment intercepter les touches entrée et échappement dans une boîte de dialogue ?
Pour faire passer le focus sur le contrôle suivant on utilisera la fonction NextDlgCtrl();
Voir post : Comment donner le ‘focus' au contrôle suivant / précédent suivant l'ordre des tabulations ?
Au final on écrira :
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | BOOL CMyForm::OnCommand(WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class CWnd *pWnd = GetFocus(); switch(wParam) { case IDOK: if(pWnd!=GetDlgItem(IDOK)) { reinterpret_cast<CDialog *>(this)->NextDlgCtrl(); return FALSE; } break; case IDCANCEL:if(pWnd!=GetDlgItem(IDCANCEL)) { return FALSE; } break; } return CFormView::OnCommand(wParam, lParam); } |
Pour un CEdit simple ligne :
Code c++ : | Sélectionner tout |
1 2 3 | pEdit->PostMessage(WM_KEYDOWN,VK_END,0); pEdit->SetFocus(); // eventuellement |
Code c++ : | Sélectionner tout |
1 2 3 4 5 | int n=pEdit->GetWindowTextLength()-1; pEdit->SetSel(n,n,TRUE); pEdit->PostMessage(WM_KEYDOWN,VK_END,0); pEdit->SetFocus(); // eventuellement |
En interceptant le message "reflect" =WM_CTLCOLOR à destination de l'édit.
Voici comment procéder :
Générer une classe dérivée de CEdit par ClassWizard .
Toujours dans ClassWizard intercepter le message "reflect"=WM_CTLCOLOR dans la liste des messages.
L'exemple ci-dessus mettra une couleur de fond blanche si l'édit est mode lecture seule.
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor) { // TODO: Change any attributes of the DC here //déclarer dans la classe produite un pointeur sur une CBrush // CBrush* m_pBrushReadOnly=NULL; // le mettre à null dans le constructeur // dans le destructeur delete m_pBrushReadOnly if((GetStyle() & ES_READONLY)) { if(!m_pBrushReadOnly) m_pBrushReadOnly = new CBrush(RGB(255,255,255)); pDC->SetBkColor(RGB(255,255,255)); return (HBRUSH)m_pBrushReadOnly->GetSafeHandle(); } // TODO: Return a non-NULL brush if the parent's handler should not be called return NULL; } |
Par défaut la touche entrée n'est pas relayée au niveau de l'édit pour les messages WM_CHAR ,WM_KEYDOWN etc..
Note: il en est de même pour les flèches et la touche tabulation .
Pour intercepter cette touche il faudra commencer par générer une classe dérivée de CEdit avec l'aide de ClassWizard .
Et de redéfinir la fonction PreTranslateMessage comme suit:
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | BOOL CMyEdit::PreTranslateMessage(MSG* pMsg) { // TODO : ajoutez ici votre code spécialisé et/ou l'appel de la classe de base if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) { TRACE("\nReturn intercepté"); } return CEdit::PreTranslateMessage(pMsg); } |
Méthode: il faut intercepter le message WM_CHAR et ne pas répondre quand le caractère ne convient pas.
Il va sans dire qu'il faudra générer une classe édit dérivée de la classe CEdit avec l'aide de ClassWizard.
L'exemple ci-dessous interdit de saisir les ‘a'.
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // CMyEdit CMyEdit::CMyEdit() { } CMyEdit::~CMyEdit() { } BEGIN_MESSAGE_MAP(CMyEdit, CEdit) //{{AFX_MSG_MAP(CMyEdit) ON_WM_CHAR() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMyEdit message handlers void CMyEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if(nChar=='a') return; CEdit::OnChar(nChar, nRepCnt, nFlags); } |
Pour commencer avec l'aide de ClassWizard :
Il faut générer une classe dérivée d'un CEdit .
Ensuite intercepter le message WM_CHAR .
Pour Les caractères non souhaités il ne faut pas appeler la fonction de la classe de base ,
Pour envoyer un autre caractère en fonction de celui qui est reçu on utilisera un postmessage.
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | void CMyEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if(nChar=='a') { PostMessage(WM_CHAR,'A'); return; } CEdit::OnChar(nChar, nRepCnt, nFlags); } |
Note:il faudra bien sûr utiliser cette classe à la place de CEdit lors de la génération de la variable contrôle dans la classe parent.
(pour un CEdit multiligne)
On peut par exemple récupérer la taille du contenu du CEdit, envoyer un message de sélection à la fin du CEdit, et remplacer la sélection par le nouveau texte.
Exemple qui ajoute une ligne avec l'heure courante :
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 | CTime monTemps = CTime::GetCurrentTime(); CString resultat; resultat.Format("%d:%d:%d\r\n",monTemps.GetHour(),monTemps.GetMinute(),monTemps.GetSecond()); int longueur = m_monEdit.GetWindowTextLength(); m_monEdit.SetSel(longueur,longueur); m_monEdit.ReplaceSel(resultat); |
Il suffit de changer le style du CEdit avec la fonction:
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::ModifyStyle BOOL ModifyStyle( DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0 ); |
Code c++ : | Sélectionner tout |
1 2 | GetDlgItem(IDC_EDIT1)->ModifyStyle(0,WS_HSCROLL |WS_VSCROLL,SWP_DRAWFRAME); |
Code c++ : | Sélectionner tout |
1 2 | GetDlgItem(IDC_EDIT1)->ModifyStyle(WS_HSCROLL |WS_VSCROLL,0,SWP_DRAWFRAME); |
Sur windows 95 la limite est de 64K et on ne peut pas la changer.
Sur windows NT c'est différent et la limite dépendra de la machine.
Pour cela on appellera la fonction SetLimitText avec la valeur 4111222333 pour disposer du maximum disponible sur la machine utilisée...
Voir note MSDN
Cette séquence de touche peut être utile avec l'utilisation de différents contrôles
Exemple placer le curseur dans un CEdit ou CEditView en fin de page avec un défilement de la fenêtre si nécessaire.
Code c++ : | Sélectionner tout |
1 2 3 4 5 | keybd_event(VK_CONTROL,0x9d,0 , 0); // Ctrl Press keybd_event(VK_END,0,0,0); keybd_event(VK_END,0,KEYEVENTF_KEYUP,0); keybd_event(VK_CONTROL,0x9d,KEYEVENTF_KEYUP,0); // Ctrl Release |
Le but étant par exemple de changer le type d'alignement du texte.
Par exemple de passer de l'alignement à gauche à centré etc.
La première idée serait d'utiliser la fonction Comment modifier le style d'une fenêtre ?
Exemple :
Code C++ : | Sélectionner tout |
m_edit_test.ModifyStyle(ES_RIGHT | ES_CENTER ,ES_LEFT);
Malheureusement ce code ne fonctionne pas, on ne peut modifier certains styles spécifiques d'un contrôle après sa création.
Le mieux étant de faire un essai avant; Exemple avec ES_READONLY ça fonctionne.
Pour résoudre le problème on procédera par la re création d'un nouveau contrôle en copiant les informations du précédent.
Code C++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | void ModifyEditStyle(CEdit &rEdit,DWORD dwRemove,DWORD dwAdd) { rEdit.ModifyStyle(dwRemove,dwAdd); UINT nID=rEdit.GetDlgCtrlID(); CRect rect; rEdit.GetWindowRect(&rect); CWnd *pParent=rEdit.GetParent(); pParent->ScreenToClient(&rect); DWORD dwExEditStyle =rEdit.GetExStyle( ); DWORD dwEditStyle =rEdit.GetStyle( ); CString str; rEdit.GetWindowText(str); HWND hwnd=::CreateWindowEx( dwExEditStyle, TEXT("EDIT"), // Class name str, // Window text dwEditStyle, // Window style rect.left, // x coordinate of the upper-left corner rect.top, // y coordinate of the upper-left corner rect.Width(), // Width of the edit control window rect.Height(), // Height of the edit control window pParent->GetSafeHwnd(), // Window handle of parent window (HMENU)(nID), // Control identifier AfxGetInstanceHandle(), // Instance handle NULL); // Specify NULL for this parameter when // creating a control ::SendMessage(hwnd, WM_SETFONT, (WPARAM)::SendMessage(rEdit.GetSafeHwnd(), WM_GETFONT, 0, 0),TRUE); rEdit.DestroyWindow(); rEdit.SubclassWindow(hwnd); } //................ void CessaiOCX1View::OnBnClickedButtonAlignDrotie() { ModifyEditStyle( m_edit_test, ES_LEFT | ES_CENTER , ES_RIGHT); } |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.