Windows : Généralités Windows : Généralités

Transcription

Windows : Généralités Windows : Généralités
Windows : Généralités
! Windows est avant tout adapté au marché (à moins que
Microsoft n'ait adapté le marché à Windows...), tant du point de vue
fonctionnel que du point de vue technique.
" simplicité
" la plus vaste gamme de logiciels
" pérennité ???
! Principaux inconvénients
" son passé (compatibilité ascendante du DOS…)
" Les systèmes de fichiers « bas de gamme »
• fragmentation, droits d ’accès des utilisateurs, ...
" fonctionnalités réseau effroyablement pauvres
• netBIOS, pas de service « serveur » pour FTP, Telnet, Winsock
" Espace mémoire non protégé (avant NT)
Windows : Généralités
! quelques points forts techniques
" environnement de programmation correct
" Les développeurs ne se soucient pas des détails matériels
" les fonctions du noyau de base (gestion de la mémoire, des
processus, des threads, des communications inter-processus et
des entrées/sorties) sont extrêmement bien écrites et constituent
une base solide et cohérente pour les applications
" une API très large
1
Architecture de Windows NT, 2000, XP
! Architecture souhaitée :
"
"
"
"
"
"
"
"
"
Objet, objet, objet
monolithique pas trop, plutôt modulaire
Préemptif et multi-tâches
Multi-processeurs
Architecture Client/Serveur
Adressage 32 bits # 4Go d’espace mémoire
Support de plusieurs systèmes de fichier ?
Ecrit en C et C++ principalement
Services réseau intégrés
! Structure de l’architecture Windows NT
"
"
"
"
$
HAL (Hardware Abstraction Layer) Intel, Alpha, Multiprocesseur
Kernel
NT Executive
Sous environnements (win32 subsystem)
Architecture de Windows NT, 2000, XP
! Kernel NT/2000
"
"
"
"
"
"
Gère le(s) microprocesseur(s)
distribue et planifie les threads (en fonction des priorités)
Gère les interruptions système
Traite les exceptions processeur
Parties critiques écrites en assembleur
Le reste des tâches est délégué aux services de NT Executive
! NT Executive
I/O
Manager
Security
Object
Process
Ressource
Manager
Manager
Manager
LPC
Virtual
Memory Graphic
Manager Manager
(USER et
GDI)
2
Object Manager
! Sous NT/2000, les ressources de l’OS sont représentés par des objets :
" Processus, thread
" Périphériques
! Un handle est une référence d’objet. Permet de l ’utiliser
! Un handle contient un pointeur ainsi que des informations de contrôle sur
l’objet qu’il représente
! Le gestionnaire d’objet crée, modifie et supprime ces objets. Supprime aussi
les objets orphelins.
" Fournit ces handles
" gère les ressources consommées par chaque objet
---------------------------------------------------------------| HANDLE TYPE | EXAMPLES
|
MEANING
|
|--------------+-------------+---------------------------------|
| HANDLE
|hnd or hdl
| Generic handle
|
| HWND
|hwnd or hWnd | Window handle
|
| HDC
|hdc or hDC
| Device context handle
|
| HBRUSH
|hbr or hBrush| Paint brush handle
|
| HPEN
|hpen or hPen | Drawing pen handle
|
----------------------------------------------------------------
Objet processus et objet Thread
3
Windows : l ’IHM
! Distinguer les application SDI et MDI
Prog. Windows en mode console
! Programmation en mode console
! Utilisation de la plupart des appels Win32
" Ceux qui n’interviennent pas sur une fenêtre principale,
par exemple :
#include <windows.h>
main()
{
MessageBox(NULL, "Hello World","Message", MB_OK);
}
" La console permet toujours l’usage du « printf »
(par la suite, et pour les MessageBox, utiliser wsprintf : évite
d’inclure stdio.h)
char buf[250];
wsprintf(buf, "Vous consultez le message %d",i);
MessageBox(NULL,buf,"Message", MB_OK);
4
Prog. Windows en mode fenêtré
! Remplacer main() par winmain()
" Décrire la classe de la fenêtre principale
" Enregistrer la classe
" Créer la fenêtre en y associant une routine de traitement des
évènements (messages)
" Gérer les messages
! La routine de traitement de message est une fonction à
part (dénommée WinProc = callback affecté à la fenêtre)
" Gestion explicite des message : structure de type switch() case:
! Chaque boite de dialogue peut/doit avoir sa WinProc (ou
DlgProc)
Prog. Windows en mode fenêtré
! La fonction printf ne fonctionne plus. On peut utiliser
MessageBox dans la plupart des cas pour afficher des
messages courts.
! Cette fonction affiche simplement une chaîne de
caractère dans une boîte de message :
petite fenêtre accompagnée d'un ou plusieurs boutons
(ex : Ok et Cancel). Cette fonction est très souvent
utilisée pour donner des avertissements à l'utilisateur (Fin
d'une tâche ou erreur).
5
MessageBox
! int WINAPI MessageBox( HWND, LPCTSTR, LPCTSTR, UINT );
" Le premier argument est un handle de fenêtre. Elle indique à
quelle fenêtre se rapporte la boîte de message.
Programmation console : argument égal à NULL car notre
application ne possède pas de fenêtre.
" Le deuxième argument est la chaîne de caractère à afficher.
" Le troisième argument est une chaîne de caractère affiché dans
la barre de titre de la boîte de message.
" Le dernier argument est une constante ou une combinaison de
constantes.
Indique quels boutons et quel icône sont à afficher dans la boîte.
Ces constantes commencent par le préfixe MB_ (MessageBox)
Les messages Windows
! Le pendant de la structure Event de X11
! La structure MSG contient six champs :
" hwnd: l'handle de la fenêtre destinée à recevoir le message.
" message : Nombre identifiant le message. Ici, encore, des
identificateurs facilitent la gestion des messages pour le
programmeur. Ils commencent par le préfixe WM_ (exemple:
WM_CREATE est envoyé immédiatement après la création de la
fenêtre).
" wParam : Paramètre de message 32 bits utilisé pour certains
messages.
" lParam: Idem
" time: Permet de connaître à quelle heure le message a été placé
dans la file d'attente.
" pt: Coordonné de la souris lors de l'arriver du message dans la
file d'attente.
6
File d’attente
Le traitement des messages
! Traitement explicite des messages dans la boucle
! Ce traitement est masquée si on utilise les MFC
7
Callback des fenêtres
! Si un message est destiné à une fenêtre, il est envoyé au callback
de la fenêtre en question.
! Le nom de la procédure de fenêtre est du type WndProc :
LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
! C'est le nom que les programmeurs lui donne en général. Les quatre
arguments de cette procédure sont des champs de la structure MSG.
Il faut consulter l’aide pour connaître la signification des paramètres
transmis (wParam, lParam) selon le message.
! Pour traiter les messages, on utilise généralement un switch.
Code basique pour le WinMain
!
!
!
!
!
Définir / créer une classe de fenêtre
Enregistrer la classe
Créer la fenêtre et obtenir le handle vers celle-ci
Afficher la fenetre
Entrer dans la boucle de gestion de messages
struct WNDCLAS
{
UINT style; // Any combination of many styles
WNDPROC lpfnWndProc; // Address of this window's procedure
int cbClsExtra; // Extra bytes (not required)
int cbWndExtra; // Extra bytes (not required)
HINSTANCE hInstance; // This window's instance
HICON hIcon; // Handle to an icon to use with this window
HCURSOR hCursor; // Specifies the kind of cursor you'd like
HBRUSH hbrBackground; // Background color
LPCTSTR lpszMenuName; // Name of the menu we would use
LPCTSTR lpszClassName; // User-defined, custom name for the class
};
8
Code basique pour le WinMain
! Pour afficher une fenêtre, il faut :
" Créer une classe de fenêtre qui contient les caractéristiques de
celle-ci (Avec ou sans menu, redimensionnable ou non …). C'est
une structure de type WNDCLASS qu'il vous faut remplir.
" Enregistrer la classe avec la fonction RegisterClass. Elle permet
d'allouer de la mémoire pour stocker les informations sur la
classe de fenêtre.
" Obtenir un handle pour votre fenêtre et définir de quelle manière
elle doit être afficher pour la première fois à l'écran (emplacement
à l'écran, taille …) en utilisant CreateWindow.
" Afficher la fenêtre à l'aide de ShowWindow et UpdateWindow.
Etape 1 : Définir la classe de fenêtre
#include <windows.h>
const char g_szClassName[] = "myWindowClass";
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize
wc.style
wc.lpfnWndProc
wc.cbClsExtra
wc.cbWndExtra
wc.hInstance
wc.hIcon
wc.hCursor
wc.hbrBackground
wc.lpszMenuName
wc.lpszClassName
wc.hIconSm
=
=
=
=
=
=
=
=
=
=
=
=
sizeof(WNDCLASSEX);
0;
WndProc;
0;
0;
hInstance;
LoadIcon(NULL, IDI_APPLICATION);
LoadCursor(NULL, IDC_ARROW);
(HBRUSH)(COLOR_WINDOW+1);
NULL;
g_szClassName;
LoadIcon(NULL, IDI_APPLICATION);
Association
callback - fenêtre
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
9
Etape 2 : Créer la fenêtre et l’afficher
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!",
"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
Etape 3 : Entrer dans la boucle de messages
while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
10
La « pompe à messages »
! GetMessage lit les messages placés dans la liste d'attente et remplit
la structure msg. Si ce message est WM_QUIT, GetMessage
retourne 0 pour sortir de la boucle while. Le deuxième paramètre est
un handle de fenêtre. Ici, NULL permet de lire les messages de
toutes les fenêtres. En l'absence de messages, l'application est au
repos.
! TranslateMessage repasse la structure msg à Windows qui
effectue un transcodage du clavier. Ce qui permet de traduire les
événements de touche en événement de caractère. En faite, cette
fonction permet entre autre de gérer les combinaisons de touches.
Exemple: "SHIFT" + "a" donne le caractère "A".
! DispatchMessage repasse la structure msg à Windows, et cette
structure sera transmise à la procédure de fenêtre.
Etape 4 : Écrire la Procédure de traitement
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
11
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
" OpenFileName
! Dialogues
définis par l’utilisateur
Boîtes de dialogue
! Boîtes de dialogue personnalisée :
" Écriture 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;
}
12
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);
13