| auteur : Farscape | Les traitements liés à la CStatusBar sont situés dans la classe de fenêtre principale CMainFrame.
Dans un projet classique on doit trouver un tableau initialisé avec les valeurs standard des indicateurs claviers :
ID_INDICATOR_CAPS : Majuscule/Minuscule
ID_INDICATOR_NUM, : Verrou Numérique
ID_INDICATOR_SCRL, :
Pour personnaliser ce tableau procédez comme suit :
Dans tous les cas la première ligne du tableau indicators doit comporter ID_SEPARATOR
static UINT indicators[] =
{
ID_SEPARATOR,
ID_INDICATOR_1,
ID_INDICATOR_2,
ID_INDICATOR_3
} ;
|
ID_INDICATOR_x sont des valeurs à rajouter dans les ressources, sous Visual 6 voir menu View option Resources Symbols.
Ajouter dans la String Table l'ID_INDICATOR_x que l'on vient de créer (on va le chercher dans la liste)
Ensuite dans l'entête mainframe.h rajouter la ligne
void OnUpdatePane (CCmdUI * pCmdUI) { pCmdUI- > Enable ();
|
dans le source mainframe.cpp rajouter:
BEGIN_MESSAGE_MAP (CMainFrame, CFrameWnd)
ON_WM_CREATE ()
ON_UPDATE_COMMAND_UI ( ID_INDICATOR_1, OnUpdatePane )
ON_UPDATE_COMMAND_UI ( ID_INDICATOR_2, OnUpdatePane )
ON_UPDATE_COMMAND_UI ( ID_INDICATOR_3, OnUpdatePane )
END_MESSAGE_MAP ()
m_wndStatusBar.SetPaneInfo (1 , ID_INDICATOR_1, SBPS_NORMAL ,50 );
m_wndStatusBar.SetPaneInfo (2 , ID_INDICATOR_2, SBPS_NORMAL,50 );
m_wndStatusBar.SetPaneInfo (3 , ID_INDICATOR_3, SBPS_NORMAL,50 );
m_wndStatusBar.SetPaneText (m_wndStatusBar.CommandToIndex (ID_INDICATOR_1), " Valeur 1 " );
|
|
| auteur : Nourdine Falola | Si vous avez décoché l'option "initial status bar" à l'étape 4 de la création de votre projet, alors vous n'aurez pas de barre d'état. Que faire si votre projet, déjà bien avancé, nécessite finalement la barre d'état ? La solution tient en quelques lignes.
1. Déclarer une donnée membre CStatusBar dans la classe CMainFrame
private :
CStatusBar m_wndStatusBar;
|
2. Définir le tableau statique indicators qui donne les panneaux de la barre d'état
static UINT indicators[] =
{
ID_SEPARATOR,
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
} ;
|
3. Créer la barre d'état dans la fonction OnCreate de CMainFrame
if (! m_wndStatusBar.Create (this ) | |
! m_wndStatusBar.SetIndicators (indicators,
sizeof (indicators) / sizeof (UINT)))
{
TRACE0 (" Impossible de créer la barre d'état\n " );
return - 1 ;
}
|
Notez que l'identifiant donné à la barre d'état est AFX_IDW_STATUS_BAR (cf. doc BOOL CStatusBar::Create(...)). L'architecture d'application recherche cette identifiant lorsqu'elle doit afficher un libellé associé à une commande de menu.
|
| auteur : Nourdine Falola | La barre d'état par défaut est constituée d'un panneau de message (ID_SEPARATOR) et de trois panneaux d'indicateurs:
ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL.
Un panneau d'indicateur est lié à une unique chaîne de caractère, fournie par une ressource (String Table), affichée ou cachée suivant le gestionnaire d'actualisation de l'interface associée.
La dimension du panneau est égale à la largeur de la chaîne de caractères.
Si l'on veut par exemple afficher "Ctrl/Ret" si Control et Return sont pressés (en même temps ou séparément) :
1. On définit ID_IND_CTRL_RET dans la String Table, associé à la chaîne "Ctrl/Ret"
2.
public :
void OnUpdateKeyReturn (CCmdUI* pCmdUI);
|
static UINT indicators[] =
{
ID_SEPARATOR,
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_IND_CTRL_RET,
} ;
...
BEGIN_MESSAGE_MAP (CMainFrame, CFrameWnd)
ON_WM_CREATE ()
...
ON_UPDATE_COMMAND_UI (ID_INDICATOR_ENT,OnUpdateKeyReturn)
END_MESSAGE_MAP ()
...
void CMainFrame:: OnUpdateKeyReturn (CCmdUI* pCmdUI)
{
pCmdUI- > Enable (:: GetKeyState (VK_RETURN) & :: GetKeyState (VK_CONTROL) & 1 );
}
|
|
| auteur : Nourdine Falola | Comme on a changé l'ID de la barre d'état pour gérer soi-même l'affichage, la commande Affichage/Barre d'état, gérée par l'architecture d'application, n'agit plus. On va donc devoir gérer soi-même la commande.
On déclare une variable booléenne dans la classe CMainFrame. Cet booléen indique si la barre d'état est visible ou non, et si un check doit apparaître devant la commande Affichage/Barre d'état :
private :
bool m_bStatusBarIsVisible;
|
On initialise le booléen dans OnCreate, après avoir créé la barre d'état :
if (! m_wndStatusBar.Create (this ,WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, ID_MY_STATUS_BAR)
| | ! m_wndStatusBar.SetIndicators (indicators, sizeof (indicators) / sizeof (UINT)))
{
TRACE0 (" Impossible de créer la barre d'état\n " );
return - 1 ;
}
m_bStatusBarIsVisible = (m_wndStatusBar.IsWindowVisible () = = 0 );
|
On intercepte ensuite le message ON_COMMAND de ID_VIEW_STATUS_BAR :
void CMainFrame:: OnViewStatusBar ()
{
if (m_bStatusBarIsVisible)
m_wndStatusBar.ShowWindow (SW_HIDE);
else
m_wndStatusBar.ShowWindow (SW_SHOW);
RecalcLayout ();
m_bStatusBarIsVisible = ! m_bStatusBarIsVisible;
}
|
puis on implémente le gestionnaire de mise à jour du menu (message ON_COMMAND_UPDATE_UI) :
void CMainFrame:: OnUpdateViewStatusBar (CCmdUI* pCmdUI)
{
pCmdUI- > SetCheck (m_bStatusBarIsVisible);
}
|
A présent la commande Affichage/Barre d'état joue son rôle habituel.
|
| auteurs : Farscape, zebiloute | On procédera comme suit :
Avec l'assistant générez une classe dérivée de la classe CStatusbar.
Générez ensuite les fonctions de réponse pour les messages WM_CREATE et WM_SIZE.
Rajoutez une variable contrôle CProgressCtrl comme donnée membre de la classe.
Enfin il faudra utiliser cette classe dans votre Mainframe en modifiant la déclaration de la variable initiale (CStatusBar).
# pragma once
class CStatusBarEx : public CStatusBar
{
DECLARE_DYNAMIC (CStatusBarEx)
public :
CStatusBarEx ();
virtual ~ CStatusBarEx ();
protected :
CProgressCtrl m_Progress;
DECLARE_MESSAGE_MAP ()
public :
afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize (UINT nType, int cx, int cy);
} ;
|
# include "stdafx.h"
# include "StatusBarEx.h"
IMPLEMENT_DYNAMIC (CStatusBarEx, CStatusBar)
CStatusBarEx:: CStatusBarEx ()
{
}
CStatusBarEx:: ~ CStatusBarEx ()
{
}
BEGIN_MESSAGE_MAP (CStatusBarEx, CStatusBar)
ON_WM_CREATE ()
ON_WM_SIZE ()
END_MESSAGE_MAP ()
int CStatusBarEx:: OnCreate (LPCREATESTRUCT lpCreateStruct)
{
if (CStatusBar:: OnCreate (lpCreateStruct) = = - 1 )
return - 1 ;
CRect rect ( 0 , 0 , 100 , 16 );
m_Progress.Create ( WS_VISIBLE | WS_CHILD, rect, this , IDC_PROGRESS );
m_Progress.SetRange ( static_cast < short > (0 ), static_cast < short > (100 ) );
return 0 ;
}
void CStatusBarEx:: OnSize (UINT nType, int cx, int cy)
{
CStatusBar:: OnSize (nType, cx, cy);
CWnd* pWnd = (CWnd* )this ;
CRect rect;
pWnd- > GetWindowRect ( & rect );
ScreenToClient ( & rect );
if ( m_Progress.GetSafeHwnd ())
{
m_Progress.SetWindowPos ( & CWnd:: wndTop, 0 , 0 , 100 , 16 , SWP_NOMOVE | SWP_NOZORDER);
m_Progress.SetPos ( 16 );
}
}
|
|
| auteur : Farscape | |
static UINT indicators[] =
{
ID_SEPARATOR,
ID_INDICATOR_BMP,
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
} ;
|
Le nouvel identifiant doit être préalablement rajouté dans les ressources :
Sur le fichier .rc dans les ressources : clic droit ressources symbols.
On rajoutera aussi cet identifiant dans la string table.
L'étape suivante est de faire apparaitre le bitmap dans la barre d'états.
Pour cela il va falloir créer une classe héritée de CStatusbar pour placer notre traitement dans la méthode DrawItem , notre barre d'états devra donc posséder le style OwnerDraw pour le panneau concerné, ici le numéro 1.
La classe:
# pragma once
class CStatusBarEx : public CStatusBar
{
DECLARE_DYNAMIC (CStatusBarEx)
public :
CStatusBarEx ();
virtual ~ CStatusBarEx ();
void SetBitmap (UINT nId){ m_BitmapId= nId;}
protected :
UINT m_BitmapId;
DECLARE_MESSAGE_MAP ()
public :
virtual void DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct);
} ;
|
Le Code:
|
# include "StatusBarEx.h"
IMPLEMENT_DYNAMIC (CStatusBarEx, CStatusBar)
CStatusBarEx:: CStatusBarEx ():m_BitmapId (0 )
{
}
CStatusBarEx:: ~ CStatusBarEx ()
{
}
BEGIN_MESSAGE_MAP (CStatusBarEx, CStatusBar)
END_MESSAGE_MAP ()
void CStatusBarEx:: DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (! m_BitmapId) return ;
CRect rect (lpDrawItemStruct- > rcItem);
CDC Memdc,barDC;
barDC.Attach (lpDrawItemStruct- > hDC);
Memdc.CreateCompatibleDC (NULL );
CBitmap Bmp;
Bmp.LoadBitmap (m_BitmapId);
BITMAP bmpInfo;
Bmp.GetBitmap (& bmpInfo);
CBitmap * poldBmp= Memdc.SelectObject (& Bmp);
barDC.StretchBlt (rect.left,rect.top,rect.Width (),rect.Height (),& Memdc,0 ,0 ,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY);
Memdc.SelectObject (poldBmp);
}
|
Enfin il faut indiquer que le panneau 1 de notre barre d'état est OwnerDraw, on placera ce code dans la méthode OnCreate de la Mainframe :
|
if (! m_wndStatusBar.Create (this ) | |
! m_wndStatusBar.SetIndicators (indicators,
sizeof (indicators)/ sizeof (UINT)))
{
TRACE0 (" Failed to create status bar\n " );
return - 1 ;
}
m_wndStatusBar.SetBitmap (IDB_BITMAP1);
m_wndStatusBar.SetPaneStyle (1 ,SBT_OWNERDRAW);
|
|
lien : Comment implanter des éléments dans une CStatusBar ?
|
Consultez les autres F.A.Q.
|
|