A telecharger

Transcription

A telecharger
Les boîtes de dialogue
! Les boîtes de dialogues sont des fenêtres comme les
autres !
" Ensemble de fonctions pour en faciliter la création et le
comportement
" Le système assure une gestion par défaut
" Utilisation de l’éditeur de ressource
! Boites de dialogues prédéfinies
" MessageBox
Boîtes de dialogue
! Boîtes de dialogue personnalisée :
" Ecriture d’une DlgProc associé
BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT
Message, WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
EndDialog(hwnd, IDOK);
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
default: return FALSE;
}
return TRUE;
}
1
Boîtes de dialogue
! Affichage d’une boîte de dialogue personnalisée
( dans le programme appelant)
DialogBox(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDD_ABOUT),
hwnd, AboutDlgProc);
! Fermeture d ’une boîte de dialogue
(dans la DlgProc)
EndDialog(hwnd, reason);
Boîte de Dialogue comme fenêtre principale
! Si le programme n'utilise que des éléments IHM standard
(pas de zone de dessin, par exemple)
HINSTANCE TheInstance = 0;
int WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,char *cmdParam,int cmdShow)
{
TheInstance = hInst;
_set_new_handler (& NewHandler);
HWND hDialog = 0;
hDialog = CreateDialog(hInst,MAKEINTRESOURCE(DLG_MAIN),0,DialogProc);
if (!hDialog)
{
// Message d'erreur
}
MSG msg;
int status;
while ((status = GetMessage (& msg, 0, 0, 0)) != 0)
{
if (status == -1) return -1;
if (!IsDialogMessage (hDialog, & msg))
{
TranslateMessage ( & msg );
DispatchMessage ( & msg );
}
} return msg.wParam;
}
2
Utilisation des menus
! Le menu est « construit » avec l ’éditeur de ressources :
" Un menu est constitué d'une barre comportant des menu button
" Une action sur un menu button provoque l'apparition d'un menu
déroulant (pulldown menu)
" Le menu déroulant comporte lui-même des menu item button
" Identifiants :
• La barre de menu
possède un ID
• Les menu button
possèdent un ID
que s'il ne sont pas
liés à des pulldown
• Chaque article de menu
(menu item) possède son ID
Utilisation des menus
! Seul la fenêtre principale possède un menu
! le lien est fait lors du renseignement de la structure de
classe, avant enregistrement de celle-ci :
struct WNDCLAS
{
UINT style; // Any combination of many styles
WNDPROC lpfnWndProc; // Address of this window's procedure
...
HBRUSH hbrBackground; // Background color
LPCTSTR lpszMenuName; // Name of the menu we would use
...
};
WNDCLAS wc;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
3
Action sur les menus 1/3
! Une action sur un article de menu génère un message de
type WM_COMMAND
! En extrayant l’information LOWORD(wParam), on obtient
l’ID de l’article
! Le code correspondant à une action sur un article de
menu prend donc place dans la WinProc de la fenêtre
principale
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_EXIT:
..
break;
case ID_STUFF_GO:
..
break;
}
break;
Action sur les menus 2/3
! Raccourcis claviers (utilisation des touches modifier keys
(CTRL, ALT, SHIFT).
" Mise en place dans l’éditeur de ressource (précéder la lettre avec
&, par exemple &Save).
" Même message avec le même ID (correspondance effectuée par
TranslateAccelerator())
4
Action sur les menus 3/3
! Par convention, trois petits points qui suivent le nom
d'une entrée du menu (par exemple : "Save as ...") provoque
l'apparition d'un (ou plusieurs) autre(s) dialogue(s),
" Ex : "Save as ..." provoque l'ouverture d'une boite de dialogue
typique permettant a l'utilisateur d'entrer le nom du fichier à
sauver etc ...
! Pour placer le menu d’aide à droite, cocher l’option dans
les propriétés (éditeur de ressource)
! Un article de menu peut être initialisé dans un état
dévalidé (grayed)
Les Contrôles (Controls)
! Ensemble de contrôles standard de Windows (inclus
depuis Windows 3.1 et Win95
"
"
"
"
"
"
"
Buttons
Combo boxes
Edit controls
List boxes
Rich edit controls
Scroll bars
Static controls
! Ensemble supplémentaire : Common controls
le code est dans COMCTL32.DLL.
Livré avec toute version de Windows (MAJ IE)
! Contrôles particuliers : ActiveX controls, User-defined
controls.
5
Envoi de message vers un contrôle
! Un contrôle étant une fenêtre (avec une classe
préenregistrée), le comportement du contrôle est
prédéfini
" Par ex. effet visuel quand on clique pour la classe BUTTON
" Chaque contrôle dispose d'une boucle de message déjà
fonctionnelle
! On peut envoyer des messages spécifiques au contrôle
" Par exemple, invalider un contrôle, positionner un bouton radio,
paramètrer l'étendue d'un curseur, faire avancer une barre de
progression, etc…
" L'envoi de message se fait par SendMessage() si on dispose
du handle du contrôle, ou par SendDlgItemMessage() pour
les contrôles placé dans une boite de dialogue.
Exemple : le contrôle d ’affichage
! Affichage de texte « statique » : Static Control
" On évite de changer le texte en dynamique
Seule exception : l ’internationalisation
! Affichage de texte « dynamique » : Edit Control
" Prévu pour la saisie de texte et pour son affichage
" Gestion du copier/coller, des touches d ’effacement, de la
sélection, etc...
" Pour l’affichage seul marquer comme read only
! par exemple
SetDlgItemText(hwnd, IDC_TEXT, "This is a string");
6
Edit Control : Informations numériques
! On doit souvent afficher des informations numériques
" Les Edit Control peuvent gérer un mode « purement numérique »
" Dans ce cas, l’utilisateur n’a pas à faire les tests
" Il existe des fonctions spécifiques
! Les Edit Control numériques peuvent s ’associer à des
spin boxes
" Le spin box fait partie des Common Controls
" Le contrôle de type edit doit présenter une information numérique
BOOL bSuccess;
int nTimes = GetDlgItemInt(hwnd, IDC_NUMBER, &bSuccess,FALSE);
Accès aux fichiers
! Utilisation de fopen()/fread()/fwrite()possible
(sans oublier #include <stdio.h>)
! Utilisation des iostreams possible en C++
! En Win32 pur :
" utiliser la fonction CreateFile() (au lieu de fopen())
" utiliser ReadFile() et WriteFile() pour lire et écrire
" utiliser CloseHandle() (au lieu de fclose())
7
Accès aux fichiers
! Utilisation d ’une structure
OPENFILENAME et de la
fonction GetOpenFileName()
" Renseigner la structure
" Faire pointer le champ lpstrFile
de la structure sur le buffer destiné
à recueillir le nom du fichier
" Appeler la fonction OpenFileName()
OPENFILENAME ofn;
char szFileName[MAX_PATH];
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
if(GetOpenFileName(&ofn))
{
// Operation sur le fichier dont le nom est dans szFileName
}
OPENFILENAME
! Champs optionnels de la structure OPENFILENAME
" Filtres sur les extensions
• Créer une chaîne de caractères avec des paires « description 0 extension »,
L ’ensemble des paires étant terminé par un double 0
ofn.lpstrFilter =
"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
" Extension par défaut
ofn.lpstrDefExt = "txt";
" Répertoire par défaut
! Dans le même gamme :
choix d'une couleur avec le dialogue
ChooseColor()
8
Fonctions temporelles sous Windows
! GetTickCount()
The GetTickCount function retrieves the number of milliseconds that have
elapsed since Windows was started.
DWORD GetTickCount(VOID)
! Utile pour "chronomètrer" la durée d'une tâche.
" Attention pour les durées longues :
The internal timer wraps around to zero if Windows is run continuously
for approximately 49.7 days
" Pas très précis pour les durées < 1 sec.
int start, now;
start = GetTickCount();
…
// some processing
…
now = GetTickCount();
printf("durée d'execution (en ms) = %d",now-start);
Fonctions temporelles sous Windows
! Mise en place d'un TIMER
SetTimer()
UINT SetTimer(
HWND hwnd,
UINT idTimer,
UINT uTimeout,
TIMERPROC tmprc
);
//
//
//
//
handle of window for timer messages
timer identifier
time-out value (ms)
address of timer procedure
! KillTimer()
BOOL KillTimer(
HWND hWnd,
UINT uIDEvent
);
// handle of window that installed timer
// timer identifier
#define MY_TIMER 1515
SetTimer(hWnd,MY_TIMER,500,NULL;
KillTimer(hWnd,MY_TIMER);
9
Fonctions temporelles sous Windows
! Une fois créé, le TIMER générera un message
WM_TIMER (ou active sa TimerProc) à l'intervalle
spécifié.
! Si réception d'un message, celui-ci est traité dans la
routine principale de traitement de message de
l'application (WndProc)
case WM_CREATE:
SetTimer(hWnd,MY_TIMER,1000,NULL);
break;
…
case WM_TIMER:
x = x+10;
y = y+10;
UpdateWindow();
break;
…
case WM_CLOSE:
KillTimer(hWnd,MY_TIMER);
break;
Affichage de texte (1)
! TextOut()
BOOL TextOut(
HDC hdc,
int nXStart,
int nYStart,
LPCTSTR lpString,
int cbString
);
//
//
//
//
//
handle of device context
x-coordinate of starting position
y-coordinate of starting position
address of string
number of characters in string
" Dessine le texte à l'endroit spécifié
" Utilise les paramètres du contexte graphique (device context)
HDC hdc;
char buf[] = "Hello!";
…
case WM_PAINT:
hdc = BeginPaint (hWnd, &ps);
TextOut(hdc,x,y,buf,strlen(buf));
EndPaint (hWnd, &ps);
break;
10
Affichage de texte (2)
! DrawText()
int DrawText(
HDC hDC,
LPCTSTR lpString,
int nCount,
LPRECT lpRect,
UINT uFormat
);
//
//
//
//
//
handle of device context
address of string to draw
string length, in characters
address of structure with formatting dimensions
text-drawing flags
" Dessine le texte dans le contexte graphique avec formatage
" Valeur de retour : hauteur du texte
HDC hdc;
RECT rect;
char buf[] = "Hello!";
rect.top = y;
rect.left = x;
…
case WM_PAINT:
hdc = BeginPaint (hWnd, &ps);
DrawText(hdc,buf,strlen(buf),&rect, DT_LEFT | DT_SINGLELINE);
EndPaint (hWnd, &ps);
break;
Quelques fonctions graphiques
! MoveToEx()
BOOL MoveToEx(
HDC hdc,
int X,
int Y,
LPPOINT lpPoint
);
//
//
//
//
handle of device context
x-coordinate of new current position
y-coordinate of new current position
address of old current position
" Déplace la positon courante de dessin aux coord. spécifiées
! LineTo()
BOOL LineTo(
HDC hdc,
int nXEnd,
int nYEnd
);
// device context handle
// x-coordinate of line's ending point
// y-coordinate of line's ending point
" Trace une ligne depuis le point courant jusqu'aux coord.
spécifiées
11
Quelques fonctions graphiques
! Rectangle()
BOOL Rectangle(
HDC hdc,
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect
);
//
//
//
//
//
handle of device context
x-coord. of bounding rectangle's
y-coord. of bounding rectangle's
x-coord. of bounding rectangle's
y-coord. of bounding rectangle's
//
//
//
//
//
handle of device context
x-coord. of bounding rectangle's upper-left corner
y-coord. of bounding rectangle's upper-left corner
x-coord. of bounding rectangle's lower-right corner
y-coord. bounding rectangle's f lower-right corner
upper-left corner
upper-left corner
lower-right corner
lower-right corner
! Ellipse()
BOOL Ellipse(
HDC hdc,
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect
);
Graphique : Brush & Pen
! Utiliser un objet prédéfini : GetStockObject()
The GetStockObject function retrieves a handle to one of the predefined
stock pens, brushes, fonts, or palettes.
HGDIOBJ GetStockObject(
int fnObject // type of stock object
);
! Activer l'objet : SelectObject()
The SelectObject function selects an object into the specified device context.
The new object replaces the previous object of the same type.
HGDIOBJ SelectObject(
HDC hdc,
// handle of device context
HGDIOBJ hgdiobj
// handle of object
);
HBRUSH hb,holdb;
HPEN hp;
hb = (HBRUSH)GetStockObject(GRAY_BRUSH);
hp = (HPEN)GetStockObject(BLACK_PEN);
holdb = SelectObject(hdc,hb);
12
Graphique : Créer un style de tracé
! Créer un Pen : CreatePen()
HPEN CreatePen(
int fnPenStyle,
int nWidth,
COLORREF crColor
);
// pen style
// pen width
// pen color
! Pour la couleur, utiliser la macro RGB
COLORREF RGB(
BYTE bRed, // red component of color
BYTE bGreen, // green component of color
BYTE bBlue // blue component of color
);
HPEN hp,holdp;
hp = (HPEN)CreatePen(PS_SOLID, 2,RGB(250,10,0);
holdp = SelectObject(hdc,hp);
Les petites fonctions bien utiles
! Beep()
BOOL Beep(
DWORD dwFreq,
DWORD dwDuration
);
// sound frequency, in hertz
// sound duration, in milliseconds
" Génère un bip système
" Sous Win95 & Win98, pas de paramètres
" Sous NT, 2000 (XP ?), préciser fréquence et durée
13
Les petites fonctions bien utiles
! OutputDebugString()
" Permet de remplacer le printf() pour afficher des messages, y
compris pour des applications en mode fenêtré
" Les messages n’apparaissent qu’en mode DEBUG, au sein de
l ’environnement de développement
If the application has no debugger, the system debugger displays the string. If the
application has no debugger and the system debugger is not active,
OutputDebugString does nothing.
" Les messages peuvent être intercepté par des utilitaires, y
compris via le réseau
OutputDebugString("Etape 5 franchie\n");
14