FAQ VC++ et MFCConsultez toutes les FAQ

Nombre d'auteurs : 20, nombre de questions : 546, 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


SommaireClasse Fenêtre (CWnd) (21)
précédent sommaire suivant
 

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.

Mis à jour le 5 avril 2013 farscape

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

Mis à jour le 5 avril 2013 farscape

Code c++ : Sélectionner tout
1
2
3
  
CWnd::ShowWindow 
BOOL ShowWindow( int nCmdShow );
Voici les modes les plus courants (voir la documentations MSDN pour les autres):

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

Mis à jour le 5 avril 2013 farscape

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); 
   } 
}

Mis à jour le 5 avril 2013 farscape

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 .
Pour les autres modes d'un édit voir documentation MSDN et chercher :
Edit Styles ou un des styles précités

Mis à jour le 5 avril 2013 farscape

Code c++ : Sélectionner tout
1
2
3
  
CWnd::GetStyle 
DWORD GetStyle( ) const;
Exemple d'utilisation typique dans un CEdit savoir si l'edit est en mode Lecture seule (Read Only).

Code c++ : Sélectionner tout
1
2
3
4
5
  
if((MyEdit.GetStyle() & ES_READONLY)) 
{ 
// mode read only. 
}

Mis à jour le 5 avril 2013 farscape

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);
à adapter selon les besoins.

Mis à jour le 5 février 2006 farscape

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"));
On pourra donc fixer le texte d'un édit par cette méthode directement.
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 »).

Mis à jour le 5 avril 2013 farscape

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);
Donc on pourra utiliser la même technique pour récupérer le texte d'un édit.

Mis à jour le 5 avril 2013 farscape

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 );
La fonction GetFont renvoie un pointeur sur un objet de la classe CFont
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) ;

Mis à jour le 5 avril 2013 farscape

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( );
Note la fonction est statique ; on a pas besoin de disposer d'une fenêtre ou d'un contrôle existant pour l'utiliser.

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); 
}

Mis à jour le 5 avril 2013 farscape

Code c++ : Sélectionner tout
1
2
3
  
CWnd::SetFocus 
CWnd* SetFocus( );
Cette fonction donne le focus à l'objet fenêtre spécifié qui recevra le message WM_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();

Mis à jour le 5 avril 2013 farscape

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;
Curieusement Microsoft a implémenté ces fonctions uniquement dans la classe CDialog.
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() ;
Faire un cast d'une CFormView vers une CDialog c'est autorisé ?
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); }
Note : Dans le même registre on trouve la fonction GotDlgCtrl qui attend en argument le pointeur sur fenêtre qui aura le focus.

Mis à jour le 5 avril 2013 farscape

Code c++ : Sélectionner tout
1
2
3
  
CWnd::GetDlgCtrlID   
int GetDlgCtrlID( ) const;
voici un exemple d'utilisation :

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
  
CWnd *pWnd=CWnd ::GetFocus(); 
if(pWnd) 
{ 
    if(pWnd->GetDlgCtrlID( )==IDOK) 
    { 
  
    } 
}

Mis à jour le 5 avril 2013 farscape

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()

Mis à jour le 5 avril 2013 farscape

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() ;

Mis à jour le 5 avril 2013 farscape

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();

Mis à jour le 5 avril 2013 farscape

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.
Pour la destruction du Timer

Code c++ : Sélectionner tout
1
2
3
4
  
CWnd::KillTimer 
BOOL KillTimer(  
int nIDEvent ); // numéro du Timer
Exemple :
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); 
}

Mis à jour le 5 avril 2013 farscape

En utilisant l'api 32 :

Code c++ : Sélectionner tout
1
2
3
4
  
BOOL GetCursorPos( 
  LPPOINT lpPoint   // cursor position 
);
Exemple d'utilisation :Affichage d'un menu contextuel à l'emplacement de la souris sur le clic d'un bouton :

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(); 
}

Mis à jour le 5 avril 2013 farscape

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; 
   }

Mis à jour le 5 avril 2013 farscape

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
14
  
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
6
  
void XTabCtrl::SetBkGndColor(COLORREF clr) 
{ 
   m_crBackColor=clr; 
  if(::IsWindow(GetSafeHwnd())) Invalidate(); 
}
Pour les CStatic ou CEdit on procédera comme indiqué dans

Mis à jour le 27 novembre 2005 farscape

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 ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les 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 © 2017 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.

 
Contacter le responsable de la rubrique C++