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 rendre un contrôle actif/inactif ?
- Comment savoir si un contrôle est actif / Inactif ?
- Comment cacher / faire apparaître une fenêtre ?
- Comment savoir si une fenêtre est visible ?
- Comment modifier le style d'une fenêtre ?
- Comment récupérer le style d'une fenêtre ?
- Comment mettre en lecture seule les edits d'une boîte de dialogue ?
- Comment changer le titre d'une fenêtre ?
- Comment récupérer le titre d'une fenêtre ?
- Comment récupérer/modifier la fonte courante d'une fenêtre ?
- Comment récupérer le contrôle qui a le ‘focus' dans une fenêtre ?
- Comment donner le ‘focus' à un contrôle dans une fenêtre ?
- Comment donner le ‘focus' au contrôle suivant / précédent suivant l'ordre des tabulations ?
- Comment récupérer l'id (IDC_) d'un contrôle ?
- Comment récupérer un pointeur sur un contrôle d'après son identificateur IDC_ ?
- Comment récupérer le parent d'une fenêtre?
- Comment faire passer l'application en avant plan ?
- Comment implémenter un Timer dans une fenêtre ?
- Comment récupérer la position de la souris ?
- Comment changer la couleur de fond d'une View ?
- Comment gérer la couleur de fond d'une fenêtre ?
Dans les MFC toutes les fenêtres héritent de la classe CWnd
Quand on regarde la documentation MSDN cette classe donne accès à toutes les fonctions de base que l'on peut faire sur une fenêtre :
la rendre inactive / active modifier son style la déplacer etc…
Donc :
Code c++ : | Sélectionner tout |
1 2 3 | CWnd:: EnableWindow BOOL EnableWindow( BOOL bEnable = TRUE ); |
Code c++ : | Sélectionner tout |
1 2 | MyWnd.EnableWindow(TRUE) // ou FALSE pour la rendre inactive. |
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::IsWindowEnabled BOOL IsWindowEnabled( ) const; |
Code c++ : | Sélectionner tout |
1 2 3 4 5 | if(!MyEdit. IsWindowEnabled( )) { // l ‘edit est inactif (disable). } |
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::ShowWindow BOOL ShowWindow( int nCmdShow ); |
- SW_HIDE : rend la fenêtre invisible
- SW_MINIMIZE : minimise la fenêtre et active la première fenêtre de la liste système
- SW_RESTORE : active et affiche la fenêtre si celle-ci est maximisée ou minimisée elle est restaurée à sa taille et position d'origine
- SW_SHOW : active et affiche la fenêtre à sa taille et position courante
- SW_SHOWMAXIMIZED : active la fenêtre et l'affiche a sa taille maximale
- SW_SHOWMINIMIZED : active la fenêtre et l'affiche sous forme d'icône
- SW_SHOWNORMAL : est synonyme de SW_RESTORE
Code c++ : | Sélectionner tout |
1 2 | MyWnd.ShowWindow(SW_SHOW ); // pour afficher SW_HIDE pour Cacher. |
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::IsWindowVisible BOOL IsWindowVisible( ) const; |
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // exemple trouvé sur MSDN void CSomeClass::DisplayDlgWindow() { if(!m_myDlg.IsWindowVisible()) { m_myDlg.ShowWindow(SW_SHOWNORMAL); } } // This example uses the CWnd::IsWindowVisible() function to // determine if a dialogue box is visible. If it is, it calls // CWnd::ShowWindow with the SW_HIDE command. void CSomeClass::HideDlgWindow() { if(m_myDlg.IsWindowVisible()) { m_myDlg.ShowWindow(SW_HIDE); } } |
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 3 4 | MyEdit.ModifyStyle(0,ES_UPPERCASE); // passer l'édit en majuscules . MyEdit.ModifyStyle(0, ES_READONLY ); // passer l'édit en mode lecture seule . |
Edit Styles ou un des styles précités
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::GetStyle DWORD GetStyle( ) const; |
Code c++ : | Sélectionner tout |
1 2 3 4 5 | if((MyEdit.GetStyle() & ES_READONLY)) { // mode read only. } |
En parcourant les fenêtres filles de la boîte de dialogue tout en contrôlant la classe du contrôle trouvé , et en appliquant le SetReadonly le cas échéant.
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | void SetEditReadOnly(CDialog *pDlg,bool bReadOnly/*=true*/) { char szClassName[100]; CWnd *pCtrl=pDlg->GetWindow(GW_CHILD); while(pCtrl) { ::GetClassName(pCtrl->GetSafeHwnd(),szClassName,sizeof(szClassName)); if(!strcmp(szClassName,"Edit")) ((CEdit *)pCtrl)->SetReadOnly(bReadOnly); pCtrl = pCtrl->GetWindow(GW_HWNDNEXT); } } SetEditReadOnly(this,true); |
Fenêtre au sens large du terme puisque tout est fenêtre un édit c'est une fenêtre :
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::SetWindowText void SetWindowText( LPCTSTR lpszString ); |
Code c++ : | Sélectionner tout |
1 2 3 4 | // Fixe le texte dans l'edit IDC_MYEDIT CWnd* pWnd = GetDlgItem(IDC_MYEDIT); pWnd->SetWindowText(_T("vive les MFC")); |
Notes :
la signature accepte une CString sans problème
Dans le cas des classes CView/CFormView toutes les classes fenêtres liées à l'architecture document view on procédera différemment en utilisant la fonction
GetDocument()->SetTitle(« nom de fa fenêtre »).
Code c++ : | Sélectionner tout |
1 2 3 4 | CWnd::GetWindowText int GetWindowText( LPTSTR lpszStringBuf, int nMaxCount ) const; void GetWindowText( CString& rString ) const |
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 | CString str; pWnd->GetWindowText(str); // ou char sz[10]; int nRet = pWnd->GetWindowText(sz, 10); |
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 | CWnd::GetFont CFont* GetFont( ) const; CWnd::SetFont void SetFont( CFont* pFont, BOOL bRedraw = TRUE ); |
Attention le pointeur est temporaire il ne faut pas le stocker pour un usage ultérieur.
Si je veux modifier la fonte courante en mettant l'attribut gras par exemple :
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | LOGFONT lf; // récupération de l'objet CFont CFont *pFont= MyEdit.GetFont() ; // récupération de logical Fonte structure LOGFONT pFont->GetLogFont(&lf); // fixe l'attribut en mode gras voir Documentation sur la // structure LOGFONT pour les autres styles. lf.lfWeight = FW_BOLD; // création d'un nouvel objet CFont non temporaire m_NewFont.CreateFontIndirect(&lf); // donne à l'edit une nouvelle fonte. MyEdit.SetFont(&m_NewFont) ; |
Le focus voulant dire le contrôle qui est actif au niveau de la fenêtre et qui va répondre à la prochaine entrée clavier .
L'état est représenté suivant le contrôle soit par la présence d'un curseur (pour un edit par exemple) ,soit par un rectangle en pointillés etc..
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::GetFocus static CWnd* PASCAL GetFocus( ); |
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 | CWnd *pWnd= CWnd ::GetFocus() ; if(pWnd) { CString str; pWnd->GetWindowText(str); AfxMessageBox( str); } |
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::SetFocus CWnd* SetFocus( ); |
Le contrôle qui disposait précédemment du focus recevra le message WM_KILLFOCUS.
Code c++ : | Sélectionner tout |
1 2 3 | CWnd *pWnd=GetDlgItem(IDC_MYEDIT) ; If(pWnd) pWnd->SetFocus(); |
Communément appelé Tab Order qui se règle dans une boîte de dialogue par le menu layout option tab order ou Ctrl+D.
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 | CDialog::PrevDlgCtrl void PrevDlgCtrl( ) const; CDialog::NextDlgCtrl void NextDlgCtrl( ) const; |
une question se pose : comment faire quand quand la fenêtre de traitement est une CFormView ?
Comme ça :
Code c++ : | Sélectionner tout |
1 2 | ((CDialog *)this)->NextDlgCtrl() ; |
Non ,mais si on est un peu curieux et que l'on regarde la définition de ces fonctions dans les MFC,
on s'aperçoit qu'elles sont déclarées ‘Inline' dans la classe CDialog et que d'autre part elles testent uniquement le handle de la fenêtre qui est une donnée membre de la classe CWnd et appellent la fonction globale SendMessage.
Donc pas de problème, mais ça relève de la bidouille.
Rien n'empêche si on veut rester « propre » de redéfinir ces fonctions pour son propre usage en tant que macro , par exemple en rajoutant le préfixe ‘Goto' devant pour éviter les problèmes de redéfinitions.
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | // Définitions MFC _AFXWIN_INLINE void CDialog::NextDlgCtrl() const { ASSERT(::IsWindow(m_hWnd)); ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 0, 0); } _AFXWIN_INLINE void CDialog::PrevDlgCtrl() const { ASSERT(::IsWindow(m_hWnd)); ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 1, 0); } _AFXWIN_INLINE void CDialog::GotoDlgCtrl(CWnd* pWndCtrl) { ASSERT(::IsWindow(m_hWnd)); ::SendMessage(m_hWnd, WM_NEXTDLGCTL, (WPARAM)pWndCtrl->m_hWnd, 1L); } |
Code c++ : | Sélectionner tout |
1 2 3 4 | // Redéfinitions perso. #define GotoDlgCtrl() { ASSERT(::IsWindow(m_hWnd)); ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 0, 0); } #define GotoPrevDlgCtrl() { ASSERT(::IsWindow(m_hWnd)); ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 1, 0); } |
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::GetDlgCtrlID int GetDlgCtrlID( ) const; |
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | CWnd *pWnd=CWnd ::GetFocus(); if(pWnd) { if(pWnd->GetDlgCtrlID( )==IDOK) { } } |
Code c++ : | Sélectionner tout |
1 2 3 4 | CWnd::GetDlgItem CWnd* GetDlgItem( int nID ) const; void CWnd::GetDlgItem( int nID, HWND* phWnd ) const; |
Code c++ : | Sélectionner tout |
1 2 3 4 | CEdit* pBoxOne; pBoxOne = (CEdit*) GetDlgItem(IDC_EDIT1); GotoDlgCtrl(pBoxOne); // voir NextDlgCtrl() |
Si il y a une fonction essentielle c'est bien celle-là !
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::GetParent CWnd* GetParent( ) const; |
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | // je suis dans une CDialog et je fais sur un contrôle: m_MyEdit.GetParent() ; // j'obtiens le pointeur sur la dialogue, facile…… // je suis dans une dialogue ou CForm avec des onglets et des edit // sur un de ces edit je veux récupérer le pointeur sur la dialogue. CWnd *pParent=m_MyEdit.GetParent() ;// la dialogue dans le CtabCtrl. // le CtabCtrl. pParent=pParent->GetParent() ; // le parent de mon CtabCtrl c'est la dialogue pParent= pParent->GetParent() ; |
Code c++ : | Sélectionner tout |
1 2 3 | CWnd::BringWindowToTop void BringWindowToTop( ); |
Code c++ : | Sélectionner tout |
1 2 3 4 5 | // l'application AfxGetMainWnd()->BringWindowToTop(); // fonctionne aussi pour la MDI a partir de la view on pourra faire GetParentFrame()->BringWindowToTop(); |
La classe de base CWnd dispose des fonctions suivantes pour gérer un Timer :
Pour la mise en place du Timer
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 | CWnd::SetTimer UINT SetTimer( UINT nIDEvent, // numéro du timer à partir de 1 UINT nElapse, // temps ecoulé entre 2 appels en ms. void (CALLBACK EXPORT* lpfnTimer)( HWND, UINT, UINT, DWORD) ); // fonction callback. |
Code c++ : | Sélectionner tout |
1 2 3 4 | CWnd::KillTimer BOOL KillTimer( int nIDEvent ); // numéro du Timer |
Mise en place du timer 1 avec un intervalle d'appel de deux secondes
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 | void CMyView::OnStartTimer() { m_nTimer = SetTimer(1, 2000, 0); } void CMyView::OnStopTimer() { KillTimer(m_nTimer); } void CMyView::OnTimer(UINT nIDEvent) { switch(nIDEvent) { case 1:MessageBeep(0xFFFFFFFF); // Beep default:break; } // Call base class handler. CView::OnTimer(nIDEvent); } |
En utilisant l'api 32 :
Code c++ : | Sélectionner tout |
1 2 3 4 | BOOL GetCursorPos( LPPOINT lpPoint // cursor position ); |
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | void CSdisamplesView::OnButton1() { // TODO: Add your control notification handler code here CPoint point; CMenu menu,*pPopup; GetCursorPos(&point); menu.LoadMenu(IDR_MENU1); ASSERT (menu.m_hMenu != NULL); pPopup = menu.GetSubMenu(0); ASSERT (pPopup != NULL); int nResult = pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); menu.DestroyMenu(); } |
Pour changer la couleur de fond d'un objet CView,CFrameWnd, ou CWnd Il suffit d'intercepter avec ClassWizard le message WM_ERASEBKGND, comme dans l'exemple ci-dessous.
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | BOOL CMyView::OnEraseBkgnd(CDC* pDC) { // Fixe une brosse avec la couleur de fond choisie CBrush BkClrBrush(RGB(255, 128, 128)); // Sauvegarde l'ancienne brosse. CBrush* pOldBrush = pDC->SelectObject(&BkClrBrush); CRect rect; pDC->GetClipBox(&rect); // récupère la zone a effacer. pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY); pDC->SelectObject(pOldBrush);// restitue l'ancienne brosse. return TRUE; } |
Pour gérer la couleur de fond d'une fenêtre on interceptera le message WM_ERASEBKGND
Exemple
Code C++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | BOOL XTabCtrl::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default CBrush backBrush(m_crBackColor);//COLORREF CBrush *pOldBrush=pDC->SelectObject(&backBrush); CRect rect; pDC->GetClipBox(&rect); pDC->PatBlt(rect.left,rect.top,rect.Width(),rect.Height(),PATCOPY); pDC->SelectObject(pOldBrush); return TRUE; } |
Dans l'exemple ci-dessus la variable m_crBackColor est du type COLORREF et doit être déclarée dans la classe fenêtre.
On procédera à son initialisation dans le constructeur et on pourra lui changer sa valeur avec une fonction accesseur comme suit :
Code C++ : | Sélectionner tout |
1 2 3 4 5 | void XTabCtrl::SetBkGndColor(COLORREF clr) { m_crBackColor=clr; if(::IsWindow(GetSafeHwnd())) Invalidate(); } |
Pour les CStatic ou CEdit on procédera comme indiqué dans Comment gérer la couleur sur un CEdit ?
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.