Avant d'aborder cette partie, vous devez savoir créer une fenêtre windows de base, et savoir ajouter des fichiers vides à votre projet (voir cours précédent). On supposera d'ailleur réutiliser la fenêtre du chapître 2 : "Séparation des fichiers et ajout d'icones"
Pour des raisons de clartés nous allons écrire le code dans deux fichiers que nous allons créer maintenant.
Le premier se nommera : "MesControls.h", et le deuxième : "MesControls.cpp".
Une fois ces fichiers créés, l'arborescence de notre projet ressemble à ceci :
Dans le fichier "MesControls.h" nous déclarons le prototype de la nouvelle fonction créatrice de notre bouton.
void MonBouton(HWND);
Le choix du nom de la fonction "MonBouton" est bien sur tout à fait arbitraire (J'aurais pu l'appeler "truc" ou "machin"). Comme on peut l'appercevoir cette fonction recevra un "handle" (HWND), mais ne retournera rien (void). C'est cet "handle" qui assurera le lien entre notre bouton et la fenêtre.
Puis dans le fichier "MesControls.cpp" dont le code complet est donné ici, nous allons définir la fonction "MonBouton".
#include <windows.h>
#include "resource.h"
#include "MesControls.h"
HINSTANCE hInstBouton;
void MonBouton(HWND hwnd)
{
HWND hBouton;
hBouton = CreateWindow (
"BUTTON",
"OK",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
10, 10,
100, 25,
hwnd,
(HMENU) ID_BOUTON,
hInstBouton,
NULL);
}
On remarque aussitôt que la création d'un bouton nécessite une fonction de création de fenêtre : CreateWindow(). Que contient cette fonction ?
"BUTTON" est le premier paramètre qui précisera à la fonction que nous désirons un bouton.
Le paramètre suivant indique le nom qui apparaitra dans le bouton (ici "OK"). Vous pouvez entrer ce que vous voulez.
Viennent ensuite trois paramètres qui indiquent respectivement que le bouton sera "enfant" de la fenêtre (le bouton lui appartient), qu'il sera visible, et enfin que c'est un bouton poussoir.
(10, 10) indique la position (x, y) du coin supérieur gauche du bouton dans la fenêtre.
(100, 25) indique respectivement la largeur et la hauteur du bouton.
"hwnd" est le handle fournit à l'appel de la fonction par la fenêtre.
(HMENU) ID_BOUTON sera l'identifiant qui nous permettra de travailler avec le bouton. Comme il est nouveau, nous le définissons en l'ajoutant dans le fichier "resource.h", dont le code complet est donné ici :
#define MABELLEICONE 100 // icône principale
#define MAPETITEICONE 101 // icône pour la barre de titre
#define ID_BOUTON 200 // Identificateur du bouton "OK"
hInstBouton est une instance qui permet la réservation de l'espace mémoire nécessaire pour la création du bouton. On doit la déclarer avant l'utilisation de la fonction avec le code : "HINSTANCE".
Enfin, le dernier paramètre est un pointeur que nous n'utiliserons pas, donc mis à zéro (NULL).
Vite compilons pour admirer notre oeuvre.
Pourquoi notre bouton ne s'affiche pas dans ma fenêtre ?
Pas de panique, notre bouton est prêt, mais il faut encore dire au programme de le dessiner. Vous vous souvenez de la
procédure de fenêtre dans laquelle se trouvait le message WM_DESTROY ?
C'est dans cette procédure que nous allons maintenant demander l'affichage du bouton.
A quel moment ? Hé bien au moment de sa création. Voici ce que nous allons ajouter :
case WM_CREATE:
// Fonction de dessin du bouton
MonBouton(hwnd);
break;
La procédure de fenêtre devrait maintenant avoir cette allure :
LRESULT CALLBACK WindowProcedure (HWND hwnd,
UINT message, WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
// Fonction de dessin du bouton
MonBouton(hwnd);
break;
case WM_DESTROY:
PostQuitMessage
(0);
// Déclenche la fermeture de la fenêtre
break;
default:
return DefWindowProc
(hwnd,
message, wParam,
lParam)
;
}
return
0;
}
C'est bien joli tout ça, mais notre bouton ne fait pas grand chose !
Nous allons créer une deuxième fonction qui va chercher à indentifier le numéro du bouton sur lequel l'utilisateur à cliqué. Ici le cas est simple, il n'y a qu'un bouton défini en début de prgramme par "ID_BOUTON". C'est naturellement dans le fichier "MesControls.h" que nous allons ajouter la déclaration de notre nouvelle fonction. Appelons là "TestBouton" :
void MonBouton(HWND);
void TestBouton(HWND,
WPARAM);
Ah un paramètre de plus ! A quoi sert-il ?
Pour comprendre, écrivons la définition de la fonction dans le fichier "MesControls.cpp". Nous placerons "TestBouton(...) à la suite de la fonction
déjà existante "MonBouton(...)".
void
TestBouton (HWND hwnd,
WPARAM wParam)
{
if (ID_BOUTON
== LOWORD(wParam))
{
MessageBox(hwnd,
"Vous avez cliqué sur le bouton",
"Test du bouton", MB_OK);
}
}
En fait c'est dans les octets de poids faibles de la variable wParam que Window nous transmet
l'identifiant du bouton sur lequel on a cliqué. LOWORD permet d'extraire ces octets.
Si la valeur correspond à l'identifiant de notre bouton, alors un message est envoyé par l'intermédiaire d'une boîte de dialogue.
Intéressons nous maintenant à la fontion "MessageBox(...)".
Le premier paramètre est le handle permettant de lier la boîte de dialogue à la fenêtre.
Le deuxième est une chaine de caractère contenant le message à transmettre.
Le troisième contient le titre de la boite de dialogue.
Le dernier indique que la fenêtre ne comportera qu'un unique bouton "OK".
Encore une fois, nous allons utiliser la procédure de fenêtre. Lorsque l'utilisateur clic sur le bouton poussoir, cette fenêtre nous envoit le message WM_COMMAND. A la reception de ce message, nous activons donc notre nouvelle fonction.
case WM_COMMAND:
TestBouton(hwnd,
wParam);
break;
Nous pouvons maintenant compiler et exécuter notre programme. On obtient ceci :