- Boites de dialogues (exemple avec le contrôle CListCtr) - Le dessin de texte (exemple)
- Le défilement - La barre d’outils
L3 informatique - Interface Homme Machine 2
Boites de dialogues (exemple avec le contrôle CListCtr)
L3 informatique - Interface Homme Machine 3
Plan
Généralités
Ajout d’un contrôle de liste dans boîte de dialogue
Création des listes d’images
Association des listes d’images au contrôle
Ajout d’éléments au contrôle
Ajout d’informations pour le format d’affichage
Détermination des éléments sélectionnés
Exemple
L3 informatique - Interface Homme Machine 4
Les contrôles de type CListCtrl
Les contrôles CListCtrl permettent d’afficher des informations et les icônes associées dans quatre format différents :
Grands Icônes, Petits Icônes, Liste et Détails.
Le volet de droite de l’explorateur Windows est un exemple d’utilisation de ce type de contrôle .
Propriétés
View : Indique le format d’affichage initial du contrôle : Icon, Small Icon, List, Report
Align : définit le format d’alignement des éléments
Sort : Permet le tri par ordre alphabétique
Auto Arrange : les éléments doivent être automatiquement réorganisés lorsqu’ils sont affichés dans les formats Icon et Small Icon
Single Selection : n’autorise la sélection que d’un élément à la fois
No Scroll : désactive le défilement
No Column Header : pas d’entête de colonnes
Edit Label : on ne peut pas changer le nom d’un élément affichés.
No Label Wrap : chaque élément doit être affiché sur une seule ligne
L3 informatique - Interface Homme Machine 5
Ajout d’un contrôle de type CListCtrl
Après avoir créer le projet, dessiner la boîte de dialogue et déclarer les méthodes de gestion des boutons radio, les étapes restantes consiste en :
Créer d’une liste d’images pour stocker les images affichées à coté de chaque élément de la liste
Associer la liste d’images au contrôle
Insérer les éléments à afficher dans le contrôle
Ajuster les propriétés de la liste pour déterminer les éléments sélectionnés
Ajouter les instructions nécessaires pour pouvoir changer le format d’affichage en fonction du bouton radio sélectionné
L3 informatique - Interface Homme Machine 6
Création des listes d’images
Création de deux bitmaps sous l’éditeur de ressources
IDB_BOULES et IDB_PT_BOULES qui représentent les grands icônes et les petits icônes
Utiliser un objet CBitmap pour charger les ressources des 2 images CBitmap bmp1, bmp2;
bmp1.LoadBitmap(IDB_BOULES) ; bmp2.LoadBitmap(IDB_PT_BOULES) ;
Utiliser un objet CImageList pour insérer les images dans la liste : CImageList imList ;
imList.Add(&bmp1, RGB(255, 255, 255) ) ; imList.Add(&bmp2, RGB(255, 255, 255)) ; bmp1.DeleteObject() ;
bmp2.DeleteObject() ;
Les objets CBitmap doivent être détruits une fois insérés dans la liste
Le premier argument de la méthode CImageList::Add indique l’adresse de l’image Bitmap à ajouter, le deuxième indique la couleur d’arrière-plan du Bitmap
L3 informatique - Interface Homme Machine 7
Association de la liste d’images au contrôle
Pour ajouter une liste d’images à un contrôle, on utilise la méthode
SetImageList(ImListAdresse, ImStyle).
Cette méthode reçoit
en premier argument l’adresse de la liste d’images
en deuxième argument un paramètre de style indiquant le type d’images stockées dans la liste
Il existe trois types d’images :
LVSIL_NORMAL: pour la liste d’images utilisées pour le format Grands icônes
LVSIL_SMALL: pour la liste d’images utilisées pour le format Petits icônes
LVSIL_STATE: pour les images optionnelles d’indication d’état, par exemple des coches
L3 informatique - Interface Homme Machine 8
Ajout d’éléments à un contrôle
La structure LV_ITEM permet de représenter un élément faisant partie d’un contrôle de type CListCtrl, elle est utilisée pour l’ajout, la modification ou l’extraction.
Données membres de LV_ITEM
mask : indique les parties valides de la structure.
• Valeur possible : LVIF_TEXT, LVIF_IMAGE, LVI_PARAM, LVIF_STATE
item : No d’index de l’élément
iSubItem : No d’index du sous-élément courant
state et stateMask : contiennent l’état courant de l’élément
psztext : Adresse de la chaîne représentant le nom de l’élément
cchTextMax : Taille du tampon pour le membre pszText
iImage : No d’index de la liste d’images pour cet élément
Insertion d’un élément InsertItem():
LV_ITEM listItem ; listItem.mask = LVIF_TEXT ; listItem.iItem = 0 ; listItem.pszText = szText ; CListCtrl listCtrl;
listCtrl.InsertItem(&listItem);
L3 informatique - Interface Homme Machine 9
Ajout d’informations pour le format d’affichage
Le format d’affichage Détails affiche pour chaque élément de la liste des colonnes supplémentaires (sous-éléments)
Tous les éléments doivent comprendre le même nombre de sous-éléments
L’ajout de colonnes pour les sous-éléments se fait en 2 étapes :
Initialiser un objet de la structure LV_COLUMN
Insérer cet objet à l’aide de la fonction InsertColumn
Données membres de LV_COLUMN
mask : indique les parties valides de la structure;
• Valeurs possibles : LVIF_FMT, LVIF_ SUBITEM, LVIF_ TEXT, LVIF_ WIDTH
fmt : spécifie l’alignement de la colonne.
• Valeurs possibles : LVCFMT_LEFT, LVCFMT_ RIGHT et LVCFMT_ CENTER.
• La première colonne doit utiliser la valeur LVCFMT_ LEFT.
cx : largeur de la colonne en pixel
pszText, cchTextMax, iSubItem
Une fois les valeurs d’un objet LV_COLUMN complétées, la colonne est ajoutée au contrôle ListView :
listCtrl.InsertColumn(nCol, &lvcolObject)
L3 informatique - Interface Homme Machine 10
Changement du format d’affichage d’un contrôle
Deux étapes :
Utiliser la méthode GetWindowLong pour récupérer le format d’affichage courant
Utiliser la méthode SetWindowLong pour changer le format
DWORD dwOldStyle = GetWindowLong(hWndList, GWL_STYL)
GetWindowLong a deux paramètres :
un handle de fenêtre sur le contrôle
une constante GWL spécifiant les informations demandées; ici GWL_STYLE
L3 informatique - Interface Homme Machine 11
Détermination des éléments sélectionnés
La méthode CListCtrl::GetNextItem doit être utilisée pour déterminer quels sont les éléments sélectionnés. :
int nSel = listCtrl.GetNextItem(nItem, nFlags);
Le paramètre désigne l’élément de départ. Donnez -1 pour commencer la recherche au premier élément
Le paramètre nFlagsest un flag indiquant la relation (géométrique ou d’état) entre l’élément de départ et l’élément recherché.
Valeurs géométriques possibles pour le flag
LVNI_ABOVE, LVNI_ BELOW : recherche un élément situé au dessus (resp. sous) l’élément de départ
LVNI_ TOLEFT, LVNI_ TORIGHT : recherche un élément situé à gauche (resp. à droit) de l’élément de départ
LVNI_ ALL : recherche l’élément suivant de l’index
Valeurs d’état d’un élément :
LVNI_DROPHILITED
Recherche un élément dont l’indicateur LVIS_DROPHILITED activé.
LVNI_FOCUSED
Recherche un élément dont l’indicateur LVIS_FOCUSED est activé.
LVNI_SELECTED
Recherche 1 élément dont l’indicateur LVIS_SELECTED activé.
L3 informatique - Interface Homme Machine 12
Exemple (1)
Ce programme affichera une boîte de dialogue contenant un contrôle CListCtrl et des boutons radio pour passer d’un format d’affichage à l’autre
Créer un projet « Dialog Based », nommé ListEx.
Avec l’éditeur de ressources ajoutez les boutons radio et un contrôle CListCtrl dans la boîte de dialogue du projet avec une variable associée (m_listCtrl)
Donnez aux boutons radio les identifiants : IDC_RADIO_GRAND, IDC_RADIO_PETIT, IDC_RADIO_LISTE, IDC_RADIO_DETAILS.
Définir les gestionnaires liés au clic sur le bouton (BN_CLICKED)
OnRadioGrand, OnRadioPetit, OnRadioDetails, OnRadioListe
Ajouter à la classe CListEx les données membres : protected:
CImageList m_imagePetite, m_imageGrande;
void SetListView(DWORD dwView); // Gère le format d’affichage
Modifier la fonction OnInitDialog pour initialiser les listes d’images, les lignes et les colonnes du contrôle CListCtrl
L3 informatique - Interface Homme Machine 13
Exemple (2)
L3 informatique - Interface Homme Machine 14
Exemple (3)
BOOL CListExDlg::OnInitDialog() {
… // On ne touche pas à ce qu’a été génée par AppWizard // TODO: Add extra initialization here
// Création des listes d'images
m_imageGrande.Create(IDB_BOULES,32,1,RGB(255,255,255) );
m_imagePetite.Create(IDB_PT_BOULES,16,1,RGB(255,255,255));
// Associer les listes d'images crées au contrôle ListView m_listCtrl.SetImageList( &m_imageGrande, LVSIL_NORMAL );
m_listCtrl.SetImageList( &m_imagePetite, LVSIL_SMALL );
// Creation des colonnes de la liste LV_COLUMN listColumn;
char* arColonnes[3]= {"Animal", "Boisson", "Nourriture"};
listColumn.mask=
LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;
listColumn.fmt = LVCFMT_LEFT;
listColumn.cx = 60;
L3 informatique - Interface Homme Machine 15
Exemple (4)
for( int nColonne = 0; nColonne < 3; nColonne++ ){
listColumn.iSubItem = nColonne;
listColumn.pszText = arColonnes[nColonne];
m_listCtrl.InsertColumn( nColonne, &listColumn );
}
// Ajout des éléments de la liste LV_ITEM listItem;
listItem.mask = LVIF_TEXT | LVIF_IMAGE;
listItem.iSubItem = 0;
char* arAnimal[3] = {"Chat", "Lion", "Panthère"};
char* arBoisson[3] = {"Lait", "Eau", "Eau"};
char* arNourriture[3]= {"Souris", "Antilope", "Lapin"};
for( int nItem = 0; nItem < 3; nItem++ ) { listItem.iItem = nItem; listItem.iImage = 0 ; listItem.pszText = arAnimal[nItem];
m_listCtrl.InsertItem(&listItem );
m_listCtrl.SetItemText(nItem, 1, arBoisson[nItem]);
m_listCtrl.SetItemText(nItem,2,arNourriture[nItem]);
} return TRUE; }
L3 informatique - Interface Homme Machine 16
Exemple (5)
void CListExDlg::OnRadioGrand() { SetListView( LVS_ICON ); } void CListExDlg::OnRadioListe() { SetListView( LVS_LIST ); } void CListExDlg::OnRadioDetails(){ SetListView(LVS_REPORT);}
void CListExDlg::OnRadioPetit(){SetListView(LVS_SMALLICON);}
void CListExDlg::SetListView( DWORD dwNewStyle ){
DWORD dwOldStyle;
HWND hWndList = m_listCtrl.GetSafeHwnd();
dwOldStyle = GetWindowLong( hWndList, GWL_STYLE );
if( (dwOldStyle & LVS_TYPEMASK) != dwNewStyle ) { dwOldStyle&=~LVS_TYPEMASK; // Masque infos du style superflues dwNewStyle |= dwOldStyle;
SetWindowLong( hWndList, GWL_STYLE, dwNewStyle );
} }
L3 informatique - Interface Homme Machine 17
Exemple (6)
L3 informatique - Interface Homme Machine 18
Le dessin du texte
L3 informatique - Interface Homme Machine 19
Le dessin du texte
Le DC de la vue en cours comporte une police par défaut (SYSTEM_FONT), une couleur de texte et une couleur de fond.
Les fonctions CDC : GetTextColor, SetTextColor, GetBkColor et SetBkColor permettent de changer et de prendre connaissance de la couleur du texte et de fond
On a souvent besoin d’interroger le contexte de périphérique sur les dimensions du texte avant que MFC n’appelle la fonction OnDraw
Pour déterminer ces dimensions, on fait appel à la fonction CDC::GetTextMetric afin d’obtenir un objet TEXTMETRIC. Puis nous utilisons les informations contenues dans cette structure pour calculer des informations utiles comme la hauteur de lignes, la largeur de caractères, …
L3 informatique - Interface Homme Machine 20
Le dessin du texte (2)
voici une version allégée de la structure TEXTMETRIC :
typedef struct tagTEXTMETRIC {int tmHeight;
int tmAscent;
int tmDescent;
int tmInternalLeading;
int tmExternalLeading;
int tmAveCharWidth;
int tmMaxCharWidth;
int tmWeight;
BYTE tmItalic;
BYTE tmUnderlined;
} TEXTMETRIC; …
L3 informatique - Interface Homme Machine 21
Fonctions CDC pour le dessin de texte
TextOut : prend en argument la position en x et y et le texte à dessiner
DrawText : Préciser un rectangle dans lequel on souhaite que le texte soit dessiné. Vous pouvez préciser l’alignement à droite, à gauche, centré, justifié
ExtTextOut : Très proche de TextOut, qui, comme Drawtext, vous permet de dessiner dans un rectangle circonscrit
TabbedTextOut : Pour introduire des tabulations dans le texte
GetTextExtent : retourne la hauteur et la largeur d’une ligne de texte en fonction de la police du caractère utilisée.
Remarque :
La macro _T permet de créer des chaînes de caractères dont les caractères font deux octets si Unicode est activé et un octet dans le cas contraire. _T(‘’C’est une chaîne’’) ;
L3 informatique - Interface Homme Machine 22
Exemple MyText
L3 informatique - Interface Homme Machine 23
MyText (2)
Sur un projet nommé MyText créer par AppWizard Apportez les modifications suivantes :
1) Compléter la fonction OnDraw
const int MARGIN_LEFT = 5;const int LINES = 30;
void CMyTextView::OnDraw(CDC* pDC) {
CMyTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// Sélectionne une couleur, et stocke l’ancienne COLORREF colorOld;
colorOld = pDC->SetTextColor(RGB(0,0,255)); //
Blue
L3 informatique - Interface Homme Machine 24
MyText (3)
// Selectionner la font
CFont* pFontOld = pDC->SelectObject(m_pFontNew);
// Le dessin
ASSERT(m_nHeightLine > 0);
CString strLines;
for(int nLines = 0; nLines < LINES; nLines++) {
strLines.Format("%d: ", nLines);
if(nLines < 10) strLines += " ";
pDC->TextOut(MARGIN_LEFT, nLines * m_nHeightLine, strLines + m_strTextDraw);
}
// Restaure la font et la couleur d’origine au DC pDC->SetTextColor(colorOld);
pDC->SelectObject(pFontOld);
}
L3 informatique - Interface Homme Machine 25
MyText (4)
2) Dans MyTextView.h ajouter la déclaration de deux données membres : int m_nHeightLine;
CString m_strTextDraw;
3) Surcharger la fonction OnInitialUpdate comme suit : void CMyTextView::OnInitialUpdate()
{
CView::OnInitialUpdate();
CClientDC dc(this);
// For text-drawing code TEXTMETRIC tm;
dc.GetTextMetrics(&tm);
// Calcule différentes tailles nécessaires au dessin //int cxChar = tm.tmAveCharWidth;
//int cyChar = tm.tmHeight;
m_nHeightLine = tm.tmHeight + tm.tmExternalLeading;
L3 informatique - Interface Homme Machine 26
MyText (5)
m_strTextDraw = "No matter where you go, there you are.";
m_strTextDraw += " -- Buckaroo Banzai, ";
m_strTextDraw += "The Adventures of Buckaroo Banzai ";
m_strTextDraw += " Across the Eighth Dimension";
}
Exercice pour le TP :
Si vous implémentez cet exemple et essayez de l’exécuter vous voyez sûrement un certain nombre de lignes, mais certainement pas les trente lignes générées par le programme
définissez une font différente, une couleur de texte et une couleur de fond et utilisez-les pour écrire votre texte
Exercez-vous pour ajouter le défilement à cet exemple
L3 informatique - Interface Homme Machine 27
Le défilement
L3 informatique - Interface Homme Machine 28
Plan du cours
Introduction
Défilement et classes MFC
Conversions coord. physiques/coord. logiques
Comment ajouter le défilement à votre application ?
La fonctions CScrollView::SetScrollSizes
Autres Fonctions utiles pour le défilement
Exemple
Membres à ajouter dans CScrollView
Initialisation des données membres
Définition des fonctions de mise à jour des données membres
Le gestionnaire souris OnLButton
La fonction OnDraw
L3 informatique - Interface Homme Machine 29
Introduction
Définition : le concept de défilement repose sur l’idée que la surface de dessin peut être plus grande que la fenêtre, nous permettant de la visualiser.
Le défilement est assuré par l’ajustement entre l’origine de la vue et l’origine de la zone de dessin en fonction des actions entreprises.
L’origine de la vue est le coin supérieur gauche de la zone client de la fenêtre de visualisation (on dit aussi origine de la vue physique). Cette origine bouge avec le défilement
L’origine du dessin est le coin supérieur gauche de la surface de dessin (on dit aussi origine de la vue logique). Cette origine ne change pas avec le défilement
Lorsqu’on clique avec la souris dans la zone client de la fenêtre vue, Windows nous retourne les coordonnées du point de clic dans le système de coordonnées de périphérique, nous devons convertir ces coordonnées en coordonnées logiques pour compenser les effets du défilement.
L3 informatique - Interface Homme Machine 30
Introduction (2)
L’origine de la vue est le point (0,0) dans le système de coordonnées du DC. MFC déplace l’origine en faisant appel aux fonctions CDC::SetViewPortOrg et
CDC::SetWindowOrg
La gestion des défilements se fait en utilisant la classe MFC CScrollView, qui est héritière de CView
Faites donc hériter votre classe View de CScrollView pour récupérer ces fonctionnalités de défilement dans votre application
Lorsque Windows envoie un message WM_VSCROLL ou
WM_HSCROLL, le gestionnaire OnVScroll ou OnHScroll
de CScrollView traite le message. CWnd::ScrollWindow
sera ensuite sollicité pour effectuer le défilement
L3 informatique - Interface Homme Machine 31
Défilement et classes MFC
CEdit et CRichEditCtrlÆPour le texte des boîtes de dialogue en texte brut ou mise en forme.
CEditView et CRichEditViewÆPour permettre à l’utilisateur de saisir une quantité importante de texte comme dans un bon petit éditeur de texte (Bloc-notes Windows)
CListeView pour afficher certaines données (enregistrement de bases de données ou listes de fichiers (Explorateur Windows))
CRecordView, CDaorecordView, COleDBRRecordView pour les bases de données
CListBox, CComboBox pour permettre à l’utilisateur de choisir dans des listes, dans des boîtes de dialogue
L3 informatique - Interface Homme Machine 32
Défilement et classes MFC (2)
CDaoRecordView CRecordView
CRichEditView
COleDBRecordView CEditView CListView
CHtmlView
CTreeView CScrollView
CFormView
CView CObject CWnd
CCtrlView
L3 informatique - Interface Homme Machine 33
Conversion coord. physiques/coord. logiques
La plus part des fonctions de CDC prennent en charge les coord.
logiques, alors que les fonctions CWnd les coord. périphériques. La conversion coord. physiques/coord. logiques devient obligatoire à chaque fois qu’on a besoin de faire l’interface entre CDC et CWnd
Appeler la fonction CScrollView::OnPrepareDC qui ajuste le DC pour compenser les mouvements de l’origine de la vue par rapport à l’origine du document
Appeler la fonction CDC::DPtoLP qui remplace les coordonnées x et y de CPoint fournit en argument avec les valeurs ajustées en fonction du défilement
Dans un gestionnaire du bouton de la souris, on écrit : CPoint pos = point;
CClientDC dc (this);
OnPrepareDC (&dc);
dc.DPtoLP (&pos);
L3 informatique - Interface Homme Machine 34
Comment ajouter le défilement à votre application ?
Modifiez la dérivation de votre classe vue de CView à CScrollView.
Cherchez dans les fichiers .h et .cpp de la vue toutes les références à la classe CView pour les remplacer par CScrollView
Définissez les variables dont vous avez besoin pour gérer le défilement dans le fichier .h de la vue
Surcharger la fonction CView::OnInitialUpdate ou CView:: OnUpdate pour initialiser ces variables
Planifiez les dimensions de la surface de dessin et définissez comment la vue doit répondre aux différentes actions sur les barres de défilement.
Initialisez les variables dans OnInitialUpdate ou dans OnUpdate et faites appel à la fonction membre CScrollView::SetScrollSizes
L3 informatique - Interface Homme Machine 35
Comment ajouter le défilement à votre application ? (2)
L3 informatique - Interface Homme Machine 36
La fonction CScrollView::SetScrollSizes
void SetScrollSizes(nMapMode int, SIZE sizeTotal, const SIZE&
sizePage = sizeDefault, const SIZE& sizeLine = sizeDefault );
Cette fonction fixe :
L’unité de mesure pour les autres paramètres (système de coordonnées): nMapMode
La taille totale de la surface de dessin: sizeTotal
De combien il faut défiler quand on clique sur PageUp ou PageDown: sizePage
De combien il faut défiler quand on clique sur les flèches pour se déplacer d’une ligne vers le haut ou vers le bas: sizeLine
CSize est une classe MFC ayant deux données membres publiques cx et cy
La fonction CScrollView::SetScrollSizes est souvent appelée par la fonction OnInitialUpdate pour fixer les tailles de la vue logique
L3 informatique - Interface Homme Machine 37
La fonctions CView::OnInitialUpdate
Cette fonction est appelée par l’infrastructure MFC avant le premier affichage de la fenêtre cadre. Elle utilise la fonction SetScrollSizes pour fixer les tailles de la vue logique :
virtual void OnInitialUpdate( );
Voici une fonction OnInitialUpdate qui fixe la largeur de la vue logique à 1,280 pixels et sa hauteur à 1,024 pixels.
void CMyView::OnInitialUpdate () { CScrollView::OnInitialUpdate ();
SetScrollSizes (MM_TEXT, CSize (1280, 1024));
}
Dans cette version, on fixe ces tailles à 8.5 par 11 pouces void CMyView::OnInitialUpdate () {
CScrollView::OnInitialUpdate ();
SetScrollSizes (MM_LOENGLISH, CSize (850, 1100));
}
L3 informatique - Interface Homme Machine 38
La fonction OnInitialUpdate (2)
Dans cette version, on se déplace de 2 pouces en réponse aux événements SBPAGEUP/DOWN/RIGHT/ LEFT et de 0.25 pouce en réponse aux événements SB_LINEUP/DOWN/LEFT/RIGHT
void CMyView::OnInitialUpdate () {
CScrollView::OnInitialUpdate ();
SetScrollSizes (MM_LOENGLISH, CSize (850, 1100), CSize (200, 200), CSize (25, 25));
}
Le mapping mod (le premier argument de SetScrollSizes) fixe l’unité de mesure pour les autres arguments
L3 informatique - Interface Homme Machine 39
Autres fonctions utiles pour le défilement
GetScrollPosition : retrouver la position actuelle : CPoint pos = GetScrollPosition ();
ScrollToPosition : se déplacer vers une position donnée : ScrollToPosition(CPoint (100, 100));
GetTotalSize : retourne la taille totale de la vue logique : CSize size = GetTotalSize ();
int nWidth = size.cx;
int nHeight = size.cy;
GetClipBox : Dans le cas de défilement, OnDraw est sollicitée beaucoup plus que dans le cas contraire. Il faut donc l’optimiser pour ne redessiner que ce qui est nécessaire. La fonction CDC::GetClipBox peut être utilisée pour récupérer le rectangle invalide (les limites de la partie qu’il faut redessiner) :
CRect rect;
pDC->GetClipBox (&rect);
L3 informatique - Interface Homme Machine 40
Exemple
L3 informatique - Interface Homme Machine 41
Membres à ajouter dans CScrollView
class CScrollDemoView : public CScrollView {
…
protected:
BOOL m_bSmooth; // Un booléen pour contrôler le coloriage // Retourne le rectangle d’une cellule
void GetCellRect (int row, int col, LPRECT pRect);
// Ecrit le numéro d’une cellule
void DrawAddress (CDC* pDC, int row, int col);
// Peint la cellule courante avec une couleur différente
void DrawPointer (CDC* pDC, int row, int col, BOOL bHighlight);
CFont m_font; // La font utilisée pour écrire les différents labels int m_nCurrentCol; //Colonne actuelle
int m_nCurrentRow; //Ligne actuelle
L3 informatique - Interface Homme Machine 42
Membres à ajouter dans CScrollView (2)
int m_nRibbonWidth; //Largeur de marge pour écrire les n° de lignes
int m_nCellHeight; //Hauteur de cellules int m_nCellWidth; //Largeur de cellules
//{{AFX_MSG(CScrollDemoView)
afx_msg void OnLButtonDown(UINT nFlags, CPoint pt);
//}}AFX_MSG } ;
On constate que notre classe ne gère qu’un seul message
souris : le clic sur le bouton gauche. Rappelant que cette
action fait peindre la cellule précédemment sélectionnée
avec la couleur de l’écran et attribue à la cellule courante
la couleur bleu
L3 informatique - Interface Homme Machine 43
Initialisation des données membres
CScrollDemoView::CScrollDemoView() {
m_font.CreatePointFont (80, _T ("MS Sans Serif"));
}
void CScrollDemoView::OnInitialUpdate() { CScrollView::OnInitialUpdate();
m_nCurrentRow = 0;
m_nCurrentCol = 0;
m_bSmooth = FALSE;
CClientDC dc (this);
m_nCellWidth = dc.GetDeviceCaps(LOGPIXELSX);
m_nCellHeight = dc.GetDeviceCaps(LOGPIXELSY) / 4;
m_nRibbonWidth = m_nCellWidth / 2;
int nWidth = (26 * m_nCellWidth) + m_nRibbonWidth;
int nHeight = m_nCellHeight * 100;
SetScrollSizes (MM_TEXT, CSize (nWidth, nHeight));
}
L3 informatique - Interface Homme Machine 44
La fonction GetCellRect
// Remplit dans pRect, le rectangle englobant de la cellule // courante, LPRECT est equivalent à CRect*
void CScrollDemoView::GetCellRect(int row, int col, LPRECT pRect)
{
pRect->left= m_nRibbonWidth+ (col * m_nCellWidth)+1;
pRect->top= m_nCellHeight+ (row * m_nCellHeight)+ 1;
pRect->right = pRect->left + m_nCellWidth - 1;
pRect->bottom = pRect->top + m_nCellHeight - 1;
}
L3 informatique - Interface Homme Machine 45
La fonction DrawAddress
// Ecrit le n° de la cellule courante au milieu
void CScrollDemoView::DrawAddress(CDC *pDC, int row, int col)
{
CRect rect;
GetCellRect (row, col, &rect);
CString string;
string.Format (_T ("%c%d"), col + _T ('A'), row + 1);
pDC->SetBkMode (TRANSPARENT);
CFont* pOldFont = pDC->SelectObject (&m_font);
pDC->DrawText (string, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
pDC->SelectObject (pOldFont);
}
L3 informatique - Interface Homme Machine 46
La fonction DrawPointer
// Colore la cellule courante en bleu, et appelle DrawAddress pour // Ecrire son N° au milieu.
void CScrollDemoView::DrawPointer(CDC *pDC, int row, int col, BOOL bHighlight)
{
CRect rect;
GetCellRect (row, col, &rect);
// Si bHighlight == TRUE, le pinceau de remplissage sera bleu // Sinon, il prendra la couleur de la fenêtre, dans ce cas après // l'appel de FillRect le coloriage de l'ancienne cellule disparaît CBrush brush (bHighlight ? RGB (0, 255, 255) :
::GetSysColor (COLOR_WINDOW));
pDC->FillRect (rect, &brush);
DrawAddress (pDC, row, col);
}
L3 informatique - Interface Homme Machine 47
Le gestionnaire souris OnLButton
void CScrollDemoView::OnLButtonDown(UINT nFlags, CPoint point)
{
// Appelle CScrollView::OnLButtonDown pour gérer les défilements CScrollView::OnLButtonDown(nFlags, point);
// Conversion des coord. physiques en coord. logiques CPoint pos = point;
CClientDC dc (this);
OnPrepareDC (&dc);
dc.DPtoLP (&pos);
// Modifier la couleur de la cellule sur laquelle on clique
CSize size = GetTotalSize (); // Obtenir les dimensions de la // surface de dessin if (pos.x > m_nRibbonWidth && pos.x < size.cx &&
pos.y > m_nCellHeight && pos.y < size.cy) {
L3 informatique - Interface Homme Machine 48
OnLButton (2)
int row = (pos.y - m_nCellHeight) / m_nCellHeight;
int col = (pos.x - m_nRibbonWidth) / m_nCellWidth;
ASSERT(row>=0 && row<=98 && col>=0 && col<=25);
// Dessiner la cellule courante avec la couleur de l’écran
DrawPointer(&dc, m_nCurrentRow, m_nCurrentCol,FALSE);
// mettre à jour les n° de la cellule courante m_nCurrentRow = row;
m_nCurrentCol = col;
// Dessine la cellule sur laquelle on a cliqué
DrawPointer (&dc, m_nCurrentRow, m_nCurrentCol,TRUE);
} }
L3 informatique - Interface Homme Machine 49
La fonction OnDraw
void CScrollDemoView::OnDraw(CDC* pDC) { CScrollDemoDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// Tracer la grille
CSize size = GetTotalSize ();
CPen pen (PS_SOLID, 0, RGB (192, 192, 192));
CPen* pOldPen = pDC->SelectObject (&pen);
for (int i=0; i<99; i++) {
int y = (i * m_nCellHeight) + m_nCellHeight;
pDC->MoveTo (0, y); pDC->LineTo (size.cx, y);
}
for (int j=0; j<26; j++) {
int x = (j * m_nCellWidth) + m_nRibbonWidth;
pDC->MoveTo (x, 0); pDC->LineTo (x, size.cy);
}
pDC->SelectObject (pOldPen);
L3 informatique - Interface Homme Machine 50
La fonction OnDraw (2)
//Trace les en-têtes des lignes et colonnes CBrush brush;
brush.CreateStockObject (LTGRAY_BRUSH);
CRect rcTop (0, 0, size.cx, m_nCellHeight);
pDC->FillRect (rcTop, &brush);
CRect rcLeft (0, 0, m_nRibbonWidth, size.cy);
pDC->FillRect (rcLeft, &brush);
pDC->MoveTo (0, m_nCellHeight);
pDC->LineTo (size.cx, m_nCellHeight);
pDC->MoveTo (m_nRibbonWidth, 0);
pDC->LineTo (m_nRibbonWidth, size.cy);
pDC->SetBkMode (TRANSPARENT);
L3 informatique - Interface Homme Machine 51
La fonction OnDraw (3)
// Ajoute les Numéros et les boutons dans les en-têtes des lignes for (i=0; i<99; i++)
{
int y = (i * m_nCellHeight) + m_nCellHeight;
pDC->MoveTo (0, y);
pDC->LineTo (m_nRibbonWidth, y);
CString string;
string.Format (_T ("%d"), i + 1);
CRect rect (0, y, m_nRibbonWidth, y+m_nCellHeight);
pDC->DrawText (string, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
rect.top++;
pDC->Draw3dRect (rect, RGB (255, 255, 255), RGB (128, 128, 128));
}
L3 informatique - Interface Homme Machine 52
La fonction OnDraw (4)
// Ajoute les lettres et les boutons pour les en-têtes des colonnes for (j=0; j<26; j++)
{
int x = (j * m_nCellWidth) + m_nRibbonWidth;
pDC->MoveTo (x, 0);
pDC->LineTo (x, m_nCellHeight);
CString string;
string.Format (_T ("%c"), j + 'A');
CRect rect (x, 0, x + m_nCellWidth, m_nCellHeight);
pDC->DrawText (string, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
rect.left++;
pDC->Draw3dRect (rect, RGB (255, 255, 255), RGB (128, 128, 128));
}
L3 informatique - Interface Homme Machine 53
La fonction OnDraw (5)
// Ajoute un label dans chaque cellule CRect rect;
pDC->GetClipBox (&rect);
int nStartRow= max (0, (rect.top - m_nCellHeight) / m_nCellHeight);
int nEndRow= min (98, (rect.bottom - 1) / m_nCellHeight);
int nStartCol= max (0, (rect.left - m_nRibbonWidth) / m_nCellWidth);
int nEndCol = min (25, ((rect.right+m_nCellWidth-1) – m_nRibbonWidth) / m_nCellWidth);
for (i=nStartRow; i<=nEndRow; i++)
for(j=nStartCol;j<=nEndCol;j++) DrawAddress(pDC,i,j);
// Dessine la cellule pointée par la souris avec une couleur différente (voir // l’argument TRUE. En haut cet argument est fixé, par défaut, à FALSE DrawPointer (pDC, m_nCurrentRow, m_nCurrentCol, TRUE);
}
L3 informatique - Interface Homme Machine 54
La barre d’outils
L3 informatique - Interface Homme Machine 55
Les barres d’outils et la sélection (plan)
La barre d’outils et la barre d’état standards
La fonction MainFrame::OnCreate
Les styles des barres d’outils
Les styles des boutons des barres d’outils
Les barres d’outils ancrables et flottantes
Comment ajouter une barre d’outils à une application
Spécification des boutons
Ecriture des gestionnaires
Exemple la barre d’outils Drawing
La sélection :
Ajouter la sélection de figures dans un programme de dessin
L’implémentation du mode de sélection
Modification à apporter aux classes et fonctions de l’application pour prendre en compte le mode de sélection
L3 informatique - Interface Homme Machine 56
La barre d’outils et la barre d’état standards
Les barres d’outils et d’état standards sont des fenêtres à part entière incorporées dans la fenêtre cadre. Elles partagent l’espace de la fenêtre cadre avec l’objet vue.
Déclarées comme données membres de la classe fenêtre principale : protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
Elles sont créées dans la fonction CMainFrame::OnCreate. Cette fonction est le handler du message WM_CREATE qui est envoyé par Windows à l’application après la création de la fenêtre principale, mais avant son affichage.
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame)
//NOTE - the ClassWizard will add/remove macros here.
//DO NOT EDIT what you see of generated code ! ON_WM_CREATE()
//}}AFX_MSG_MAP END_MESSAGE_MAP()
L3 informatique - Interface Homme Machine 57
Le gestionnaire Oncreate
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
//Création de la barre d’outils standard
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n");
return -1; // fail to create }
// Création de la barre d’état standard if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("Failed to create status bar\n");
return -1; // fail to create }
L3 informatique - Interface Homme Machine 58
Le gestionnaire OnCreate (2)
// Rendre les deux barres ancrables et flottantes m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
OnCreatecrée la barre d’outils par appel à CToolBar::CreateEx et charge l’image des boutons en faisant appel à CToolBar::LoadToolBar
OnCreatecrée la barre d’état avec un appel à CStatusBar::Create et des appels à CStatusBar::SetIndicators
Les indicateurs sont les petites zones de la barre d’état (déclarés dans MainFrame.cpp):
static UINT indicators[] = {
ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, // verrouillage majuscule ID_INDICATOR_NUM, // verrouillage du pavé numérique ID_INDICATOR_SCRL, // verrouillage du défilement };
L3 informatique - Interface Homme Machine 59
Le gestionnaire OnCreate (3)
La fonction setIndicators utilise le tableau des indicateurs quand elle construit la barre d’état pour affichage.
Les styles d’une barre d’outils :
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { // ---
}
Ces lignes définissent les styles de la barre d’outils, ajoutés à l’aide de l’opérateur binaire C++ |. Cet opérateur définit certains bits comme étant des flags (drapeaux) dans un entier.
La fonction CControlBar::SetBarStyle permet également de fixer les styles des barres
L3 informatique - Interface Homme Machine 60
Le style des barres d’outils
La fonction CToolBar::CreateEx précise un certain nombre de styles pour la barre d’outils. Les styles sont des drapeaux qui indiquent à Windows comment afficher et traiter les barres d’outils.
Deux types de styles :
WS_ : s’applique sur n’importe quelle fenêtre
CBRS_ : ne s’applique que sur les barres de contrôles
Les différents styles :
CBRS_ALIGN_TOP, CBRS_ALIGN_BOTTOM, CBRS_ALIGN_LEFT, CBRS_ALIGN_RIGHT, CBRS_ALIGN_ANY, CBRS_BORDER_TOP, CBRS_BORDER_BOTTOM, CBRS_BORDER_LEFT, CBRS_BORDER_RIGHT, CBRS_FLOAT_MULTI, CBRS_TOOLTIPS, CBRS_FLYBY, CBRS_GRIPPERL3 informatique - Interface Homme Machine 61
Le style des boutons d’une barre d’outils
On peut attribuer aux boutons d’une barre d’outils un style qui permettra de modifier leur comportement.
Par défaut, les boutons ont le style TBBS_PUSHBUTTON qui correspond à ce que nous avons dans la barre d’outils standard.
Quand l’utilisateur clique sur un bouton ce dernier s’enfonce un instant et reprend son aspect original
Les boutons ayant le style TBBS_CHECKGROUP se comportent comme des boutons d’option, i.e. ils sont interdépendants, un bouton cliqué reste enfoncé et plusieurs boutons ne peuvent pas être enfoncés simultanément
CToolBar::SetButtonStyle permet de fixer le style d’un bouton. Une combinaison de plusieurs styles est possible en utilisant l’opérateur |
CToolBar::GetButtonStyle permet de connaître le style d’un bouton
L3 informatique - Interface Homme Machine 62
Le style des boutons d’une barre d’outils (2)
Les différents styles : TBSTYLE_AUTOSIZE, TBSTYLE_BUTTON, TBSTYLE_CHECK, TBSTYLE_CHECKGROUP, TBSTYLE_SEP, TBSTYLE_DROPDOWN, TBSTYLE_GROUP, BSTYLE_NOPREFIX
Exemple :
// Définit le style des boutons de la barre drawing const int NUM_DRAW_BUTTONS = 3;
for(int i = 0; i < NUM_DRAW_BUTTONS; i++) {
m_wndToolBarDraw.SetButtonStyle(i, m_wndToolBarDraw.GetButtonStyle(i) | TBBS_CHECKGROUP);
}
L3 informatique - Interface Homme Machine 63
Les barres d’outils ancrables et flottantes
OnCreate ajoute (vers la fin) le code permettant aux barres d’outils d’être ancrables ou flottantes :
// Rendre les deux barres ancrables et flottantes m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
Ces appels permettent d’ancrer la barre d’outils sur l’un des bords de la fenêtre. Le style CBRS_ALIGN_ANY indique à Windows de placer la barre n’importe où sur les côtés de la zone client de la fenêtre principale.
Le premier appel CToolBarr::EnableDocking permet d’ancrer la barre d’outils
Le deuxième appel CFrameWnd::EnableDocking prépare la fenêtre principale pour pouvoir ancrer des barres d’outils ou d’autres fenêtres.
L3 informatique - Interface Homme Machine 64
Ajouter une barre d’outils
En 3 étapes :
Création d’une ressource toolbar
Dessin des boutons
Ajout du code pour gérer la barre d’outils
Les classes Toolbar :
Les classes CToolBar, CStatusBar et CDialogBar sont toutes les trois dérivées de la classe CControlBar des MFC et sont capables de gérer des toolbars.
Pour créer une ressource ToolBar, activez la commande Insert, Ressource, Sélectionner toolbar dans la boîte de dialogue. Utilisez ensuite l’onglet Ressource View pour changer l’ID proposé par défaut : IDR_TOOLBAR1 en un ID plus compréhensible (IDR_DRAWING par exemple)
Utiliser l’éditeur des barres d’outils pour dessiner les boutons. Cet éditeur possède, à son tour un ensemble d’outils et une palette de couleurs.
L3 informatique - Interface Homme Machine 65
Spécifications des boutons
De la même façon que les options des menus, chaque bouton d’une barre d’outils doit avoir :
Un ID qui permet de le distinguer et d’appeler son gestionnaire.
Une chaîne prompt qui correspond au message écrit sur la barre d’état lorsque le pointeur de la souris passe par dessus le bouton
Une info-bulle : c’est le texte qui s’affiche dans une bulle lorsque l’on passe la souris sur le bouton. Ajouter \nUntexte à la suite du prompt si vous voulez avoir une info-bulle.
Exemple :
Dans un programme de dessin on peut envisager un bouton Rectangle ayant :
ID : ID_TOOL_RECTANGLE
Prompt : Dessine un Rectangle\nRectangle
Info-bulle : Le \nRectangle dans le prompt permet de l’avoir
L3 informatique - Interface Homme Machine 66
L’écriture du code
Le code nécessaire à l’exploitation d’une barre d’outils repose sur les deux éléments suivants :
Ajouter dans la fonction OnCreate le code d’affichage de la barre.
Ajouter du code pour une deuxième barre équivaut presque à copier et à modifier ce que AppWizard nous a fourni dès le début avec la barre d’outils standard
Ecrire les handlers des boutons. ( Il n’y a rien à ajouter si les boutons de la barre ont les mêmes ID que des options de menus pour lesquelles nous avons déjà écrit des handlers)
Exemple : Dans une application de dessin d’objets géométriques de type rectangles et ellipses, créer une barre d’outils contenant 3 boutons :
Un pour le dessin des rectangles
Un pour le dessin des ellipses
Un pour pour la sélection, permet à l’utilisateur de sélectionner une figure dans son rectangle circonscrit
L3 informatique - Interface Homme Machine 67
Exemple de barres à outils
On donne à notre barre d’outils et à ses trois boutons les ID suivants :
La barre d’outils : IDR_DRAWING
Le bouton rectangle : ID_TOOL_RECLANGLE
Le bouton ellipse : ID_TOOL_ELLIPSE
Le bouton sélection : ID_TOOL_SELECTION
Les boutons rectangle et ellipse correspondent à deux options de menus. Leurs handlers sont donc déjà écrits, une petite modification sera apportée pour gérer la sélection.
Le bouton sélection traite une nouvelle fonctionnalité , beaucoup de modifications doivent être apportées à notre application pour gérer la sélection.
Dans le fichier MainFrame.h on doit ajouter la déclaration de notre nouvelle boîte à outils :
protected: // control bar embedded members CStatusBar m_wndStatusBar;
CToolBar m_wndToolBarStd;
CToolBar m_wndToolBarDraw;
L3 informatique - Interface Homme Machine 68
Exemple (2)
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
// Changed window name when adding new toolbar // Create the Standard toolbar
if (!m_wndToolBarStd.CreateEx(this, TBSTYLE_FLAT, WS_CHILD
| WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBarStd.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n");
return -1; // fail to create }
// Crée la nouvelle barre d’outils drawing if (!m_wndToolBarDraw.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_LEFT | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBarDraw.LoadToolBar(IDR_DRAWING)) { TRACE0("Failed to create toolbar\n");
return -1; // fail to create }
L3 informatique - Interface Homme Machine 69
Exemple (3)
// Définit le style des boutons de la barre drawing const int NUM_DRAW_BUTTONS = 3;
for(int i = 0; i < NUM_DRAW_BUTTONS; i++) { m_wndToolBarDraw.SetButtonStyle(i,
m_wndToolBarDraw.GetButtonStyle(i) | TBBS_CHECKGROUP);
}
// Définit l’intitulé des barres d’outils.
m_wndToolBarStd.SetWindowText("Standard");
m_wndToolBarDraw.SetWindowText("Drawing");
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) {
TRACE0("Failed to create status bar\n");
return -1; // fail to create }
L3 informatique - Interface Homme Machine 70
Exemple (4)
// TODO: Delete these three lines if you don't want // the toolbar to be dockable
m_wndToolBarStd.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBarDraw.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
// Changed name while adding new toolbar DockControlBar(&m_wndToolBarStd);
DockControlBar(&m_wndToolBarDraw);
return 0;
}