| auteur : Farscape | 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 :
CWnd:: EnableWindow
BOOL EnableWindow ( BOOL bEnable = TRUE );
|
|
| auteur : Farscape |
CWnd:: IsWindowEnabled
BOOL IsWindowEnabled ( ) const ;
|
if (! MyEdit. IsWindowEnabled ( ))
{
}
|
|
| auteur : Farscape |
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
MyWnd.ShowWindow (SW_SHOW );
|
|
| auteur : Farscape |
CWnd:: IsWindowVisible
BOOL IsWindowVisible ( ) const ;
|
void CSomeClass:: DisplayDlgWindow ()
{
if (! m_myDlg.IsWindowVisible ())
{
m_myDlg.ShowWindow (SW_SHOWNORMAL);
}
}
void CSomeClass:: HideDlgWindow ()
{
if (m_myDlg.IsWindowVisible ())
{
m_myDlg.ShowWindow (SW_HIDE);
}
}
|
|
| auteur : Farscape |
CWnd:: ModifyStyle
BOOL ModifyStyle ( DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0 );
|
MyEdit.ModifyStyle (0 ,ES_UPPERCASE);
MyEdit.ModifyStyle (0 , ES_READONLY );
|
Pour les autres modes d'un édit voir documentation MSDN et chercher :
Edit Styles ou un des styles précités
|
| auteur : Farscape |
CWnd:: GetStyle
DWORD GetStyle ( ) const ;
|
Exemple d'utilisation typique dans un CEdit savoir si l'edit est en mode Lecture seule (Read Only).
if ((MyEdit.GetStyle () & ES_READONLY))
{
}
|
|
| auteur : 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.
void SetEditReadOnly (CDialog * pDlg,bool bReadOnly)
{
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.
|
| auteur : Farscape | Fenêtre au sens large du terme puisque tout est fenêtre un édit c'est une fenêtre :
CWnd:: SetWindowText
void SetWindowText ( LPCTSTR lpszString );
|
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 »).
|
| auteur : Farscape |
CWnd:: GetWindowText
int GetWindowText ( LPTSTR lpszStringBuf, int nMaxCount ) const ;
void GetWindowText ( CString& rString ) const
|
CString str;
pWnd- > GetWindowText (str);
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.
|
| auteur : Farscape |
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 :
LOGFONT lf;
CFont * pFont= MyEdit.GetFont () ;
pFont- > GetLogFont (& lf);
lf.lfWeight = FW_BOLD;
m_NewFont.CreateFontIndirect (& lf);
MyEdit.SetFont (& m_NewFont) ;
|
|
| auteur : 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..
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.
CWnd * pWnd= CWnd :: GetFocus () ;
if (pWnd)
{
CString str;
pWnd- > GetWindowText (str);
AfxMessageBox ( str);
}
|
|
| auteur : Farscape |
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.
CWnd * pWnd= GetDlgItem (IDC_MYEDIT) ;
If (pWnd) pWnd- > SetFocus ();
|
|
| auteur : 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.
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 :
((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.
_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 ); }
|
# 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.
|
| auteur : Farscape |
CWnd:: GetDlgCtrlID
int GetDlgCtrlID ( ) const ;
|
voici un exemple d'utilisation :
CWnd * pWnd= CWnd :: GetFocus ();
if (pWnd)
{
if (pWnd- > GetDlgCtrlID ( )= = IDOK)
{
}
}
|
|
| auteur : Farscape |
CWnd:: GetDlgItem
CWnd* GetDlgItem ( int nID ) const ;
void CWnd:: GetDlgItem ( int nID, HWND* phWnd ) const ;
|
CEdit* pBoxOne;
pBoxOne = (CEdit* ) GetDlgItem (IDC_EDIT1);
GotoDlgCtrl (pBoxOne);
|
|
| auteur : Farscape | Si il y a une fonction essentielle c'est bien celle-là !
CWnd:: GetParent
CWnd* GetParent ( ) const ;
|
m_MyEdit.GetParent () ;
CWnd * pParent= m_MyEdit.GetParent () ;
pParent= pParent- > GetParent () ;
pParent= pParent- > GetParent () ;
|
|
| auteur : Farscape |
CWnd:: BringWindowToTop
void BringWindowToTop ( );
|
AfxGetMainWnd ()- > BringWindowToTop ();
GetParentFrame ()- > BringWindowToTop ();
|
|
| auteur : Farscape | La classe de base CWnd dispose des fonctions suivantes pour gérer un Timer :
Pour la mise en place du Timer
CWnd:: SetTimer
UINT SetTimer (
UINT nIDEvent,
UINT nElapse,
void (CALLBACK EXPORT* lpfnTimer)(
HWND, UINT, UINT, DWORD) );
|
Pour la destruction du Timer
CWnd:: KillTimer
BOOL KillTimer (
int nIDEvent );
|
Exemple :
Mise en place du timer 1 avec un intervalle d'appel de deux secondes
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 );
default :break ;
}
CView:: OnTimer (nIDEvent);
}
|
|
| auteur : Farscape | En utilisant l'api 32 :
BOOL GetCursorPos (
LPPOINT lpPoint
);
|
Exemple d'utilisation :Affichage d'un menu contextuel à l'emplacement de la souris sur le clic d'un bouton :
void CSdisamplesView:: OnButton1 ()
{
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 ();
}
|
|
| auteur : 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.
BOOL CMyView:: OnEraseBkgnd (CDC* pDC)
{
CBrush BkClrBrush (RGB (255 , 128 , 128 ));
CBrush* pOldBrush = pDC- > SelectObject (& BkClrBrush);
CRect rect;
pDC- > GetClipBox (& rect);
pDC- > PatBlt (rect.left, rect.top, rect.Width (),
rect.Height (), PATCOPY);
pDC- > SelectObject (pOldBrush);
return TRUE;
}
|
|
| auteur : Farscape | Pour gérer la couleur de fond d'une fenêtre on interceptera le message
WM_ERASEBKGND
Exemple
BOOL XTabCtrl:: OnEraseBkgnd (CDC* pDC)
{
CBrush backBrush (m_crBackColor);
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:
void XTabCtrl:: SetBkGndColor (COLORREF clr)
{
m_crBackColor= clr;
if (:: IsWindow (GetSafeHwnd ())) Invalidate ();
}
|
|
Consultez les autres F.A.Q.
|
|