Vous êtes sur la page 1sur 258

Tutoriel : Apprentissage de l'API Windows Version en ligne

Table des matières


Apprentissage de l'API Windows
Les bases
Commencement
Votre première fenêtre
Elle est vide, ma fenêtre !
Les menus
Les boîtes de dialogue
Les contrôles
Les boutons (tous types)
Le contrôle d'édition
La liste déroulante
La liste de choix
La glissière
Le contrôle Static
L'a ichage
Les contextes de périphériques
Le texte
Les formes géométriques
Les images
TP : Un lecteur audio
But
Nécessaire
Pistes
Correction
Améliorations
Les événements
Evénements "clavier"
Evénements "souris"
Esthétique avancée
Les régions
Gestion de la fenêtre

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Documentation
Fonctions
Messages
Structures
Glossaire
Termes
Manipulation du registre
Quelques notions de BDR
Changement d'icône de fichiers
Lancement au démarrage de windows
Association de fichiers
Divers
Utiliser le style du Windows courant
La notation hongroise
Quelques codes...
Programmes
Neoblast, de Kidpaddle2 (ex-Mg++)
DdPop, de damien.09

Apprentissage de l'API Windows

Vous voudriez apprendre l'API Windows et vous trouvez les autres cours présents sur le net trop di iciles ou pas assez précis ? Vous avez frappé à la bonne
porte.
Bienvenue dans ce tutoriel. Vous allez apprendre ici à vous servir d'une API très développée : l'API Win32. Sa proximité avec le système d'exploitation lui
permet d'avoir un contrôle total sur n'importe quelle partie de l'OS, et un grand éventail de fonctions.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
L'API Windows est, malheureusement et comme son nom l'indique, exclusivement dédiée à Windows. Donc, si vous possédez un autre OS, passez
votre chemin.

Je considère dans ce tutoriel que vous ne connaissez strictement rien à l'API Windows, ceci pour ne pas décourager les débutants ; néanmoins, vous aurez
besoin des connaissances acquises tout au long du tuto de M@teo21. Vous trouverez donc ici des cours évolutifs, entrecoupés de TP réguliers, une
documentation sur les di érents messages, notifications, styles, fonctions, etc., et même un glossaire ;) .

Toutes ces parties seront progressivement remplies au fur et à mesure de la rédaction du tutorial en lui-même. J'ai pour cela des coéquipiers,
respectivement pamaury et acryline.

Si vous avez des problèmes, des questions, ou encore des suggestions, vous pouvez nous envoyer un MP, auquel on se fera un plaisir de répondre. ;)

Les termes touchant à la programmation que vous êtes susceptibles de ne pas comprendre seront de couleur rouge, et seront définis dans le
glossaire.

Sur ce, je vous souhaite une agréable lecture, et j'espère que ce tuto vous aidera le plus possible. :)

Les bases
Ce chapitre va vous inculquer les bases du API Win32.

Commencement
Le nom de ce que vous allez apprendre vous a sûrement laissés perplexes : je vous ai dit que nous allions vous apprendre l'API Windows, mais vous ne savez peut-
être toujours pas de quoi il s'agit.

Une API, ou Application Programming Interface est, comme son nom l'indique, une interface de programmation : elle contient un ensemble de fonctions bas
niveau, ici extrêmement bien documentée (comme vous pouvez le constater), permettant de programmer des applications haut niveau. Elles sont alors
accessibles à partir de bibliothèques intégrées au projet.
Pour pouvoir utiliser le WinAPI, vous devez évidemment sélectionner un projet WinAPI dans votre IDE pendant la création du nouveau projet. Par exemple, sous
code::blocks, vous devez sélectionner "Win32 GUI Application" comme sur cette photo :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Vous n'aurez rien à linker pour le moment.

Comme vous pouvez vous en douter, vous devrez inclure la bibliothèque appropriée pour utiliser cette API, à savoir :

#include <windows.h>

Comme chacun sait, une seule fonction est commune à tous les programmes : le main. Le point d'entrée du programme est, dans cette API, un peu plus
compliqué que dans un projet console ou SDL. Ainsi, le code minimal que vous pouvez faire en WinAPI est le suivant :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
#include <windows.h>

int WinMain (
HINSTANCE cetteInstance,
HINSTANCE precedenteInstance,
LPSTR lignesDeCommande,
int modeDAffichage
)
{
return 0;
}

:waw: C'est quoi, tout ça ? Où diable sont passés les argc et argv tout bêtes ?

Pas de panique. ;) Étudions ensemble cette fonction. Vous connaissez forcément le type de retour de cette fonction : il s'agit d'un int. Passons maintenant aux
arguments :

Le premier argument est l'instance actuelle de votre programme. C'est en quelque sorte une "boîte" représentant votre programme, et imbriquant tout ce
qu'il contient (pour ne pas vous encombrer la tête) :

HINSTANCE cetteInstance

Le deuxième argument désigne l'instance précédente. En fait, ce paramètre date de Windows 16 bits, et donc obsolète. Il vaut donc toujours NULL :

HINSTANCE precedenteInstance

Conséquence : vous n'êtes même pas obligés d'indiquer un nom de variable, bien que le type soit quand même nécessaire.

Le troisième argument remplace justement argv que vous connaissez déjà dans le prototype du main console ou SDL. Cependant, il est dans sa forme brute ;
vous ne pourrez donc pas l'utiliser de suite (je vous expliquerai plus tard comment la découper et l'utiliser) :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
LPSTR lignesDeCommande

Il est d'un type que vous ne connaissez pas, puisqu'il s'agit d'une structure signée Microso . Celle-ci correspond à un bête char*.

Le petit dernier ne vous servira probablement pas souvent : il s'agit du mode d'a ichage (visible, invisible, minimisé etc...) de la fenêtre principale :

int modeDAffichage

Même remarque que pour le paramètre contenant l'instance précédente.

Pour ceux qui écoutent les conseils du rédacteur -à savoir moi ;) -, vous devriez au préalable savoir à quoi correspondent les types principaux utilisés par cette API
:

LPSTR correspondant à un char *, et ses déclinaisons :

LPCSTR correspondant à un const char *.

LPTSTR correspondant à un TCHAR * (voir TCHAR plus bas).


On l'initialise avec la macro TEXT, selon :

LPTSTR string = TEXT("exemple");

LPWSTR correspondant à un wchar_t *


On l'initialise avec le préfixe ' L', selon :

LPWSTR string = L"exemple";

Vous pouvez combiner les lettres définissant un caractère particulier de LPSTR pour obtenir des types adaptés (comme LPCTSTR).

WORD correspondant à un unsigned short

DWORD correspondant à un unsigned long

TCHAR correspondant à :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
En compilant en Unicode : un wchar_t

Sinon : un char ;)

Il est recommandé d'utiliser les TCHAR partout (même si ce n'est pas fait dans ce tuto), du moment que l'on n'utilise pas stdio, ou certaines fonctions
de cette API (dont je vous mettrai en garde si c'est le cas), pour des raisons de compatibilité avec n'importe quel IDE.

Seuls les utilisateurs de VS en général compilent en Unicode. Si n'en voulez pas (ça simplifie les choses), voici la manip' à exécuter : Project Properties -
> Configuration Properties -> General -> Character set -> Changer l 'option de "unicode" à "multi-byte".

Et voilà pour une présentation restreinte ^^ .

Vous savez maintenant ne rien a icher sans erreur de compilation ! :lol: Génial, non ? Vous en voulez plus ? (pas étonnant ;) ) D'accord, direction "Votre première
fenêtre" :) .

Pour ceux qui veulent absolument un "Hello World" avant de commencer (ça les frustre sûrement), voici la formule magique à rajouter dans le WinMain :

MessageBox(NULL, "Hello World", "Hello World", MB_OK);

Ou plus propre :

MessageBox(NULL, TEXT("Hello World"), TEXT("Hello World"), MB_OK);

Rédacteur : Mg++

Votre première fenêtre


Vous êtes impatient de créer votre première fenêtre ? Tant mieux, c'est ici que ça se passe. :p

Le minimum
Premièrement, munissez-vous du code minimal que je vous ai donné tout à l'heure :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
#include <windows.h>

int WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance, LPSTR lignesDeCommande, int modeDAffichage)
{
return 0;
}

Dans certains cas, vous serez contraints de rajouter les mots clés WINAPI ou APIENTRY entre 'int' et 'WinMain', cause d'une erreur de compilation de type
"WinMain already defined in...". Si c'est le cas, adaptez mes codes à cette situation.

Les variables nécessaires


Nous aurons besoin pour a icher la fenêtre de plusieurs variables :

HWND fenetrePrincipale;
MSG message;
WNDCLASS classeFenetre;

Étudions d'abord leur type respectif et leurs rôles :

fenetrePrincipale est de type HWND, qui veut dire handle de fenêtre. Si vous connaissez un minimum l'anglais, vous remarquerez que l'on pourrait le
traduire par poignée.

Quel est le rapport ?

Réfléchissez : fenetrePrincipale sera une sorte de "poignée" nous permettant d'agir sur la fenêtre principale. En outre, cette structure possède sur la fenêtre
toutes les informations nécessaires à son a ichage. Bien sûr, ce handle ayant un nom, cela nous permet d'identifier, par le nom d'une variable, la fenêtre
créée (bref : c'est bien pratique :) ).

message, quant à lui, est comme son nom l'indique un message système, utilisé pour communiquer entre l'utilisateur et les fenêtres : il s'agit en fait du
descriptif d'un événement. Si vous connaissez la SDL, vous pourriez faire la correspondance avec 'SDL_event'.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
classeFenetre est la classe de fenêtre (décidément, je choisis bien les noms ;) ) nécessaire à la construction de la fenêtre principale. C'est en fait une liste
d'informations permettant par la suite de créer la fenêtre selon notre bon vouloir. (Je précise que la "classe" n'a pas ici la même définition que pour le C++.)

Remplissage de la classe de fenêtre


La création de la fenêtre demande le remplissage de sa classe, ou WNDCLASS. Nous allons donc nous en occuper :

Le champ 1 définit le style à a ecter à la fenêtre. Ici, il n'y en a pas :

classeFenetre.style=0;

Le champ 2 définit la fonction callback à utiliser pour cette fenêtre (je vous explique plus loin) :

classeFenetre.lpfnWndProc = procedureFenetrePrincipale;

Le champ 3 définit combien de bytes en plus seront alloués à la suite de la structure (cela nous est inutile, donc 0 ^^ ) :

classeFenetre.cbClsExtra = 0;

Le champ 4 définit la même chose, mais suite à l'instance (donc aussi inutile) :

classeFenetre.cbWndExtra = 0;

Le champ 5 définit l'instance à laquelle appartient la fenêtre :

classeFenetre.hInstance = cetteInstance;

Le champ 6 définit l'icône à utiliser pour la fenêtre (en haut à gauche). Elle doit être chargée soit en passant par les ressources (nous verrons cela plus tard),
soit, comme suit, avec une icône inclue dans Windows, possédant un ID spécifique (la liste sera peut-être proposée dans notre documentation) :

classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);

Le champ 7 définit le curseur par défaut à utiliser pour cette fenêtre (même chose que pour les icônes : le curseur utilisé ici est inclus dans Windows, et choisi
parmi une petite liste) :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);

Le champ 8 définit la couleur à utiliser pour le fond de la fenêtre. Son type est HBRUSH, (traduit par brosse), et peut être changé grâce à une fonction de
conversion, RGB->HBRUSH, que nous verrons plus tard, dans le chapitre sur l'a ichage :

classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);

Le champ 9 définit le menu associé à cette fenêtre (peut être ajouté d'une autre manière) : ici, il n'y en aura aucun :

classeFenetre.lpszMenuName = NULL;

Et enfin le le champ 10, qui sera le nom de la classe en question :

classeFenetre.lpszClassName = "classeF";

Maintenant que nous avons rempli la classe de la fenêtre, encore faut-il la sauvegarder. Voici comment faire :

RegisterClass(&classeFenetre);

Création proprement dite de la fenêtre principale


Enfin ! Nous sommes prêts à créer notre fenêtre. C'est le travail de la fonction, dont voici le prototype :

HWND CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
HANDLE hInstance,
LPVOID lpParam
);

:euh: Ne me dis pas que l'on doit retenir toutes ces fonctions ?

Bon d'accord, elles sont lourdes... mais non, vous n'êtes pas obligés de les retenir. Mais à force de les utiliser (vous verrez ;) ), vous les connaîtrez par coeur. "C'est
en forgeant qu'on devient forgeron" à ce qu'il paraît. :p
Bon. Déjà, vous pouvez remarquer que son type de retour est HWND. Vous pouvez faire la correspondance avec fenetrePrincipale, et deviner que c'est celle-ci qui
va contenir le retour de CreateWindow ^^ . En fait, cette fonction remplit la structure HWND avec les informations propres à la fenêtre, et la crée par la même
occasion. (CreateWindow ne crée pas vraiment que des fenêtres au sens connu, mais toutes sortes de contrôles, que ce soit : fenêtre, bouton, listbox, progressbar,
etc.)

Maintenant, occupons-nous de ses arguments :

L'argument 1 désigne la classe de fenêtre à partir de laquelle la fenêtre va être créée :

LPCTSTR lpClassName

(Vous avez peut être remarqué qu'il est de type LPCTSTR... C'est en fait la même chose que LPSTR mais constant, donc égal à const char[].)

L'argument 2 désigne le nom de la fenêtre, c'est-à-dire, dans le cas d'une fenêtre, la string qui va être a ichée en guise de titre :

LPCTSTR lpWindowName

L'argument 3 désigne les styles à donner à la fenêtre :

DWORD dwStyle

(Vous avez sûrement remarqué que le type de cet argument vous est inconnu : en fait, il est utilisé un peu partout, et correspond à un unsigned long. Il est
souvent utilisé pour les styles / flags, et sûrement construit à partir d'une association de bits.)

Les arguments 4 à 7 désignent respectivement : les coordonnées du coin supérieur gauche, la largeur, ainsi que la hauteur de la fenêtre :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
int x,
int y,
int nWidth,
int nHeight

L'argument 8 désigne le handle de la fenêtre parent :

HWND hWndParent

L'argument 9 désigne, dans le cas d'une fenêtre, le menu associé à celle-ci, et dans le cas d'un contrôle, son ID (pour pouvoir le manipuler) :

HMENU hMenu

L'argument 10 désigne l'instance du programme :

HANDLE hInstance

(HINSTANCE dérive de HANDLE, donc son passage en tant que HANDLE se déroule sans histoire.)

L'argument 11 désigne les éventuels paramètres à envoyer à la fenêtre, à sa création :

LPVOID lpParam

(LPVOID est en fait un équivalent à void*. Pour ceux ayant fait de la SDL, cet argument possède le même rôle que le paramètre optionnel de type void* des
timers.)

Et maintenant que vous connaissez chacun des arguments de la fonction CreateWindow, passons au codage pour créer une fenêtre :

fenetePrincipale = CreateWindow("classeF",
"Première fenêtre en winAPI !",
WS_OVERLAPPEDWINDOW, /*Style qui permet d'avoir une fenêtre tout ce qu'il y a de plus normale : barre de titre, menu système (r
éduire, maximiser, fermer), bordure etc...*/
CW_USEDEFAULT, // Permet à l'OS de déterminer dynamiquement la position de la fenêtre
CW_USEDEFAULT, //Idem

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
400,
300,
NULL, // Pas de fenêtre parent, puisque c'est la principale
NULL, //Aucun menu ne lui est associé
cetteInstance,
NULL); // Aucun paramètre à lui envoyer en plus

Mais la fenêtre ne s'a ichera pas pour autant. :o Elle est créée, mais c'est tout. ^^

Notez qu'elle aurait pu l'être en possédant le style WS_VISIBLE.

Pour l'a icher, il faut appeler la fonction ShowWindow ! Celle-ci prend en premier paramètre le handle de la fenêtre dont on veut changer le mode d'a ichage, et
un integer déterminant son mode. Vous pouvez soit utiliser le paramètre de WinMain modeDA ichage, soit utiliser la valeur qu'il prend d'habitude : SW_SHOW.
Donc :

ShowWindow(fenetrePrincipale,SW_SHOW);

Maintenant que la fenêtre est en mode "a ichée", il faut rafraîchir l'écran afin de la montrer à l'utilisateur : c'est le rôle de UpdateWindow, prenant comme seul
paramètre le handle de la fenêtre. Vous l'utiliserez sûrement beaucoup après avoir créé des contrôles enfants d'une fenêtre, afin de rafraîchir l'écran juste après
leur création.

Boucle événementielle
Afin d'interfacer l'utilisateur avec la fenêtre, nous avons besoin d'une boucle événementielle traitant les messages créés par l'utilisateur (qui ne le sait même pas
:p ) et destinés aux fenêtres concernées.
Pour cela, nous allons utiliser une nouvelle fonction que voici :

BOOL GetMessage(LPMSG msg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax);

L'argument 1 désigne le message récupérateur des événements :

LPMSG msg

(Comme vous l'avez peut être deviné, les deux lettres 'LP' désignent un pointeur sur le type adjacent...)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
L'argument 2 désigne le handle de fenêtre dont GetMessage va récupérer les événements (s'il est égal à NULL, GetMessage traitera toutes les fenêtres de
l'instance) :

HWND hwnd

Les deux autres paramètres ne sont pas très importants pour le moment (je ne voudrais pas que vous partiez avant votre première fenêtre ;) ). Mettez-les donc à
zéro.

Donc, mettons en place la boucle :

while (GetMessage(&message, NULL, 0, 0)) /*Récupération des évènements de toutes les fenêtres de l'instance dans message*/
{
TranslateMessage(&message); // Traduction de l'événement
DispatchMessage(&message); // Envoi du message correspondant à la fenêtre concernée
}

La fonction callback
Cf glossaire
Vous vous rappelez le champ de structure de classeFenetre où on a donné le nom d'une fonction callback ? Eh bien définissons-la. ^^ Voilà déjà son prototype :

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam);

Son type de retour est assez spécial, mais j'ai choisi de ne pas vous le détailler ici, pour ne pas vous encombrer la tête avec des choses inutiles.

Le paramètre 1 désigne le handle de la fenêtre concernée :

HWND fenetrePrincipale

Le paramètre 2 désigne le message envoyé par la boucle événementielle traitée :

UINT message

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Les paramètres 3 et 4 désignent des pointeurs d'int chargés d'apporter des précisions sur l'origine du message :

WPARAM wParam, LPARAM lParam

Ces paramètres vous seront décrits un peu plus tard, quand nous parlerons plus en détail des messages créés par l'utilisateur.

La fonction callback étant un traitement des messages envoyés à la fenêtre, elle est chargée de faire telle ou telle action en fonction de tel ou tel message. C'est
heureusement nous qui devons la coder. :p

Dans un premier temps, je vous propose de gérer les messages à l'intérieur de cette fonction de la manière suivante :

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(fenetrePrincipale, message, wParam, lParam);
}
}

Le switch détermine quel message a été perçu par GetMessage :

WM_CREATE est envoyé à la création de la fenêtre. (Vous pourrez par ailleurs récupérer l'argument optionnel n°11 de CreateWindow à cet endroit.)

WM_DESTROY est envoyé lors de la destruction de la fenêtre. Par défaut (vous verrez que nous pouvons le changer), il est déclenché par WM_CLOSE,
correspondant à un clic sur la croix en haut à droite que vous connaissez si bien ;) . Ici, il est traité, et PostQuitMessage est exécuté : il s'agit d'une fonction
permettant de quitter simplement et proprement le programme. Elle prend comme unique argument 0.

Si aucun message déclaré explicitement n'est perçu, on retourne la procédure par défaut fournie par DefWindowProc.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Code complet
Et voilà : vous êtes prêts pour créer votre première fenêtre ! En combinant le tout, vous devriez avoir ce code-ci :magicien: :

#include <windows.h>

LRESULT CALLBACK procedureFenetrePrincipale(HWND, UINT, WPARAM, LPARAM);

int WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
HWND fenetrePrincipale;
MSG message;
WNDCLASS classeFenetre;

classeFenetre.style = 0;
classeFenetre.lpfnWndProc = procedureFenetrePrincipale;
classeFenetre.cbClsExtra = 0;
classeFenetre.cbWndExtra = 0;
classeFenetre.hInstance = NULL;
classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);
classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
classeFenetre.lpszMenuName = NULL;
classeFenetre.lpszClassName = "classeF";

// On prévoit quand même le cas où ça échoue


if(!RegisterClass(&classeFenetre)) return FALSE;

fenetrePrincipale = CreateWindow("classeF", "Ma première fenêtre winAPI !", WS_OVERLAPPEDWINDOW,


CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
NULL, NULL, cetteInstance, NULL);
if (!fenetrePrincipale) return FALSE;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
ShowWindow(fenetrePrincipale, modeDAffichage);
UpdateWindow(fenetrePrincipale);

while (GetMessage(&message, NULL, 0, 0))


{
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(fenetrePrincipale, message, wParam, lParam);
}
}

Et vous obtenez cette oeuvre magnifique (il ne faut pas exagérer quand même :-° ) :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Enfin, presque ;) . Vous aurez sûrement une barre de titre di érente, à cause du thème de Windows.

Voilà, ce premier chapitre est terminé, j'espère qu'il vous a plu :) . Ne vous découragez surtout pas face à la longueur du code, car cela en vaut la peine, et cela va
rentrer progressivement en tant qu'automatisme.

Rédacteur : Mg++

Elle est vide, ma fenêtre !


Pour le moment, votre fenêtre vous paraît sûrement vide et terne ... nous allons l'animer un peu ;) . Nous allons voir ici comment créer des boutons, comment les
manipuler, et comment faire apparaître un message à l'utilisateur.
Déjà, incorporez ou chargez le code obtenu dans la dernière sous-partie afin d'a icher une fenêtre (changez aussi les dimensions de 300 de hauteur à 110, cela
sera plus esthétique :) ).

Création des boutons


Je vous propose dans cette sous-partie de créer deux boutons : un permettant d'a icher une information à l'utilisateur, et un autre pour quitter (ce n'est pas pour
rien que je l'incorpore, vous allez pouvoir avoir plus de précisions sur la gestion des messages).

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Les boutons sont créés à partir d'une fonction que vous connaissez bien désormais : CreateWindow.

:-° Mais je croyais que c'était pour faire des fenêtres ?

Oui, mais les contrôles sont considérés comme des fenêtres, enfants (donc "attachées" si vous voulez) de la fenêtre parent. Seules les classes de fenêtres sont
di érentes selon le contrôle. Vous vous rappelez de la classe que nous avons créée pour la fenêtre principale, classeFenetre ? Eh bien, pour les contrôles, les
classes sont prédéfinies. On trouve donc comme classes :

BUTTON : permettant de créer un bouton.

LISTBOX : permettant de créer une liste de choix.

STATIC : permettant toutes sortes de choses, comme des images, des groupbox, etc.

Et bien d'autres...

Vous verrez ces contrôles basiques lors du prochain chapitre.

Comme vous vous en doutez, nous allons donc utiliser la classe BUTTON. Avant de les créer, vous devez savoir une chose : les contrôles sont gérés (grâce aux
messages, notifications [servant à avertir d'un événement secondaire]...) à partir soit d'un handle (pratique n'est ce pas ? ^^ ), soit d'un ID, défini grâce à :

#define ID 1

Où ID est généralement un mot l'identifiant bien (par convention, en majuscule), et suivi d'un nombre le remplaçant lors de la compilation. (Il faut avouer que
recevoir le message ' CLIC ' est plus pratique que ' 02123 ' par exemple. Surtout quand les IDs se multiplient...)

Donc, nous allons d'abord créer les handles de boutons, dans un tableau pour plus d'accessibilité. Les contrôles sont déclarés au début du callback de la fenêtre à
laquelle ils appartiennent :

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND boutons[2] = {NULL};

Veillez à bien mettre le mot-clé static lors de la déclaration d'une variable permanente : celui-ci permet à la variable d'avoir la même portée, soit, mais
surtout une durée de vie commune à celle de la fenêtre.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
C'est une méthode quelque peu barbare, surtout quand on a beaucoup de variables permanentes, mais j'ai choisi de vous en parler, car vous connaissez
normalement déjà ce mot-clé ;) . Cependant, j'envisage de vous parler d'une autre méthode (meilleure) plus tard. Pour les curieux, il s'agit de la
combinaison de SetWindowLong() avec GetWindowLong() (et leur déclinaison ~Ptr), permettant d'utiliser les membres de la WindowClass cbClsExtra et
cbWndExtra.

Intégrez au préalable les définitions des ID des boutons au début de votre code :

#define ID_B_PARLER 0
#define ID_B_QUITTER 1

Dernière chose : vous vous rappelez le prototype de CreateWindow ? Cette fonction demandait l'instance. Or, la fonction callback n'entre pas dans la portée de
cette variable. Nous sommes alors contraints d'en faire une variable globale.
Déclarez une variable globale comme suit :

HINSTANCE instance;

Et, en guise de première instruction (de préférence après les déclarations de variables) de WinMain, copiez cetteInstance dans instance comme suit :

instance = cetteInstance;

Bien. Maintenant, nous sommes prêts à créer les boutons. Cette opération se fait en général dans le WM_CREATE, puisqu'ils sont créés en même temps que la
fenêtre parent :

case WM_CREATE:
boutons[0] = CreateWindow("BUTTON", "Parler", WS_CHILD | WS_VISIBLE,
5, 5, 383, 30, fenetrePrincipale, ID_B_PARLER, instance, NULL);
boutons[1] = CreateWindow("BUTTON", "Quitter", WS_CHILD | WS_VISIBLE,
5, 45, 383, 30, fenetrePrincipale, ID_B_QUITTER, instance, NULL);
return 0;

Comme vous pouvez le voir, les styles WS_CHILD et WS_VISIBLE sont appliqués aux boutons :

WS_CHILD solidarise le contrôle à la fenêtre parent. Sans lui, le contrôle flotterait "en l'air", en dehors de la fenêtre.

WS_VISIBLE a iche le contrôle (donc, pas besoin de ShowWindow).

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Vous pouvez voir alors que les ID sont, comme je l'ai dit pendant la description de cette fonction, à la place du menu normalement associé à une fenêtre.

Si une erreur de type "Invalid conversion from...to..." se présente, e ectuez un cast de la variable passée en paramètre en type attendu. En e et, le typage
est plus strict en C++ qu'en C.

Les boutons sont maintenant créés, mais n'ont aucune action.

Gestion de l'enfoncement du bouton


Maintenant que les boutons existent, il nous faut les associer à des actions particulières. Tout d'abord, un peu de théorie. Je vous ai dit que le switch du message
déterminait le message perçu : celui-ci a pu être dans le cas précédent WM_CREATE, ou WM_DESTROY. Mais ce message est complété par wParam et lParam,
passés à la fonction callback. Ceux-ci contiennent des messages complémentaires, ou des notifications. Ces paramètres étant des doubles mots, on peut
récupérer le mot bas et le mot haut de chacun de ces deux paramètres grâce aux macros LOWORD() ou HIWORD().
Justement, quand un bouton est enfoncé, le message vaut WM_COMMAND, et le mot bas de wParam détermine l'ID du bouton qui a été cliqué, et qui a donc
envoyé ce message. En l'utilisant dans notre code, on obtient donc :

case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_B_PARLER:
//Ici l'instruction associée à "Parler"
break;

case ID_B_QUITTER:
//Là l'instruction associée à "Quitter"
break;
}
return 0;

Ainsi, si le bouton "Parler" a été cliqué, le message vaudra WM_COMMAND, et un test du mot bas du paramètre wParam indiquera l'ID de celui ci, ou ID_B_PARLER.

Peut-on, nous (à travers du code), envoyer des messages ?

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Ça tombe bien, je voulais l'utiliser pour le bouton "Quitter". :p En e et, ce bouton a le même e et que "la croix". Comme son message associé est WM_DESTROY,
nous allons donc envoyer le message WM_DESTROY à la fenêtre principale quand le bouton "Quitter" a été cliqué.

La fonction permettant d'y arriver s'appelle SendMessage (quelle coïncidence ^^) ; son prototype est le suivant :

LRESULT SendMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

Vous l'avez deviné, SendMessage ne fait qu'exécuter la fonction callback avec le message spécifié dans msg, les paramètres spécifiés dans wParam et lParam, et
retourne ce que retourne le callback (logique).
Très pratique, vous vous en servirez beaucoup, je vous l'assure ^^ .

En l'adaptant à notre code, nous obtenons ceci :

SendMessage(fenetrePrincipale, WM_DESTROY, 0, 0);

Les paramètres n'étant pas utilisés, nous les mettons à zéro. Ce bout de code est évidemment à mettre dans le ' case ID_B_QUITTER '.

Le bouton "Quitter" est donc opérationnel. Occupons-nous maintenant du bouton "Parler". Ce bouton doit avoir pour e et d'a icher quelque chose à l'utilisateur
: par exemple, de l'informer que le bouton a été cliqué (bon d'accord, ce n'est pas très original, mais ce sont les bases :p ). Et pour cela, rien de mieux que
MessageBox.

MessageBox
Cette fonction, dont le prototype est le suivant :

int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);

a iche une petite messagebox portant comme titre la chaîne spécifiée par lpCaption, comme texte celui spécifié par lpText, étant rattachée à la fenêtre spécifiée
par hWnd et ayant comme style ceux spécifiés dans uType.

Vraiment, vous ne connaissez pas ? Vous avez été bercé aux doux sons des erreurs, ou aux warnings de non-sauvegarde en quittant, tous deux rapportés grâce aux
messages boxes. :p
Les icônes et boutons de celles-ci sont déterminés grâce au paramètre uType, mais la liste ne sera pas donnée ici.

Vous trouverez la liste complète dans notre mini-documentation.

Donc, en utilisant cette fonction en guise de réponse à un clic sur "Parler", on obtient ce code :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
MessageBox(fenetrePrincipale, "Clic !", "Bonjour.", MB_ICONINFORMATION);

MB_ICONINFORMATION est une constante permettant d'ajouter un bouton 'OK' à la messagebox, et une icône en forme de bulle.
Vous n'avez plus qu'à placer ce code dans le 'case ID_B_PARLER' du callback.

Code complet
Eh bien j'ai l'impression que l'on a fini notre modeste programme ! En voici donc le code complet :

#include <windows.h>

#define ID_B_PARLER 0
#define ID_B_QUITTER 1

HINSTANCE instance;

LRESULT CALLBACK procedureFenetrePrincipale(HWND, UINT, WPARAM, LPARAM);

int WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
HWND fenetrePrincipale;
MSG message;
WNDCLASS classeFenetre;

instance = cetteInstance;

classeFenetre.style = 0;
classeFenetre.lpfnWndProc = procedureFenetrePrincipale;
classeFenetre.cbClsExtra = 0;
classeFenetre.cbWndExtra = 0;
classeFenetre.hInstance = NULL;
classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
classeFenetre.lpszMenuName = NULL;
classeFenetre.lpszClassName = "classeF";

// On prévoit quand même le cas où ça échoue


if(!RegisterClass(&classeFenetre)) return FALSE;

fenetrePrincipale = CreateWindow("classeF", "Ma premiere fenetre winAPI !", WS_OVERLAPPEDWINDOW,


CW_USEDEFAULT, CW_USEDEFAULT, 400, 110,
NULL, NULL, cetteInstance, NULL);
if (!fenetrePrincipale) return FALSE;

ShowWindow(fenetrePrincipale, modeDAffichage);
UpdateWindow(fenetrePrincipale);

while (GetMessage(&message, NULL, 0, 0))


{
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND boutons[2] = {NULL};

switch (message)
{
case WM_CREATE:
boutons[0] = CreateWindow("BUTTON", "Parler", WS_CHILD | WS_VISIBLE,
5, 5, 383, 30, fenetrePrincipale, (HMENU)ID_B_PARLER, instance, NULL);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
boutons[1] = CreateWindow("BUTTON", "Quitter", WS_CHILD | WS_VISIBLE,
5, 45, 383, 30, fenetrePrincipale, (HMENU)ID_B_QUITTER, instance, NULL);
return 0;

case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_B_PARLER:
MessageBox(fenetrePrincipale, "Clic", "Bonjour.", MB_ICONINFORMATION);
break;

case ID_B_QUITTER:
SendMessage(fenetrePrincipale, WM_DESTROY, 0, 0);
break;
}
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(fenetrePrincipale, message, wParam, lParam);
}
}

Résultat :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Puis, avec "Parler" :

Rédacteur : Mg++

Les menus
Vous en voulez toujours plus, n'est-ce pas ? ;) Eh bien vous allez apprendre dans ce chapitre à créer des menus. Pour cela, deux manières de coder :

en passant par les ressources

dynamiquement en passant par des fonctions.

Nécessaire
En premier lieu, reprenez le code du chapitre précédent. En guise de test, nous créerons un menu "Actions" comportant les deux actions présentes sous la forme
de boutons "Parler" et "Quitter".

Peu importe la méthode utilisée, des handles de menus seront nécessaires pour chaque menu, et chaque sous-menu associé à la fenêtre. Ceux-ci comportent le
type HMENU :

HMENU menu, sousMenu;

Création du menu
En utilisant des fonctions
Les handles de menus peuvent être alors créés en vue d'un remplissage avec la fonction CreateMenu, ne comportant aucun paramètre :

HMENU CreateMenu(VOID);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Une fois créés, nous pouvons les remplir selon leur type avec la fonction suivante :

BOOL AppendMenu(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCSTR lpNewItem);

Cette fonction, dont le rôle est d'ajouter une entrée, que cela soit une commande ou un sous-menu, comporte les arguments suivants :

L'argument 1 désigne le menu auquel est associée l'entrée :

HMENU hMenu

L'argument 2 désigne le type de l'entrée, mais aussi par association de flags, des options facultatives (désactivé, coché, illustré, etc.) :

UINT uFlags

L'argument 3 désigne, dans le cas d'une commande, son ID (ayant le même e et que ceux des boutons), ou dans le cas d'une entrée popup, le handle du
sous-menu associé :

UINT_PTR uIDNewItem

L'argument 4 désigne le nom a iché par l'entrée :

LPCSTR lpNewItem

Si vous voulez créer une entrée popup (donc un sous-menu), le uFlags doit correspondre à la valeur MF_POPUP. Dans le cas d'une commande, il doit être égal à
MF_STRING.
Les séparateurs peuvent, eux, être créés avec MF_SEPARATOR (les deux derniers paramètres seront alors ignorés).

Bien sûr, les sous-menus doivent être définis avant d'être associés à un menu, ou, dans le cas contraire, celui-ci n'aurait rien à intégrer.

Dans notre cas, la création du menu serait comme ceci :

//Déclarations :
HMENU menu, sousMenu;

//...

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
sousMenu = CreateMenu();
AppendMenu(sousMenu, MF_STRING, ID_B_PARLER, "Parler");
AppendMenu(sousMenu, MF_SEPARATOR, (UINT)NULL, "");
AppendMenu(sousMenu, MF_STRING, ID_B_QUITTER, "Quitter");

menu = CreateMenu();
AppendMenu(menu, MF_POPUP, (UINT)sousMenu, "Actions");

En utilisant les ressources


Les ressources servent à énormément de choses en WinAPI. Elles servent, comme vous le savez, à spécifier les fichiers stockés dans l'exécutable en précisant son
ID, type et chemin, mais aussi à définir des accélérateurs clavier (que nous verrons plus tard), des schémas de boîtes de dialogue (dont nous aborderons
l'utilisation dans le chapitre suivant), ou encore des schémas de menus (qui nous intéressent ici :p ), et bien d'autres choses.

La création d'un menu en ressource est plus logique qu'en utilisant AppendMenu. Elle observe donc une hiérarchie sous cette forme, qu'on appelle
communément template :

ID_MENU MENU
BEGIN
POPUP "Menu"
BEGIN
POPUP "Sous Menu"
BEGIN
MENUITEM "Truc", ID_TRUC
MENUITEM SEPARATOR
MENUITEM "Machin", ID_MACHIN
END
MENUITEM "Groar", ID_GROAR
END
POPUP "Menu2"
BEGIN
MENUITEM "Miaou", ID_MIAOU
END
END

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
(Bon d'accord, vive les noms... mais c'était pour vous montrer les di érents cas possibles :-° .)

Vous ne connaissez sûrement pas les mots-clés BEGIN et END : en fait, il s'agit d'une autre notation utilisée en ressources pour les accolades ouvrantes et
fermantes.

Comme vous pouvez le voir, ID_MENU n'est pas visible : il s'agit de l'identificateur du menu. (D'ailleurs, bien qu'il soit un ID, il n'a pas besoin d'être défini.) Seules
les entrées entre ses BEGIN et END sont visibles : POPUP désigne les menus déroulants, et MENUITEM une commande (je suppose que vous savez ce que signifie
SEPARATOR désormais ;) ). Les ID de chaque commande doivent être spécifiés après le nom a iché et une virgule.

On peut, tout comme AppendMenu, lui appliquer des flags permettant de cocher l'entrée, la désactiver, etc. ; dans ce cas-ci, elles sont spécifiées à la suite
après l'ID de la commande et une virgule séparatrice.

Pour notre exemple, le code en ressource serait le suivant :

ID_MENU MENU
BEGIN
POPUP "Actions"
BEGIN
MENUITEM "Parler", ID_B_PARLER
MENUITEM "Quitter", ID_B_QUITTER
END
END

Bien. Après avoir créé le menu, encore faut-il le récupérer pour l'associer à la fenêtre. Pour cela, on utilise LoadMenu. Cette fonction, prenant comme premier
paramètre l'instance actuelle, et en deuxième l'ID du menu, se charge de renvoyer un handle de menu. En utilisant ce handle de menu, vous pourrez l'utiliser lors
de CreateWindow ou SetMenu (voir méthodes d'associations ci-après).

Si vous utilisez la classe de fenêtre pour l'association, vous pouvez vous passer de ce passage, et indiquer de suite l'ID du menu au champ de la classe
correspondante.

Association du menu avec la fenêtre


Afin d'intégrer le menu à la fenêtre, vous avez trois méthodes.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Dans le cas d'une définition sans ressources (ou avec, mais en utilisant LoadMenu), à la création de la fenêtre, vous devez passer le nom du menu parent (ici
menu) au paramètre n°9 de CreateWindow, étant hMenu, sans guillemets. Exemple :

fenetrePrincipale = CreateWindow("classeF", "Ma premiere fenetre winAPI !", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAUL
T, 400, 130, NULL, <gras>menu</gras>, cetteInstance, NULL);

Dans le cas d'une définition utilisant les ressources, à la définition de la classe de fenêtre, vous devez passer le nom identificateur du menu au paramètre
lpszMenuName de la structure WNDCLASS entre guillemets. Exemple :

classeFenetre.lpszMenuName = "MENU";

Dans les deux cas, dans du reste du code, vous pouvez utiliser la fonction SetMenu, prenant comme premier paramètre le nom de la fenêtre à laquelle le
menu (précisé dans le paramètre 2 sous HMENU) est associé. Exemple (cas utilisant les ressources) :

SetMenu(fenetrePrincipale, LoadMenu(instance, "ID_MENU"));

Code complet
Contenu des autres fichiers (cas des ressources)
Resource.rc :

#include <windows.h>

#include "constantes.h"

ID_MENU MENU
BEGIN
POPUP "Actions"
BEGIN
MENUITEM "Parler", ID_B_PARLER
MENUITEM SEPARATOR
MENUITEM "Quitter", ID_B_QUITTER

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
END
END

constantes.h :

#ifndef CONSTANTES_H
#define CONSTANTES_H

#define ID_B_PARLER 0
#define ID_B_QUITTER 1

#endif

(Protection contre les inclusions multiples facultative pour le moment.)

1ère méthode

#include <windows.h>

#define ID_B_PARLER 0
#define ID_B_QUITTER 1

HINSTANCE instance;

LRESULT CALLBACK procedureFenetrePrincipale(HWND, UINT, WPARAM, LPARAM);

int WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
HWND fenetrePrincipale;
MSG message;
WNDCLASS classeFenetre;
HMENU menu, sousMenu;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
instance = cetteInstance;

sousMenu = CreateMenu();
AppendMenu(sousMenu,MF_STRING, ID_B_PARLER, "Parler");
AppendMenu(sousMenu,MF_SEPARATOR, (UINT)NULL, "");
AppendMenu(sousMenu,MF_STRING,ID_B_QUITTER,"Quitter");

menu = CreateMenu();
AppendMenu(menu, MF_POPUP, (UINT)sousMenu, "Actions");

classeFenetre.style = 0;
classeFenetre.lpfnWndProc = procedureFenetrePrincipale;
classeFenetre.cbClsExtra = 0;
classeFenetre.cbWndExtra = 0;
classeFenetre.hInstance = NULL;
classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);
classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
classeFenetre.lpszMenuName = NULL;
classeFenetre.lpszClassName = "classeF";

// On prévoit quand même le cas où ça échoue


if(!RegisterClass(&classeFenetre)) return FALSE;

fenetrePrincipale = CreateWindow("classeF", "Ma premiere fenetre winAPI !", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAU
LT, 400, 130, NULL, menu /* Ou LoadMenu(instance, "ID_MENU")*/, cetteInstance, NULL);

if (!fenetrePrincipale) return FALSE;

ShowWindow(fenetrePrincipale, modeDAffichage);
UpdateWindow(fenetrePrincipale);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
while (GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND boutons[2] = {NULL};

switch (message)
{
case WM_CREATE:
boutons[0] = CreateWindow("BUTTON", "Parler", WS_CHILD | WS_VISIBLE,
5, 5, 383, 30, fenetrePrincipale, (HMENU)ID_B_PARLER, instance, NULL);
boutons[1] = CreateWindow("BUTTON", "Quitter", WS_CHILD | WS_VISIBLE,
5, 45, 383, 30, fenetrePrincipale, (HMENU)ID_B_QUITTER, instance, NULL);
return 0;

case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_B_PARLER:
MessageBox(fenetrePrincipale, "Clic", "Bonjour.", MB_ICONINFORMATION);
break;

case ID_B_QUITTER:
SendMessage(fenetrePrincipale, WM_DESTROY, 0, 0);
break;
}
return 0;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(fenetrePrincipale, message, wParam, lParam);
}
}

2ème méthode

#include <windows.h>

#include "constantes.h"

HINSTANCE instance;

LRESULT CALLBACK procedureFenetrePrincipale(HWND, UINT, WPARAM, LPARAM);

int WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
HWND fenetrePrincipale;
MSG message;
WNDCLASS classeFenetre;

instance = cetteInstance;

classeFenetre.style = 0;
classeFenetre.lpfnWndProc = procedureFenetrePrincipale;
classeFenetre.cbClsExtra = 0;
classeFenetre.cbWndExtra = 0;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
classeFenetre.hInstance = NULL;
classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);
classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
classeFenetre.lpszMenuName = "ID_MENU";
classeFenetre.lpszClassName = "classeF";

// On prévoit quand même le cas où ça échoue


if(!RegisterClass(&classeFenetre)) return FALSE;

fenetrePrincipale = CreateWindow("classeF", "Ma premiere fenetre winAPI !", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAU
LT, 400, 130, NULL, NULL, cetteInstance, NULL);

if (!fenetrePrincipale) return FALSE;

ShowWindow(fenetrePrincipale, modeDAffichage);
UpdateWindow(fenetrePrincipale);

while (GetMessage(&message, NULL, 0, 0))


{
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND boutons[2] = {NULL};

switch (message)
{

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
case WM_CREATE:
boutons[0] = CreateWindow("BUTTON", "Parler", WS_CHILD | WS_VISIBLE,
5, 5, 383, 30, fenetrePrincipale, (HMENU)ID_B_PARLER, instance, NULL);
boutons[1] = CreateWindow("BUTTON", "Quitter", WS_CHILD | WS_VISIBLE,
5, 45, 383, 30, fenetrePrincipale, (HMENU)ID_B_QUITTER, instance, NULL);
return 0;

case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_B_PARLER:
MessageBox(fenetrePrincipale, "Clic", "Bonjour.", MB_ICONINFORMATION);
break;

case ID_B_QUITTER:
SendMessage(fenetrePrincipale, WM_DESTROY, 0, 0);
break;
}
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(fenetrePrincipale, message, wParam, lParam);
}
}

3ème méthode

#include <windows.h>

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
#include "constantes.h"

HINSTANCE instance;

LRESULT CALLBACK procedureFenetrePrincipale(HWND, UINT, WPARAM, LPARAM);

int WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
HWND fenetrePrincipale;
MSG message;
WNDCLASS classeFenetre;

instance = cetteInstance;

classeFenetre.style = 0;
classeFenetre.lpfnWndProc = procedureFenetrePrincipale;
classeFenetre.cbClsExtra = 0;
classeFenetre.cbWndExtra = 0;
classeFenetre.hInstance = NULL;
classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);
classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
classeFenetre.lpszMenuName = NULL;
classeFenetre.lpszClassName = "classeF";

// On prévoit quand même le cas où ça échoue


if(!RegisterClass(&classeFenetre)) return FALSE;

fenetrePrincipale = CreateWindow("classeF", "Ma premiere fenetre winAPI !", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAU
LT, 400, 130, NULL, NULL, cetteInstance, NULL);
if (!fenetrePrincipale) return FALSE;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
ShowWindow(fenetrePrincipale, modeDAffichage);
UpdateWindow(fenetrePrincipale);

while (GetMessage(&message, NULL, 0, 0))


{
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND boutons[2] = {NULL};

switch (message)
{
case WM_CREATE:
boutons[0] = CreateWindow("BUTTON", "Parler", WS_CHILD | WS_VISIBLE,
5, 5, 383, 30, fenetrePrincipale, (HMENU)ID_B_PARLER, instance, NULL);
boutons[1] = CreateWindow("BUTTON", "Quitter", WS_CHILD | WS_VISIBLE,
5, 45, 383, 30, fenetrePrincipale, (HMENU)ID_B_QUITTER, instance, NULL);
SetMenu(fenetrePrincipale, LoadMenu(instance, "ID_MENU"));
/*Ou dans le cas manuel, SetMenu(fenetrePrincipale, menu); où menu a été d"jà créé*/
return 0;

case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_B_PARLER:
MessageBox(fenetrePrincipale, "Clic", "Bonjour.", MB_ICONINFORMATION);
break;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
case ID_B_QUITTER:
SendMessage(fenetrePrincipale, WM_DESTROY, 0, 0);
break;
}
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(fenetrePrincipale, message, wParam, lParam);
}
}

Résultat :

Pour aller plus loin


Activer / désactiver une entrée
Dès la création du menu : spécifier le flag MF_DISABLED pour désactiver l'entrée (MF_ENABLED, permettant de l'activer, étant par défaut), ou MF_GRAYED
pour le griser. Exemple :

MENUITEM "Parler", ID_B_PARLER, MF_GRAYED

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Dans le reste du code : utiliser la fonction EnableMenuItem, prenant comme premier paramètre le handle de menu, comme deuxième soit l'emplacement
(basé sur 0) de l'entrée, soit sa commande (le choix étant spécifié par la valeur du troisième paramètre), et comme troisième son mode, par combinaison de
son mode de détermination (MF_BYCOMMAND implique d'utiliser la commande pour le deuxième paramètre, et MF_BYPOSITION l'inverse) et du mode
d'a ichage, étant les mêmes valeurs possibles que pour les flags des entrées décrits ci-dessus. Exemple :

EnableMenuItem(menu, ID_B_PARLER, MF_BYCOMMAND | MF_GRAYED);

Cocher / Décocher une entrée


Dès la création du menu, on peut spécifier le flag MF_CHECKED (pour coché) ou MF_UNCHECKED (valeur par défaut, non coché). Exemple :

MENUITEM "Parler", ID_B_PARLER, MF_CHECKED

Dans le reste du code : utiliser la fonction CheckMenuItem, prenant comme premier paramètre le handle de menu concerné, et pour les deuxième et
troisième paramètres, le même système que pour EnableMenuItem, excepté le fait que les états possibles sont ceux spécifiés ci-dessus. Exemple :

CheckMenuItem(menu, ID_B_PARLER, MF_BYCOMMAND | MF_CHECKED);

MF_BYCOMMAND permet d'utiliser la commande de l'élément de menu concerné comme moyen de le déterminer, mais rien ne vous empêche d'utiliser
MF_BYPOSITION pour son index.

Ajouter une icône à un élément de menu


Utilisez SetMenuItemBitmaps(), comme illustré dans l'exemple suivant :

SetMenuItemBitmaps(
hMenu,
ID_PARLER,
MF_BYCOMMAND,
LoadBitmap(hInstance, "talkBtnBmp_normal"),
LoadBitmap(hInstance, "talkBtnBmp_selected")
);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Rédacteur : Mg++

Les boîtes de dialogue


Nous allons maintenant aborder les boîtes de dialogue. Pour ce chapitre, l'objectif sera juste d'ajouter une boîte de dialogue simple (comportant une icône et du
texte) faisant o ice d'"A propos".

Préparation
Pour faire apparaître la boîte de dialogue, nous avons besoin d'une commande. Pour cela, nous allons rajouter un menu popup, au même niveau que "Actions",
mais ayant pour nom "Aide". Dans celui-ci, une entrée-commande sera ajoutée, portant "A propos" comme nom, et ID_B_APROPOS comme ID.

Pour cela, ajoutez (exemple utilisant les ressources : adaptez en conséquence pour les autres méthodes) :

POPUP "Aide"
BEGIN
MENUITEM "A propos", ID_B_APROPOS
END

dans le template du menu en ressources.


ID_B_APROPOS devra être par ailleurs défini dans constantes.h.
Enfin et bien sûr, ajoutez un nouveau 'case' portant cet ID dans le switch du mot faible du message WM_COMMAND. Nous le remplirons plus tard.
La création d'une boîte de dialogue exige deux parties distinctes : la définition de son template, et sa création proprement dite. Voyons chacune de ces étapes.

Template ressource
Vous vous souvenez du template d'un menu en ressources ? C'est à peu près pareil pour une boîte de dialogue, excepté le fait que le mot-clé MENU est remplacé
par DIALOG (ou DIALOGEX, si vous utilisez des styles étendus), et des informations supplémentaires comme sa position / largeur / hauteur, ses styles et son titre
sont rajoutés juste avant la définition. Un schéma basique de boîte de dialogue peut alors être le suivant :

ID_DIALOGUE DIALOG
CW_USEDEFAULT, CW_USEDEFAULT, 200, 120
STYLE WS_OVERLAPPEDWINDOW
CAPTION "Titre"

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
BEGIN
END

L'ordre des ajouts n'est pas important, excepté le fait que les positions (les quatre paramètres entre virgules) de la boîte de dialogue doivent être les premiers à
être définis.
WS_OVERLAPPEDWINDOW rend la boîte de dialogue modale, parfaitement banale : barre de titre, menu système (réduire, fermer, etc.)... tous les styles
applicables aux fenêtres principales (contenus donc dans le champ uStyle de la WNDCLASS) le sont ici. Quant à CAPTION (dont la traduction française donne
"Titre"), il indique la chaîne de caractères à a icher dans la barre de titre (d'où son nom).

Vous pouvez consulter tous les styles applicables aux boîtes de dialogue dans la documentation ci-jointe.

Chaque ajout de contrôle s'exécute par l'intermédiaire de mots-clés. Sauf exception (informations en surplus nécessaires, etc.), les lignes de "déclaration" de
contrôles en utilisant ces mots-clés possèdent une organisation de ce type :

MOTCLE TEXTE_ASSOCIE, ID, x, y, w, h, STYLES

Où x et y sont les coordonnées du coin supérieur gauche du contrôle, et w et h les dimensions du contrôle.
Par exemple, un bouton possède comme mot clé PUSHBUTTON. S'il est le bouton par défaut, il est alors DEFPUSHBUTTON.
Autre exemple (je ne les choisis pas au hasard ;) ) : une icône possède le même mot-clé que pendant une intégration à l'exécutable de celle-ci, en passant par les
ressources, à savoir ICON.
Enfin, du texte peut être a iché avec le mot clé LTEXT (justifié à gauche) ou RTEXT (justifié à droite).

D'autres mots-clés seront présentés en même temps que le cours sur le contrôle concerné (prochaine partie).

Maintenant que vous savez tout ceci, vous êtes prêts à définir le template de votre boîte de dialogue. En premier lieu, intégrez à l'exécutable l'icône voulue avec,
comme vous le savez, la syntaxe suivante :

icone1 ICON "chemin/icone.ico"

Je vous propose donc :

APROPOS DIALOG
CW_USEDEFAULT, CW_USEDEFAULT, 200, 120

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
CAPTION "Titre"
STYLE WS_OVERLAPPEDWINDOW
BEGIN
DEFPUSHBUTTON "Ok", IDOK, 96, 90, 42, 12
ICON icone1, -1, 60, 55, 32, 32
LTEXT "A propos test des boîtes de dialogue", -1, 100, 58, 100, 10
END

IDOK est déjà déclaré avec l'API, tout comme IDCANCEL et d'autres.

-1 est spécifié quand le contrôle n'a pas besoin d'ID (comme les icônes ou ici les textes).

Maintenant que le schéma est créé, passons à la création proprement dite.

Création
Pour créer la boîte de dialogue, deux méthodes : soit vous en faites une indépendante, de déco, etc., soit vous voulez la manipuler.

Les fonctions utilisées auront chacune un but spécifique, mais rien ne vous empêche d'utiliser l'une ou l'autre tout le temps. Ce sont juste des questions de
goûts et de besoins.

Vous pouvez donc utiliser soit CreateDialog, soit DialogBox. Leur prototype est presque pareil : elles possèdent toutes deux les mêmes paramètres, mais
CreateDialog permet de récupérer un handle de fenêtre sur la boîte de dialogue créée (ce qui vous fait donc deviner que CreateDialog est la fonction à utiliser, si
vous voulez manipuler la boîte de dialogue à partir d'une autre fenêtre, récupérer des infos, etc.).
Voici donc leurs paramètres :

Le premier désigne l'instance actuelle :

HINSTANCE hInstance

Le deuxième désigne le template à utiliser, donc l'ID (plutôt une chaîne identifiante) de la boîte de dialogue entre guillemets :

LPCTSTR lpTemplate

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Le troisième désigne le handle de la fenêtre parent :

HWND hWndParent

Le dernier désigne la fonction callback de la boîte de dialogue (un cast sera peut être nécessaire) :

DLGPROC lpDialogFunc

L'intérêt de CreateDialog subsiste dans le fait que la boîte de dialogue peut être créée au tout début, être manipulée entre temps et a ichée quand on la
demande. Mais tout comme DialogBox, elle s'a iche juste après être créée. Vous allez donc peut être avoir recours à ShowWindow.

Vous pouvez aussi passer des paramètres aux boîtes de dialogue créées, en utilisant DialogBoxParam ou CreateDialogParam permettant d'envoyer une
information (structure) dans le paramètre lParam du message WM_INITDIALOG (celui-ci étant donc passé dans le 5ème paramètre de ces deux fonctions).

Donc, si on choisit par exemple DialogBox comme fonction, on aura alors l'extrait de code suivant :

case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_B_APROPOS:
DialogBox(instance, "APROPOS", fenetrePrincipale, (DLGPROC)aPropos_procedure);
break;

Or, aPropos_procedure n'existe pas. Nous allons donc nous occuper de sa fonction callback.

La fonction callback
Similaire à la procédure de la fenêtre principale, elle possède néanmoins un type de retour di érent : BOOL APIENTRY. Je ne vais pas non plus le décrire ici.
Quelques di érences notoires : WM_CREATE a été remplacé par WM_INITDIALOG, et WM_DESTROY n'est pas envoyé : EndDialog s'occupe de fermer la fenêtre
(donc à ne pas utiliser de suite avec CreateDialog) en prenant comme paramètre : le handle de la boîte de dialogue, et 0.

On peut donc avoir la procédure suivante :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
BOOL APIENTRY aPropos_procedure(HWND boiteDeDialogue,UINT message,WPARAM wParam,LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:

return TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDCANCEL || LOWORD(wParam) == IDOK)
{
EndDialog(boiteDeDialogue,0);
return TRUE;
}
return 0;

default:
return FALSE;
}
}

Votre boîte de dialogue est alors achevée !

Code complet
Voici maintenant le code complet :
ressource.rc :

#include <windows.h>

#include "constantes.h"

icone1 ICON "Icones/icone.ico"

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
ID_MENU MENU
BEGIN
POPUP "Actions"
BEGIN
MENUITEM "Parler", ID_B_PARLER
MENUITEM SEPARATOR
MENUITEM "Quitter", ID_B_QUITTER
END
POPUP "Aide"
BEGIN
MENUITEM "A propos", ID_B_APROPOS
END
END

APROPOS DIALOG
CW_USEDEFAULT, CW_USEDEFAULT, 200, 120
CAPTION "Titre"
STYLE WS_OVERLAPPEDWINDOW
BEGIN
DEFPUSHBUTTON "Ok", IDOK, 76, 90, 42, 12
ICON icone1, -1, 30, 50, 32, 32
LTEXT "A propos test des boîtes de dialogue", -1, 60, 38, 200, 10
END

constantes.h :

#ifndef CONSTANTES_H
#define CONSTANTES_H

#define ID_B_PARLER 0
#define ID_B_QUITTER 1
#define ID_B_APROPOS 2

#endif

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
main.cpp :

#include <windows.h>

#include "constantes.h"

HINSTANCE instance;

LRESULT CALLBACK procedureFenetrePrincipale(HWND, UINT, WPARAM, LPARAM);


BOOL APIENTRY aPropos_procedure(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);

int WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
HWND fenetrePrincipale;
MSG message;
WNDCLASS classeFenetre;

instance = cetteInstance;

classeFenetre.style = 0;
classeFenetre.lpfnWndProc = procedureFenetrePrincipale;
classeFenetre.cbClsExtra = 0;
classeFenetre.cbWndExtra = 0;
classeFenetre.hInstance = NULL;
classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);
classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
classeFenetre.lpszMenuName = NULL;
classeFenetre.lpszClassName = "classeF";

// On prévoit quand même le cas où ça échoue


if(!RegisterClass(&classeFenetre)) return FALSE;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
fenetrePrincipale = CreateWindow("classeF", "Ma premiere fenetre winAPI !", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 130,
NULL, LoadMenu(instance, "ID_MENU"), cetteInstance, NULL);
if (!fenetrePrincipale) return FALSE;

ShowWindow(fenetrePrincipale, modeDAffichage);
UpdateWindow(fenetrePrincipale);

while (GetMessage(&message, NULL, 0, 0))


{
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND boutons[2] = {NULL};

switch (message)
{
case WM_CREATE:
boutons[0] = CreateWindow("BUTTON", "Parler", WS_CHILD | WS_VISIBLE,
5, 5, 383, 30, fenetrePrincipale, (HMENU)ID_B_PARLER, instance, NULL);
boutons[1] = CreateWindow("BUTTON", "Quitter", WS_CHILD | WS_VISIBLE,
5, 45, 383, 30, fenetrePrincipale, (HMENU)ID_B_QUITTER, instance, NULL);
return 0;

case WM_COMMAND:
switch(LOWORD(wParam))

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
{
case ID_B_APROPOS:
DialogBox(instance, "APROPOS", fenetrePrincipale, (DLGPROC)aPropos_procedure);
break;

case ID_B_PARLER:
MessageBox(fenetrePrincipale, "Clic", "Bonjour.", MB_ICONINFORMATION);
break;

case ID_B_QUITTER:
SendMessage(fenetrePrincipale, WM_DESTROY, 0, 0);
break;
}
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(fenetrePrincipale, message, wParam, lParam);
}
}

BOOL APIENTRY aPropos_procedure(HWND boiteDeDialogue,UINT message,WPARAM wParam,LPARAM lParam)


{
switch (message)
{
case WM_INITDIALOG:

return TRUE;

case WM_COMMAND:

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
if (LOWORD(wParam) == IDCANCEL || LOWORD(wParam) == IDOK)
{
EndDialog(boiteDeDialogue,0);
return TRUE;
}
return 0;

default:
return FALSE;
}
}

Résultat : (pas d'icône chez moi, je n'en avais pas sous la main ;) )

et

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Pour aller plus loin
Vous pouvez récupérer le handle d'un contrôle d'une boîte de dialogue (pour pouvoir lui envoyer des messages) avec GetDlgItem, prenant comme premier
paramètre le handle de la boîte de dialogue parent du contrôle, et en deuxième son ID.

Vous pouvez changer dynamiquement le texte des XTEXT avec SetDlgItemText, (ou Int, rajoutant un quatrième paramètre étant un booléen si l'int est signé
ou non) prenant les mêmes paramètres que GetDlgItem, mais avec en plus le texte à a icher.

A l'inverse, vous pouvez utiliser GetDlgItemText (ou Int, où le troisième paramètre est un pointeur d'int qui va récupérer les éventuelles erreurs, et un
quatrième spécifiant si l'int est signé ou non. La valeur est alors retournée.) pour en récupérer la valeur. Le troisième paramètre est alors une variable qui va
contenir la valeur, et un quatrième est ajouté pour spécifier la taille de la chaîne à récupérer (pour éviter les dépassements de tampon).

Vous avez maintenant acquis toutes les bases (de chez base :p ), et pourrez alors étendre vos connaissances avec le prochain chapitre, lequel portera sur
les di érents contrôles.

Rédacteur : Mg++

Les contrôles

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Vous en savez maintenant assez pour pouvoir utiliser les autres contrôles, qui vous sont expliqués ici :magicien: :
&lt;information&gt;Seuls les points importants sont abordés. Si vous ne trouvez pas votre bonheur, je vous invite à aller sur msdn.&lt;/information&gt;

Les boutons (tous types)


Ce contrôle est l'un des plus utiles, mais aussi le plus complet.
En e et, ce que l'on désigne par BUTTON est bien plus qu'un bouton, ce peut être :

Un "push button" :

Une "check box" (deux ou trois états) :

Un "radio button" :

Une "group box" :

Nous allons détailler tour à tour chaque utilisation.

Dans la suite de la description, j'emploierai les noms anglais ci-dessus.

La première utilisation (la plus classique) est sans contestation celle du bouton poussoir, qui s'enclenche quand vous cliquez dessus.

La seconde est tout aussi utile : c'est une case à cocher. Elle peut avoir 2 ou 3 états. Les deux états communs sont coché, et non coché. Le troisième est non
assigné, c'est-à-dire que vous ne voulez pas faire de choix entre les deux.

La troisième permet de faire un choix entre plusieurs possibilités.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
La quatrième permet de regrouper les contrôles dans un carré surmonté d'un nom.

Création
Pour créer un BUTTON, il faut appeler CreateWindow en spécifiant "BUTTON" comme classe, ou utiliser le mot-clé PUSHBUTTON en ressource. Néanmoins, cela
ne su it pas car, comme vous l'avez vu, il y a plusieurs possibilités. Ce qui va nous intéresser est donc l'attribut de style. En plus de spécifier les styles habituels
(WM_CHILD, WM_VISIBLE), vous pouvez spécifier un ou plusieurs de ces styles :

BS_3STATE : check box à 3 états.

BS_AUTO3STATE : check box trois états, qui bascule automatiquement d'un état à l'autre.

BS_AUTOCHECKBOX : idem, mais en 2 états.

BS_AUTORADIOBUTTON : radio button qui bascule automatiquement d'un choix à l'autre.

BS_CHECKBOX : check box deux états.

BS_DEFPUSHBUTTON : push button par défaut de la fenêtre.

BS_GROUPBOX : group box.

BS_LEFTTEXT : a iche le texte à gauche du radio button ou de la check box.

BS_OWNERDRAW : vous permet de dessiner vous-même le contrôle.

BS_PUSHBUTTON : push button.

BS_RADIOBUTTON : radio button.

BS_USERBUTTON : obsolète.

BS_BITMAP : a iche une image.

BS_BOTTOM : a iche le texte en bas du bouton.

BS_CENTER : a iche le texte au milieu du bouton (horizontalement).

BS_ICON : a iche une icône.

BS_FLAT : style "plat" (pas d'e et de profondeur).

BS_LEFT : a iche le texte à gauche du bouton.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
BS_MULTILINE : si le texte est trop grand, le contrôle l'a ichera sur plusieurs lignes.

BS_NOTIFY : permet au contrôle d'envoyer des notifications de type BN_KILLFOCUS et BN_SETFOCUS.

BS_PUSHLIKE : fait apparaître et comporter le contrôle comme un bouton (que ce soit un check box ou radio button).

BS_RIGHT : a iche le texte à droite du bouton.

BS_RIGHTBUTTON : même chose que BS_LEFTTEXT.

BS_TEXT : a iche du texte.

BS_TOP : a iche le texte en haut du bouton.

BS_VCENTER : a iche le texte au milieu du bouton, et verticalement.

Vous avez sûrement remarqué qu'il existait le style automatique et non-automatique pour les check box et radio button. Ceux-ci déterminent si vous
voulez que le contrôle change lui-même d'état quand on clique dessus, ou si vous voulez vous en charger vous-mêmes. On préférera le plus souvent le style
automatique.

Comment déterminer les radio button qui fonctionnent ensemble ?

C'est très simple : à chaque fois que vous commencez un nouveau groupe de radio button fonctionnant ensemble, il vous faut ajouter le style WS_GROUP lors de
la création avec CreateWindow (voir le code complet en fin de description).

Il est évident que vous ne devez pas combiner des styles contradictoires, comme le texte a iché à droite et à gauche, ou le style check box et push button
en même temps...

Notifications
Je vais décrire ici les notifications envoyées par le contrôle, via le message WM_COMMAND (sauf mention contraire). Nous partirons du principe que vous savez
comment interagir avec ce message, et je décrirai donc ici uniquement les codes de notifications.

Bon, pour ceux qui n'ont pas suivi (vous savez, au fond de la salle, près du radiateur) on rappelle tout de même que l'ID du contrôle à l'origine de la
notification ainsi que ladite notification constituent respectivement le mot bas et le mot haut de WM_COMMAND (abusez des macros LOWORD() et
HIWORD()...)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
.

BN_CLICKED
Cette notification est envoyée quand l'utilisateur clique sur un bouton.

BN_DBLCLK ou BN_DOUBLECLICKED
Cette notification est envoyée quand l'utilisateur double-clique sur un bouton.

Les boutons de type BS_RADIOBUTTON et BS_OWNERDRAW envoient ce message automatiquement.


Les autres ne l'envoient que si le style BS_NOTIFY est spécifié dans leurs styles.

WM_CTLCOLORBTN
Ce message est envoyé à la fenêtre parent juste avant que le contrôle ne soit dessiné.
Il est utile principalement pour changer la couleur du texte, ou du fond du contrôle pour le dessin.
Les paramètres valent alors:

wParam : handle du DC sur lequel dessiner.

lParam : handle du bouton.

Valeur de retour : handle d'une brosse qui sera utilisée pour le dessin du fond.

Ce message est envoyé directement à la fonction de gestion des messages, et non pas via le message WM_COMMAND.
La brosse retournée ne sera pas automatiquement détruite par le système.

Messages
Ces messages peuvent être envoyés au contrôle avec la fonction :

SendMessage(hCtl,iCode,wParam,lParam)

Pour chaque message, je décrirai le rôle et la signification de wParam et lParam, ainsi que la valeur retournée.

BCM_GETIDEALSIZE

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Ce message permet de récupérer la taille du bouton permettant d'a icher correctement le texte et l'image (si présente).

wParam : 0.

lParam : pointeur vers une structure de type SIZE qui recevra la taille désirée.

Valeur de retour : TRUE en cas de succès, et FALSE en cas d'échec.

BM_CLICK
Ce message permet de simuler un clic de souris sur le bouton.

wParam : 0.

lParam : 0.

Valeur de retour : aucune.

BM_GETCHECK
Ce message permet de récupérer l'état d'un check box ou d'un radio button.

wParam : 0.

lParam : 0.

Valeur de retour : BST_CHECKED, BST_INDETERMINATE ou BST_UNCHECKED (ou 0 en cas d'échec).

BM_GETIMAGE
Ce message permet de récupérer le handle de l'image, ou de l'icône associée au bouton.

wParam : IMAGE_BITMAP ou IMAGE_ICON.

lParam : 0.

Valeur de retour : le handle de l'image ou de l'icône (ou NULL en cas d'échec).

BM_GETSTATE
Ce message permet de récupérer l'état d'un bouton ou d'une check box.

wParam : 0.

lParam : 0.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Valeur de retour : c'est la combinaison d'une ou plusieurs de ces valeurs :

BST_CHECKED : le bouton est coché.

BST_FOCUS : le bouton a le focus clavier.

BST_INDETERMINATE : la check box est non assignée.

BST_PUSHED : le bouton est maintenu enfoncé.

BST_UNCHECKED : le bouton n'est pas coché.

BM_SETCHECK
Ce message permet de définir l'état d'une check box ou un d'un radio button.

wParam : BST_CHECKED, BST_INDETERMINATE ou BST_UNCHECKED

lParam : 0.

Valeur de retour: 0.

BM_SETIMAGE
Ce message permet de définir le handle de l'image, ou de l'icône associée au bouton.

wParam : IMAGE_BITMAP ou IMAGE_ICON.

lParam : le handle de l'image ou de l'icône.

Valeur de retour : le handle de l'image, ou de l'icône associée précédente (ou NULL si aucune).

BM_SETSTATE
Ce message permet de définir l'état de surbrillance d'un bouton. L'état de surbrillance est utilisé lorsque l'utilisateur est en train de cliquer sur le bouton.

wParam : TRUE pour mettre le bouton en surbrillance et FALSE pour ne pas le mettre en surbrillance.

lParam : 0.

Valeur de retour : 0.

L'état de surbrillance n'a ecte pas l'état même d'un bouton, à savoir enfoncé ou pas (ou coché / non coché pour une check box et radio button). Il a ecte
uniquement le dessin du bouton.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Exemple
Ceci est le code complet d'un exemple utilisant les boutons.

#include <windows.h>
#include <stdio.h>

HINSTANCE instance;

#define ID_PUSHBUTTON_1 110


#define ID_PUSHBUTTON_2 111
#define ID_PUSHBUTTON_3 112
#define ID_CHECKBOX_1 113
#define ID_CHECKBOX_2 114
#define ID_CHECKBOX_3 115
#define ID_CHECKBOX_4 116
#define ID_RADIOBUTTON_11 117
#define ID_RADIOBUTTON_12 118
#define ID_RADIOBUTTON_13 119
#define ID_RADIOBUTTON_21 120
#define ID_RADIOBUTTON_22 121
#define ID_RADIOBUTTON_23 122

VOID RemplieFenetrePrincipale(HWND fenetrePrincipale)


{
// Premier groupe: le push button
HWND hGroup=CreateWindow(
"BUTTON",
"Le push button",
WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
10,10,
120,150,
fenetrePrincipale,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
NULL,
instance,
NULL);
{
HWND hControle;
// On le remplit avec un premier push button tout bête
hControle=CreateWindow(
"BUTTON",
"Button 1",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
10+10,10+20,
100,20,
fenetrePrincipale,
(HMENU)ID_PUSHBUTTON_1,
instance,
NULL);
// un second avec quelques flags : plat et plusieurs lignes
hControle=CreateWindow(
"BUTTON",
"Button 2: texte long",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_FLAT|BS_MULTILINE,
10+10,10+50,
100,40,
fenetrePrincipale,
(HMENU)ID_PUSHBUTTON_2,
instance,
NULL);
// et un troisième un peu plus exotique, c'est aussi le bouton par défaut de la fenêtre
// on lui met aussi une image alignée à gauche
hControle=CreateWindow(
"BUTTON",
"",
WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON|BS_ICON|BS_LEFT,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
10+10,10+100,
100,40,
fenetrePrincipale,
(HMENU)ID_PUSHBUTTON_3,
instance,
NULL);

HANDLE hIcon=LoadIcon(NULL,IDI_ERROR);
SendMessage(hControle,BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcon);
}
// Deuxième groupe: les check box
hGroup=CreateWindow(
"BUTTON",
"La check box",
WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
130,10,
120,150,
fenetrePrincipale,
NULL,
instance,
NULL);
{
HWND hControle;
// une check box automatique deux états
hControle=CreateWindow(
"BUTTON",
"Check box 1",
WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
130+10,10+20,
100,20,
fenetrePrincipale,
(HMENU)ID_CHECKBOX_1,
instance,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
NULL);
// le même mais plat, et avec le texte à gauche de la case à cocher
hControle=CreateWindow(
"BUTTON",
"Check box 2",
WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX|BS_FLAT|BS_LEFTTEXT,
130+10,10+50,
100,20,
fenetrePrincipale,
(HMENU)ID_CHECKBOX_2,
instance,
NULL);

// une autre check box simple automatique mais trois états


hControle=CreateWindow(
"BUTTON",
"Check box 3",
WS_CHILD|WS_VISIBLE|BS_AUTO3STATE,
130+10,10+80,
100,20,
fenetrePrincipale,
(HMENU)ID_CHECKBOX_3,
instance,
NULL);

// le même mais non automatique :)


hControle=CreateWindow(
"BUTTON",
"Check box 4",
WS_CHILD|WS_VISIBLE|BS_3STATE,
130+10,10+110,
100,20,
fenetrePrincipale,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
(HMENU)ID_CHECKBOX_4,
instance,
NULL);
}
// troisième groupe : les radio button
hGroup=CreateWindow(
"BUTTON",
"Le radio button",
WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
10,160,
240,110,
fenetrePrincipale,
NULL,
instance,
NULL);
{
HWND hControle;
// trois radio button
hControle=CreateWindow(
"BUTTON",
"Choix 1.1",
WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
10+10,160+20,
100,20,
fenetrePrincipale,
(HMENU)ID_RADIOBUTTON_11,
instance,
NULL);

hControle=CreateWindow(
"BUTTON",
"Choix 1.2",
WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
10+10,160+50,
100,20,
fenetrePrincipale,
(HMENU)ID_RADIOBUTTON_12,
instance,
NULL);

hControle=CreateWindow(
"BUTTON",
"Choix 1.3",
WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
10+10,160+80,
100,20,
fenetrePrincipale,
(HMENU)ID_RADIOBUTTON_13,
instance,
NULL);
// trois autres, mais qui forment un autre groupe
hControle=CreateWindow(
"BUTTON",
"Choix 2.1",
WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
130+10,160+20,
100,20,
fenetrePrincipale,
(HMENU)ID_RADIOBUTTON_21,
instance,
NULL);

hControle=CreateWindow(
"BUTTON",
"Choix 2.2",
WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
130+10,160+50,
100,20,
fenetrePrincipale,
(HMENU)ID_RADIOBUTTON_22,
instance,
NULL);

hControle=CreateWindow(
"BUTTON",
"Choix 2.3",
WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
130+10,160+80,
100,20,
fenetrePrincipale,
(HMENU)ID_RADIOBUTTON_23,
instance,
NULL);
}

VOID AfficheActionCheckBox(int index,HWND hCtl,HWND fenetrePrincipale)


{
// test si la check box est cochée, non cochée ou inderterminée.
LRESULT lRes=SendMessage(hCtl,BM_GETCHECK,0,0);
CHAR lpMessage[128];

sprintf(lpMessage,"La check box n°%d est maintenant %s",index,


lRes==BST_CHECKED?"cochée":
lRes==BST_UNCHECKED?"décochée":"inderterminée");

MessageBox(fenetrePrincipale,lpMessage,"Vous avez modifié une check box",


MB_ICONINFORMATION|MB_OK);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
}

VOID DemandeActionCheckBox4(HWND hCtl,HWND fenetrePrincipale)


{
// test si la check box est cochée, non cochée ou inderterminée.
LRESULT lRes=SendMessage(hCtl,BM_GETCHECK,0,0);
PCHAR lpProchainEtat;
UINT iProchainEtat;
UINT iChoix;
CHAR lpMessage[128];

if(lRes==BST_CHECKED)
{
lpProchainEtat="inderterminée";
iProchainEtat=BST_INDETERMINATE;
}
else if(lRes==BST_INDETERMINATE)
{
lpProchainEtat="décochée";
iProchainEtat=BST_UNCHECKED;
}
else
{
lpProchainEtat="cochée";
iProchainEtat=BST_CHECKED;
}

sprintf(lpMessage,"Voulez-vous passer à l'état %s ?",lpProchainEtat);

iChoix=MessageBox(fenetrePrincipale,lpMessage,"",MB_YESNO);
if(iChoix==IDYES)
SendMessage(hCtl,BM_SETCHECK,(WPARAM)iProchainEtat,0);
}

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
VOID NotificationControle(HWND fenetrePrincipale,UINT message, WPARAM wParam, LPARAM lParam)
{
UINT iId=LOWORD(wParam);
HWND hCtl=(HWND)lParam;

switch(iId)
{
case ID_PUSHBUTTON_1:
MessageBox(fenetrePrincipale,"Vous avez appuyé sur le premier bouton","",MB_OK);
break;
case ID_PUSHBUTTON_2:
MessageBox(fenetrePrincipale,"Vous avez appuyé sur le second bouton","",MB_OK);
break;
case ID_PUSHBUTTON_3:
MessageBox(fenetrePrincipale,"Vous avez appuyé sur le troisième bouton","",MB_OK);
break;
case ID_CHECKBOX_1:
case ID_CHECKBOX_2:
case ID_CHECKBOX_3:
AfficheActionCheckBox(iId-ID_CHECKBOX_1,hCtl,fenetrePrincipale);
break;
case ID_CHECKBOX_4:
DemandeActionCheckBox4(hCtl,fenetrePrincipale);
break;
}
}

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND boutons[2] = {NULL};

switch (message)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
{
case WM_CREATE:
RemplieFenetrePrincipale(fenetrePrincipale);
return 0;
case WM_COMMAND:
NotificationControle(fenetrePrincipale,message,wParam,lParam);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(fenetrePrincipale,message,wParam,lParam);
}
}

int WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
HWND fenetrePrincipale;
MSG message;
WNDCLASS classeFenetre;

instance = cetteInstance;

classeFenetre.style = 0;
classeFenetre.lpfnWndProc = procedureFenetrePrincipale;
classeFenetre.cbClsExtra = 0;
classeFenetre.cbWndExtra = 0;
classeFenetre.hInstance = NULL;
classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);
classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
classeFenetre.lpszMenuName = NULL;
classeFenetre.lpszClassName = "classeF";

// On prévoit quand même le cas où ça échoue


if(!RegisterClass(&classeFenetre))
return FALSE;

fenetrePrincipale=CreateWindow(
"classeF",
"Ma premiere fenetre winAPI !",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
270,320,
NULL,
NULL,
cetteInstance,
NULL);

if (!fenetrePrincipale)
return FALSE;

ShowWindow(fenetrePrincipale,modeDAffichage);
UpdateWindow(fenetrePrincipale);

while(GetMessage(&message,NULL,0,0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}

return message.wParam;
}

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Rédacteur : pamaury

Le contrôle d'édition

Définition
Le contrôle d'édition est un contrôle rectangulaire utilisé dans les boîtes de dialogue pour permettre à l'utilisateur d'entrer et d'éditer du texte au clavier. On peut
également l'utiliser dans une fenêtre standard.

Création
Pour créer un Contrôle d'édition, il faut appeler CreateWindow en spécifiant "EDIT" comme classe. Dans un fichier ressource, on écrira par exemple :

CONTROL "", IDC_NOMDUCONTROLE, <couleur nom="bleu">"EDIT"</couleur>, WS_CHILD | WS_VISIBLE, x, y, largeur, hauteur

Vous pouvez aussi utiliser le mot clé EDITTEXT.

Néanmoins, cela ne su it pas car comme vous vous en doutez, nous avons plusieurs possibilités pour créer notre contrôle. Ce qui va nous intéresser est donc
l'attribut de style . En plus de spécifier les styles habituels (WM_CHILD,WM_VISIBLE), vous pouvez définir un ou plusieurs de ces styles spécifiques qui
commencent tous par "ES_" :

ES_AUTOHSCROLL : défilement automatique du texte de 10 caractères vers la droite quand l'utilisateur tape un caractère à la fin de la ligne. Quand
l'utilisateur presse sur la touche "Entrée", le contrôle fait revenir tout le texte à la position d'origine.

ES_AUTOVSCROLL : fait défiler le texte automatiquement d'une page vers le haut quand l'utilisateur presse sur la touche "Entrée" à la dernière ligne.

ES_CENTER : centre le texte.

ES_LEFT : aligne le texte à gauche.

ES_LOWERCASE : convertit en minuscules tous les caractères tapés dans le contrôle.

ES_MULTILINE : par défaut, un contrôle edit n'est constitué que d'une seule ligne. Ce style a iche un contrôle multiligne.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
ES_NOHIDESEL : quand le contrôle perd le focus ; par défaut, la sélection de texte est cachée, et lorsqu'il a le focus, l'a ichage du texte sélectionné est
inversé. Avec ce style, le texte sélectionné est inversé, que le contrôle ait le focus ou non.

ES_NUMBER : ne permet que les chi res.

ES_OEMCONVERT : convertit le texte entré dans le contrôle, de sorte que le texte tapé est mappé du code ANSI vers le code OEM, et inversement.

ES_PASSWORD : a iche un astérisque * pour chaque caractère entré dans le contrôle Edit. Ce style n'est valide que pour les contrôles d'une seule ligne.

ES_READONLY : empêche l'utilisateur de taper ou d'éditer du texte dans la commande d'édition.

ES_RIGHT : aligne le texte à droite.

ES_UPPERCASE : convertit en majuscules tous les caractères tapés dans le contrôle.

ES_WANTRETURN : indique qu'un retour de chariot est inséré quand l'utilisateur presse sur la touche "Entrée", si le texte est écrit dans un contrôle Edit
multiligne dans une boîte de dialogue. Si ce style n'est pas spécifié, presser sur le touche "Entrée" aura le même e et que de presser sur le bouton par défaut
de la boîte de dialogue. Ce style n'a pas d'e et sur un contrôle Edit d'une ligne.

Il est évident que vous ne devez pas combiner des styles contradictoires, comme le texte a iché à droite et à gauche, ou le style texte en minuscules et texte
en majuscules...

Nous avons créé le contrôle Edit, nous allons maintenant étudier les façons de l'utiliser. Ainsi, dans un premier temps, nous traiterons des notifications envoyées
par le contrôle à la fenêtre parent, puis nous verrons les messages envoyés par la fenêtre parent au contrôle.

Les notifications
L'utilisateur envoie des requêtes d'édition en utilisant le clavier ou la souris. Le système envoie chaque requête à la fenêtre parent du contrôle dans le message
WM_COMMAND.
J'ai considéré que vous savez comment interagir avec ce message, et je décrirai donc ici uniquement les codes de notification.

EN_ALIGN_LTR_EC
Cette notification est envoyée quand l'utilisateur change de direction dans le contrôle d'édition de gauche vers la droite.

EN_ALIGN_RTL_EC
Cette notification est envoyée quand l'utilisateur change de direction dans le contrôle d'édition de droite vers la gauche.

EN_CHANGE

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
L'utilisateur a modifié le texte du contrôle. Le message est envoyé après que le texte soit a iché (di érent de EN-UPDATE).

Si l'on traite cette notification on dira : "s'il y a un changement dans le contrôle, faire ceci..."

EN_HSCROLL
L'utilisateur a cliqué sur la barre horizontale de défilement du contrôle d'édition.

Le système envoie ce message avant de mettre à jour l'écran.

EN_MAXTEXT
Quand l'utilisateur insère du texte, et que le nombre de caractères entrés est supérieur à ce qui est possible pour ce contrôle, l'insertion est tronquée.

Ce message est envoyé quand le contrôle d'édition n'a pas le style ES_AUTOHSCROLL, et que le nombre de caractères insérés excède la largeur du contrôle
; ou quand le contrôle d'édition n'a pas le style ES_AUTOHSCROLL, et que le nombre de lignes de texte entrées dépassent la hauteur du contrôle.

EN_UPDATE
L'utilisateur a modifié le texte dans le contrôle d'édition, et le système va a icher le nouveau texte.

Le système envoie cette notification après avoir formaté le texte, mais avant de l'a icher. Ainsi, l'application peut redimensionner le contrôle.

EN_VSCROLL
L'utilisateur a cliqué sur la barre verticale de défilement, ou a utilisé la roulette de la souris au-dessus du contrôle d'édition.

Le système envoie le message avant la remise à jour de la page.

WM_CTLCOLOREDIT
Ce message est envoyé par le système à la fenêtre parent avant que le contrôle ne soit dessiné. Ce message contient le handle du contexte d'a ichage (DC) dans
wparam, et le handle de la fenêtre fille dans lparam. La fenêtre parent peut utiliser ces handle pour changer les couleurs du texte et du fond du contrôle d'édition.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
- Ce message est envoyé directement à la fonction de gestion des messages, et non pas via le message WM_COMMAND.
- La brosse retournée ne sera pas automatiquement détruite par le système.

Les messages
Ces messages peuvent être envoyés au contrôle avec la fonction :

SendMessage(hCtl,iCode,wParam,lParam)

Pour chaque message, je décrirai le rôle et la signification de wParam et lParam et de la valeur retournée.

EM_GETCUEBANNER
Recherche une sélection textuelle dans le texte a iché.

wParam : pointeur sur une chaîne de caractères unicode qui contient la sélection textuelle.

lParam : taille du bu er qui contient cette sélection.

Valeur retournée : TRUE si la sélection a été trouvée, FALSE en cas d'échec.

EM_GETFIRSTVISIBLELINE
Ce message recherche l'index de la ligne visible la plus haute dans un contrôle d'édition multiligne.

wParam : 0.

lParam : 0.

Valeur retournée : index de la ligne.

Pour un contrôle d'édition d'une seule ligne, cet index sera celui du premier caractère visible de la ligne.

EM_GETHANDLE
Ce message renvoie le handle de la mémoire courante allouée au texte d'un contrôle d'édition multiligne.

wParam: 0.

lParam : 0.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Valeur retournée : handle du bu er qui contient le texte du contrôle d'édition. Si une erreur survient, comme par exemple l'envoi du texte à un contrôle d'une
seule ligne, cette valeur sera 0.

Si la fonction SendMessage réussit, l'application peut accéder au contenu du contrôle d'édition, en donnant la structure HLOCAL à la valeur retournée
avant de la passer à la fonction LocalLock. Pour déverrouiller le bu er, et ainsi pouvoir modifier son contenu, l'application doit au préalable utiliser la
fonction LocalUnlock.

EM_GETLIMITTEXT
Recherche les limites du texte courant.

wParam : 0.

lParam : 0.

Valeur retournée : limite du texte.

La limite du texte est la quantité maximum de texte, en TCHAR, que le contrôle peut contenir. Pour un texte en ANSI, c'est le nombre de bytes ; pour un texte
en Unicode, ce sera le nombre de caractères. Deux documents avec la même limite de caractères rapporteront la même limite de texte, même si l'un est en
norme ANSI, et l'autre en Unicode.

EM_GETLINE
Ce message copie une ligne de texte depuis un contrôle d'édition, et le place dans un bu er défini.

wParam : indique l'index de la ligne à rechercher dans un contrôle d'édition multiligne. Si ce paramètre est 0, la ligne recherchée sera la ligne la plus haute
dans le texte. Si le contrôle ne contient qu'une seule ligne, ce paramètre sera ignoré.

lParam : pointeur sur le bu er qui va recevoir la copie de la ligne. Avant d'envoyer le message, définissez le premier mot de ce bu er à sa taille en TCHAR. Pour
un texte ANSI, c'est le nombre de bytes ; pour un texte Unicode c'est le nombre de caractères. Cette taille dans le premier mot sera remplacée par la copie de
la première ligne.

Valeur retournée : nombre de TCHAR copiés. La valeur retournée sera 0 si le nombre de lignes spécifié dans le paramètre wParam est plus grand que le
nombre de lignes contenu dans le contrôle d'édition.

La copie de la ligne ne contient pas le caractère nul final \0.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
EM_GETLINECOUNT
Ce message recherche le nombre de lignes dans un contrôle d'édition multiligne.

wParam : 0.

lParam : 0.

Valeur retournée : integer, qui définit le nombre total de lignes de texte contenu dans un contrôle d'édition multiligne. Si le contrôle ne contient pas de texte,
la valeur retournée sera 1. Cette valeur ne sera jamais inférieure à 1.

Ce message recherche le nombre total de lignes de texte, et pas seulement le nombre de lignes de texte visible. Si le dispositif de retour à la ligne
automatique est désactivé, le nombre de lignes peut changer quand les dimensions de la fenêtre d'édition changent.

EM_GETMODIFY
Ce message recherche l'état du flag de modification du contrôle d'édition. Le flag indique si le contenu du contrôle a été modifié.

wParam : 0.

lParam : 0.

Valeur retournée : non nulle s'il y a une modification, 0 s'il n'y a pas de modification.

On peut envoyer le message EM_SETMODIFY au contrôle d'édition pour appliquer ou enlever le flag.

EM_GETPASSWORDCHAR
Ce message recherche le caractère d'un mot de passe que l'utilisateur entre dans le contrôle d'édition.

wParam : 0.

lParam : 0.

Valeur retournée : définit le caractère qui doit être a iché à la place des caractères entrés par l'utilisateur. Si cette valeur est NULL, il n'y a pas de caractères de
mot de passe, et le contrôle a iche les caractères entrés par l'utilisateur.

Si un contrôle d'édition est créé avec le style ES_PASSWORD, le caractère par défaut du mot de passe sera un astérisque (*). Si un contrôle d'édition est créé
sans le style ES_PASSWORD, il n'y aura pas de caractères de mot de passe ; pour changer les caractères du mot de passe, envoyez le message

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
EM_SETPASSWORDCHAR.

EM_GETRECT
Ce message recherche le rectangle de formatage d'un contrôle d'édition. Le rectangle de formatage est le rectangle dans lequel le contrôle a iche le texte. Ce
rectangle est indépendant de la taille de la fenêtre du contrôle d'édition.

wParam : 0.

lParam : pointeur sur une structure RECT qui reçoit le rectangle de formatage.

Valeur retournée : cette valeur n'a pas de grande signification.

Vous pouvez modifier le rectangle de formatage d'un contrôle d'édition multiligne en utilisant les messages EM_SETRECT et EM_SETRECTNP.
Sous certaines conditions, EM-GETRECT ne va pas retourner exactement les valeurs définies par EM_SETRECT ou EM_SETRECTNP, mais elles seront
approximativement correctes avec une variation de quelques pixels.

EM_GETSEL
Message qui recherche les positions des caractères de début et de fin d'une sélection dans le contrôle d'édition.

wParam : pointeur sur un bu er qui reçoit la position de départ de la sélection. Ce paramètre peut être NULL.

lParam : pointeur sur un bu er qui reçoit la position de premier caractère non sélectionné après la fin de la sélection. Ce paramètre peut être NULL.

Valeur retournée : valeur contenant la position de départ de la sélection dans le mot bas, et la position du premier caractère après le dernier sélectionné dans
le mot haut. Si l'une de ces valeurs excède 65,535, la valeur retournée sera 1.

EM_GETWORDBREAKPROC
Ce message recherche l'adresse de la fonction courante de retour à la ligne.

wParam : 0.

lParam : 0.

Valeur retournée : définit l'adresse de la fonction Wordwrap (retour à la ligne) de l'application. Cette valeur est NULL si aucune fonction Wordwrap n'existe.

Une fonction Wordwrap balaie le texte du bu er contenant le texte envoyé pour être a iché. Elle cherche le premier mot qui n'apparaît pas sur la ligne
d'a ichage. La fonction Wordwrap place ce mot au début de la ligne suivante. Une fonction Wordwrap définit le point où le système doit casser la ligne du

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
texte dans un contrôle d'édition multiligne, normalement au niveau d'un caractère d'espacement entre deux mots.

EM_HIDEBALLOONTIP
Cache toute info bulle associée au contrôle d'édition.

wParam : 0.

lParam : 0.

Valeur retournée : si le message réussit, cette valeur sera TRUE, sinon, elle sera FALSE.

EM_LINEFROMCHAR
Ce message recherche l'index de la ligne contenant l'index d'un caractère défini, dans un contrôle d'édition. L'index d'un caractère appartient à une suite dont le
premier terme est 0.

wParam : définit l'index du caractère contenu dans la ligne dont le numéro est recherché. Si ce paramètre est 1, EM_LINEFROMCHAR recherche soit le numéro
de la ligne courante (la ligne où se trouve le curseur), soit, si une sélection existe, le numéro de la ligne où se situe le début de la sélection de texte.

lparam : 0.

Valeur retournée : numéro de la ligne contenant l'index du caractère spécifié dans wParam. Ce numéro appartient à une série qui commence à 0.

EM_LINEINDEX
Ce message définit la limite de texte d'un contrôle d'édition. Cette limite est la quantité maximum de texte, en TCHAR, que l'utilisateur peut entrer dans le
contrôle d'édition.

wParam : spécifie le nombre maximum de TCHAR que l'utilisateur peut entrer. Pour le texte ANSI, c'est le nombre de bytes ; pour le texte Unicode, c'est le
nombre de caractères. Ce nombre ne doit pas inclure le caractère nul terminal.

lParam : 0

Valeur retournée : pas de valeur retournée.

Ce message limite seulement le texte que l'utilisateur peut entrer. Il ne concerne pas le texte qui est déjà dans le contrôle quand le message est envoyé, ni
la longueur du texte copié dans le contrôle d'édition par le message WM_SETTEXT. Si une application utilise le message WM_SETTEXT pour placer plus de
texte que le message EM_LIMITTEXT a établi dans un contrôle d'édition, l'utilisateur pourra éditer entièrement le contenu du contrôle d'édition.
Avant que EM_LIMITTEXT soit appelé, la limite par défaut de la quantité de texte que l'utilisateur peut entrer dans un contrôle d'édition est de 32,767
caractères.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
EM_LINELENGTH
Ce message recherche la longueur, en caractères, d'une ligne dans un contrôle d'édition.

wParam : définit l'index du caractère dans une ligne dont la longueur est recherchée. Si ce paramètre est plus grand que le nombre de caractères dans le
contrôle, la valeur retournée sera 0. Ce paramètre peut être 1. Dans ce cas, le message retourne le nombre de caractères non sélectionnés dans la ligne des
caractères sélectionnés. Par exemple, si une sélection va du 4ème caractère d'une ligne au 8ème caractère avant la fin de la ligne qui suit, la valeur retournée
sera 10 (3 caractères sur la première ligne, et 7 sur la ligne suivante).

lParam : 0.

Valeur retournée : pour des contrôles d'édition multiligne, la valeur retournée est la longueur, en TCHAR, de la ligne définie par le paramètre wParam. Pour le
texte ANSI, c'est le nombre de bytes ; pour le texte Unicode, c'est le nombre de caractères. Cette valeur n'inclut pas le caractère de retour de chariot de fin de
ligne.
Pour un contrôle d'une seule ligne, la valeur retournée est la longueur, en TCHAR, du texte dans le contrôle d'édition.

Utilisez le message EL_LINEINDEX pour rechercher l'index d'un caractère pour un numéro de ligne donné à l'intérieur d'un contrôle d'édition multiligne.

EM_LINESCROLL
Fait défiler le texte dans un contrôle d'édition multiligne.

wParam : définit le nombre de caractères à faire défiler horizontalement.

lParam : définit le nombre de lignes à faire défiler verticalement.

Valeur retournée : si le message est envoyé à un contrôle d'édition multiligne, la valeur est TRUE. Si le message est envoyé à un contrôle d'édition d'une ligne
la valeur est FALSE.

EM_POSFROMCHAR
Ce message recherche les coordonnées dans la zone client d'un caractère dans le contrôle d'édition.

wParam : index du caractère (les index commencent par 0).

lParam : 0.

Valeur retournée : contient les coordonnées du caractère dans la zone client. Le mot bas contient la coordonnée horizontale, et le mot haut contient la
coordonnée verticale.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Une coordonnée retournée peut être négative si le caractère défini n'est pas a iché dans l'aire client du contrôle d'édition. Si le caractère est un délimiteur
de ligne, les coordonnées retournées seront juste après le dernier caractère visible de la ligne. Si l'index spécifié est plus grand que l'index du dernier
caractère dans le contrôle, le contrôle retournera -1.

EM_REPLACESEL
Ce message remplace la sélection courante dans le contrôle d'édition avec le texte spécifié.

wParam : spécifié seulement si l'opération peut être annulée. Si le paramètre est TRUE, l'opération peut être annulée. Si le paramètre est FALSE, l'opération
ne peut pas être annulée.

lParam : pointeur sur une chaîne à terminaison nulle contenant le texte de remplacement.

Valeur retournée : ne retourne pas de valeur.

Pour remplacer tout le texte d'un contrôle d'édition, utilisez le message WM_SETTEXT.
S'il n'y a pas de sélection courante de texte, le texte de remplacement est inséré à l'endroit où est placé le curseur.

EM_SCROLL
Ce message fait défiler le texte verticalement dans un contrôle d'édition. Ce message est équivalent au message WM_VSCROLL.

wParam : peut être une des valeurs suivantes :


*** SB_LINEDOWN : déplace les lignes vers le bas
*** SB_LINEUP : déplace les lignes vers le haut.
*** SB_PAGEDOWN : passe à la page suivante.
*** SB_PAGEUP : passe à la page précédente.

lParam : 0.

Valeur retournée : si le message réussit, le mot haut retourne la valeur TRUE, et le mot bas est le nombre de lignes de défilement. Si le wParam spécifie une
valeur invalide, cette valeur sera FALSE.

EM_SCROLLCARET
Ce message fait avancer le curseur dans le contrôle d'édition.

wParam : ce paramètre est réservé. Il peut être défini à 0.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
lParam : ce paramètre est réservé. Il peut être défini à 0.

Valeur retournée : sans grande signification.

EM_SETCUEBANNER
Le texte du contrôle est a iché comme information, et va s'en aller dès que l'utilisateur commencera à utiliser le contrôle.

wParam : 0

lParam : pointeur sur une chaîne de caractères Unicode, qui contient le texte à a icher en "information".

Valeur retournée : si le message réussit, cette valeur sera TRUE ; dans le cas contraire, FALSE.

EM_SETHANDLE
Message qui définit le handle de la mémoire qui va être utilisée par un contrôle d'édition.

wParam : handle de la mémoire du bu er que le contrôle d'édition utilise pour placer le texte courant a iché, au lieu d'utiliser sa propre mémoire.

lParam : 0

Valeur retournée : pas de valeur retournée.

Avant qu'une application ne définisse un nouveau handle de mémoire, elle doit envoyer un message EM_GETHANDLE pour rechercher le handle de la
mémoire courante du bu er, et doit libérer cette mémoire.

EM_SETLIMITTEXT
Ce message définit la limite du texte d'un contrôle d'édition. La limite du texte est la quantité maximum de texte, en TCHAR, que l'utilisateur peut entrer dans le
contrôle d'édition.
C'est le même message que EM_LIMITTEXT.

wParam : définit le nombre maximum de TCHAR que l'utilisateur peut entrer. Pour un texte ANSI, c'est le nombre de bytes ; pour un texte Unicode, c'est le
nombre de caractères. Ce nombre ne doit pas inclure le caractère nul de fin.

lParam : 0.

Valeur retournée : pas de valeur retournée.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Ce message limite seulement le texte que l'utilisateur peut entrer. Il n'a ecte pas le texte qui est déjà dans le contrôle d'édition quand le message est
envoyé. Il n'a ecte pas non plus la longueur du texte copié dans le contrôle d'édition à l'aide du message WM_SETTEXT. Si une application utilise le
message WM_SETTEXT pour placer plus de texte que ne le définit EM_SETLIMITTEXT à l'intérieur du contrôle, l'utilisateur pourra éditer la totalité du
contenu du contrôle d'édition.
Avant que EM_SETLIMITTEXT soit appelé, la limite par défaut de la quantité de texte qu'un utilisateur peut entrer dans un contrôle d'édition est 32,767
caractères.

EM_SETMODIFY
Ce message applique ou annule le flag de modification pour un contrôle d'édition. Le flag de modification indique si le texte à l'intérieur d'un contrôle d'édition a
été modifié.

wParam : donne la nouvelle valeur pour le flag de modification . Une valeur TRUE indique que le texte a été modifié, une valeur FALSE indique qu'il n'y a pas
eu de modification.

lParam : 0

Valeur retournée : pas de valeur retournée.

Le système met immédiatement le flag de modification à zéro quand le contrôle est créé. Si un utilisateur change le texte du contrôle, le système définit à
"nonzéro" le flag. Vous pouvez envoyer le message EM_GETMODIFY pour trouver le stade du flag de modification du contrôle d'édition.

EM_SETPASSWORDCHAR
Ce message définit ou annule le caractère de mot de passe pour un contrôle d'édition. Quand le caractère de mot de passe est défini, ce caractère est a iché à la
place des caractères entrés par l'utilisateur.

wParam : définit le caractère à a icher à la place des caractères entrés par l'utilisateur. Si ce paramètre est zéro, le contrôle annule le caractère courant de mot
de passe, et a iche les caractères entrés au clavier par l'utilisateur.

lParam : 0.

Valeur retournée : pas de valeur retournée.

Quand un contrôle d' édition reçoit le message EM_SETPASSWORDCHAR, le contrôle redessine tous les caractères visibles en utilisant le caractère
spécifié dans wParam. Si wParam est zéro, le contrôle redessine tous les caractères visibles en utilisant les caractères qui ont été entrés par

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
l'utilisateur.
Si un contrôle d'édition a été créé avec le style ES_PASSWORD, le caractère de mot de passe par défaut est l'astérisque(*).

EM_SETREADONLY
Ce message définit ou annule le style ES_READONLY d'un contrôle d'édition.

wParam : TRUE si le style ES_READONLY est défini, FALSE sinon.

lParam : 0.

Valeur retournée : "non zéro" si la fonction réussit. Zéro si la fonction échoue.

EM_SETRECT
Ce message définit le rectangle de formatage d'un contrôle d'édition multiligne. Le rectangle de formatage est le rectangle dans lequel le contrôle dessine le
texte. Il est indépendant de la taille de la fenêtre du contrôle d'édition.

wParam : 0.

lParam : pointeur sur une structure RECT qui définit les nouvelles dimensions du rectangle. Si le paramètre est NULL, le rectangle de formatage est défini aux
valeurs par défaut.

Valeur retournée : pas de valeur retournée.

Si le contrôle d'édition n'a pas de barre horizontale de défilement, et si le rectangle de formatage est plus large que la fenêtre du contrôle d'édition, les
lignes de textes qui seront plus larges que la fenêtre du contrôle seront coupées au lieu d'être terminées sur la ligne suivante.

Si un contrôle d'édition comporte un bord, le rectangle de formatage sera réduit par la taille du bord. Si vous voulez ajuster le rectangle renvoyé par
EM_GETRECT, vous devez annuler la taille du bord avant d'utiliser le message EM_SETRECT.

EM_SETRECTNP
Ce message définit le rectangle de formatage d'un contrôle d'édition. Ce message est le même que le message EM_SETRECT à ceci près qu'il ne redessine pas la
fenêtre du contrôle d'édition.

wParam : 0.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
lParam : pointeur sur une structure RECT qui définit les nouvelles dimensions du rectangle. Si le paramètre est NULL, le rectangle de formatage est défini aux
valeurs par défaut.

Valeur retournée : pas de valeur retournée.

EM_SETSEL
Ce message sélectionne une suite de caractères dans un contrôle d'édition.

wParam : spécifie la position du caractère situé au début de la sélection.

lParam : spécifie la position du caractère de fin de la sélection.

Valeur retournée : pas de valeur retournée.

La valeur de départ peut être plus grande que la la valeur de fin. La plus petite valeur définira la position du premier caractère dans la sélection.
Inversement, la plus grande valeur définira la position du caractère de fin de la sélection.
Si le départ est 0 et la fin 1, tout le texte dans le contrôle d'édition sera sélectionné.
Si le départ est 1, la sélection sera annulée.

EM_SHOWBALLOONTIP
Ce message a iche une info-bulle associée à un contrôle d'édition.

wParam : 0.

lParam : pointeur sur une structure EDITBALLOONTIP contenant l'information concernant l'info-bulle à a icher.

Valeur retournée : si le message réussit, la valeur retournée sera TRUE ; sinon, FALSE.

EM_UNDO
Ce message annule la dernière opération du contrôle d'édition dans la file des annulations du contrôle.

wParam : 0.

lParam : 0.

Valeur retournée : pour un contrôle d'une seule ligne, cette valeur est toujours TRUE. Pour un contrôle multiligne, cette valeur est TRUE si l'annulation a
réussi, ou FALSE dans le cas contraire.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Une annulation peut également être annulée. Par exemple, vous pouvez restaurer du texte e acé avec le message EM_UNDO, et annuler une nouvelle fois
le texte avec ce message aussi longtemps qu'aucune autre opération ne se placera dans la file.

Exemple

#include <windows.h>
#include <stdio.h>

#define ID_BOUTON1 110


#define ID_BOUTON2 111
#define ID_BOUTON3 112

//variables globales
HINSTANCE inst;
HWND hEdit[2]; //handle des deux contrôles d'édition

//Afficher un contrôle d'édition d'une ligne


HWND afficheEditUneLigne (HWND hwnd)
{
HWND hEdit=CreateWindow(
"EDIT",
"Modifiez le texte SVP",
WS_VISIBLE|WS_CHILD|WS_BORDER|ES_CENTER ,
50,10,500,20,hwnd,NULL,inst,NULL);

return hEdit;
}

//Afficher un contrôle d'édition multiligne


HWND afficheEditMultiligne (HWND hwnd)
{
char texte[2000]={0};
strncat (texte, "Vous voudriez apprendre l'API windows et vous trouvez les autres ",1000);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
strncat (texte, "cours présents sur le net trop difficiles, ou pas assez précis ?",1000);
strncat (texte, "Vous avez frappé à la bonne porte. Bienvenue dans ce tutorial.",1000);
strncat (texte, "Vous allez apprendre ici à vous servir d'une API très développée :",1000);
strncat (texte, "l'API Win32. Sa proximité avec le système d'exploitation lui permet ",1000);
strncat (texte, "d'avoir un contrôle total sur n'importe quelle partie de l'OS et un ",1000);
strncat (texte, "grand éventail de fonctions. L'API Windows est, malheureusement et comme ",1000);
strncat (texte, "son nom l'indique, exclusivement dédié à Windows. Donc si vous ",1000);
strncat (texte, "possédez un autre OS, passez votre chemin. Je considère dans ce tutorial que ",1000);
strncat (texte, "vous ne connaissez strictement rien à l'API Windows, ceci pour ne pas ",1000);
strncat (texte, "décourager les débutants, néammoins, vous aurez besoin des connaissances ",1000);
strncat (texte, "acquises tout au long du tuto de M@teo. Vous trouverez donc ici des ",1000);
strncat (texte, "cours évolutifs, une documentation sur les différents messages, ",1000);
strncat (texte, "notifications, styles, fonctions etc., des projets grands, ",1000);
strncat (texte, "moyens ou petits ainsi que des bibliothèques statiques ",1000);
strncat (texte, "ou dynamiques, et enfin des annexes. ",1000);

HWND hEdit=CreateWindow("EDIT",
texte,
WS_VISIBLE|WS_CHILD|ES_MULTILINE|ES_AUTOVSCROLL,
50,50,500,300,hwnd,NULL,inst,NULL);

return hEdit;
}

//Traitement des messages


void messageCtl(HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam)
{
UINT motBas = LOWORD(wParam);
HWND hCtl= (HWND) lParam;
int nombreLignes=0;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
char lignes[70]={0},nLignes[5]={0};

switch(motBas)
{
case ID_BOUTON1://nombre de lignes

//envoyer le message approprié pour trouver le nombre de lignes dans le contôle


nombreLignes = SendMessage( hEdit[1], EM_GETLINECOUNT,wParam,lParam);

//transformer un integer en chaîne de caractères et afficher le résultat


sprintf(nLignes,"%d",nombreLignes);
strncat(lignes,"Il y a ",70);
strncat(lignes,nLignes,70);
strncat(lignes, " lignes dans ce texte. Supprimez ou ajoutez \n en et testez le message.",70);
MessageBox(hwnd,lignes,"",MB_OK);
break;
case ID_BOUTON2: //marges de gauche
wParam = EC_LEFTMARGIN ;
LOWORD(lParam) = 100;
//ou
//lParam = (LPARAM)MAKELONG (100,0);
//envoi du message au contrôle d'édition
SendMessage( hEdit[1], EM_SETMARGINS,wParam,lParam);
MessageBox(hwnd,"A vous de trouver comment réduire \nles lignes maintenant ! :)","",MB_OK);
break;
}
}

//Traitement des notifications


void NotificationControle(HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam)
{
UINT motHaut= HIWORD(wParam);
HWND hCtl= (HWND) lParam;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
switch(motHaut)
{
//Notification EN_CHANGE envoyée par le contrôle
case EN_CHANGE:
if (hCtl == hEdit[0])
{
MessageBox(hwnd,"Vous avez modifié le texte d'une contrôle à une ligne !!","",MB_OK);
}
break;
case BN_CLICKED: // cliquer sur un des boutons pour analyser les messages
messageCtl((HWND)hwnd,(UINT)message,(WPARAM)wParam,(LPARAM)lParam);
break;
}
}

//Boutons pour la démo


HWND boutonMessage(HWND hwnd,HMENU code,long x, long y, char * texte)
{
HWND hBouton=CreateWindow(
"BUTTON",
texte,
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
x,y,
350,30,
hwnd,
code,
inst,
NULL);
return hBouton;
}

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
LRESULT CALLBACK Procedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

static HWND hBouton[3]={0};

switch (message)

{
//afficher les contrôles d'édition à la réception du message WM_CREATE
case WM_CREATE:
hEdit[0]=afficheEditUneLigne (hwnd);
hEdit[1]=afficheEditMultiligne(hwnd);
//affichage des boutons pour la démo:
hBouton[0]= boutonMessage(hwnd, (HMENU)ID_BOUTON1,120,355,"Tester le message EM_GETLINECOUNT");
hBouton[1]= boutonMessage(hwnd, (HMENU)ID_BOUTON2,120,395,"Test le EM_SETMARGINS (Gauche)");
hBouton[2]= boutonMessage(hwnd, (HMENU)ID_BOUTON3,120,435,"Test le EM_SETMARGINS (Droite)");
return 0;

case WM_COMMAND:
//Recevoir une notification
NotificationControle(hwnd,message,wParam,lParam);
return 0;

case WM_CLOSE:
DestroyWindow(hwnd);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(hwnd, message, wParam, lParam);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
}
}

int WINAPI WinMain(HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
//Variables de la fonction principale
MSG msg;
WNDCLASS wc;
HWND hwnd;
inst = cetteInstance;
// Structure de la classe de la fenêtre principale
wc.style = 0 ;
wc.lpfnWndProc = Procedure;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = cetteInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(1+ COLOR_BTNFACE);
wc.lpszMenuName = NULL;
wc.lpszClassName = "ClassePrincipale";

//Enregistrer la classe de fenêtre


if(!RegisterClass(&wc)) return FALSE;
hwnd = CreateWindow("ClassePrincipale", "Démo du contrôle d'édition",WS_OVERLAPPEDWINDOW ,
200,100,600 ,500, NULL, NULL, cetteInstance, NULL);
if (!hwnd) return FALSE;
ShowWindow(hwnd,SW_SHOW);
UpdateWindow( hwnd );

//Boucle de message
while (GetMessage(&msg, NULL, 0, 0))

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

Rédactrice : acryline

La liste déroulante
Ce contrôle est appelé sous Windows une COMBOBOX, et permet d'a icher une liste déroulante de choix.

Création
Pour créer une combobox, il faut appeler CreateWindow en spécifiant "COMBOBOX" comme classe.

En ressource, utilisez le mot-clé CONTROL (dont l'utilisation est spécifiée plus loin), ou encore (plus adapté) COMBOBOX sous la forme suivante :
COMBOBOX ID_COMBO, x, y, w, h, STYLES

Néanmoins, cela ne su it pas, car comme vous l'avez vu, il y a plusieurs possibilités. Ce qui va nous intéresser est donc l'attribut de style. En plus de spécifier les
styles habituels (WM_CHILD,WM_VISIBLE), vous pouvez spécifier un ou plusieurs de ces styles :

CBS_AUTOHSCROLL : défile automatiquement le texte vers la droite dans le contrôle EDIT quand l'utilisateur tape un caractère à la fin de la ligne. Si ce style
n'est pas défini, l'utilisateur ne peut saisir plus de caractères que ceux qui tiennent dans le contrôle EDIT.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
CBS_DISABLENOSCROLL : dessine une barre de défilement vertical désactivée quand il n'y a pas assez d'éléments. Sans ce style, la barre verticale n'est pas
a ichée.

CBS_DROPDOWN : similaire à CBS_SIMPLE, sauf que la liste n'est pas a ichée tant que l'utilisateur ne clique pas sur le contrôle EDIT.

CBS_DROPDOWNLIST : similaire à CBS_DROPDOWN, sauf que le contrôle EDIT ne peut pas être modifié, et a iche le texte de l'élément sélectionné (ou rien si
aucun élément n'est sélectionné).

CBS_HASSTRINGS : spécifie une COMBOBOX dessinée par l'utilisateur, contenant des chaînes de caractères.

CBS_LOWERCASE : convertit en minuscules tous les textes.

CBS_NOINTEGRALHEIGHT : spécifie que la taille de la COMBOBOX soit exactement celle spécifiée par l'application, au lieu d'arrondir pour n'a icher que des
éléments entiers.

CBS_OEMCONVERT : convertit le texte entré dans le EDIT vers le set de caractères OEM, puis reconvertit vers le set de caractères Windows.

CBS_OWNERDRAWFIXED : spécifie une COMBOBOX dessinée par l'utilisateur : tous les éléments ont la même hauteur

CBS_OWNERDRAWVARIABLE : spécifie une COMBOBOX dessinée par l'utilisateur : tous les éléments n'ont pas la même hauteur.

CBS_SIMPLE : a iche une liste en permanence, et pas seulement quand l'utilisateur clique dessus. La sélection est a ichée dans le EDIT.

CBS_SORT : trie automatiquement les chaînes de caractères.

CBS_UPPERCASE : convertit automatiquement en majuscules les caractères.

Notifications
CBN_CLOSEUP
Cette notification est envoyée lorsque la liste déroulante a été fermée.

CBN_DBLCLK
Cette notification est envoyée lorsque l'utilisateur double-clique sur un élément de la liste.

CBN_DROPDOWN
Cette notification est envoyée lorsque la liste déroulante a été ouverte.

CBN_EDITCHANGE

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Cette notification est envoyée lorsque le texte (ou une portion de texte) de l'EDIT a été modifié (soit parce que l'utilisateur a sélectionné un élément, soit parce
qu'il a entré du texte).

Cette notification est envoyée après que le contrôle ait été redessiné.

CBN_EDITUPDATE
Cette notification est envoyée lorsque le texte (ou une portion de texte) de l'EDIT a été modifié (soit parce que l'utilisateur a sélectionné un élément, soit parce
qu'il a entré du texte).

Cette notification est envoyée avant que le contrôle ait été redessiné.

CBN_SELCHANGE
Cette notification est envoyée lorsque la sélection en cours de la liste a changé.

CBN_SELENDCANCEL
Cette notification est envoyée lorsque l'utilisateur clique sur un élément, puis clique sur un autre contrôle, annulant alors la sélection.

CBN_SELENDOK
Cette notification est envoyée lorsque l'utilisateur clique sur un élément, puis ferme la liste, acceptant alors la sélection.

Messages
Ces messages peuvent être envoyés au contrôle avec la fonction :

SendMessage(hCtl,iCode,wParam,lParam)

Pour chaque message, je décrirai le rôle et la signification de wParam et lParam et de la valeur retournée.

CB_ADDSTRING
Ajoute un élément à la liste (une chaîne de caractères).

wParam : 0.

lParam : pointeur vers la chaîne de caractères.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Valeur de retour : index de l'élément ajouté (relatif à 0).

CB_DELETESTRING
Supprime un élément de la liste (une chaîne de caractères).

wParam : index de l'élément (relatif à 0).

lParam : 0.

Valeur de retour : le nombre d'éléments restants dans la liste, ou CB_ERR en cas d'erreur.

CB_FINDSTRING
Ce message permet de rechercher un élément qui commence par une chaîne de caractères spécifiée.

wParam : spécifie l'index du précédent élément trouvé (relatif à 0), ou -1 pour commencer du début.

lParam : pointeur sur une chaîne de caractères qui contient les caractères à rechercher.

Valeur de retour : index (relatif à 0) de l'élément trouvé, ou CB_ERR si aucun.

CB_FINDSTRINGEXACT
Ce message permet de rechercher une chaîne de caractères qui correspond exactement à celle spécifiée.

wParam : spécifie l'index du précédent élément trouvé (relatif à 0), ou -1 pour commencer du début.

lParam : pointeur sur la chaîne de caractères à rechercher.

Valeur de retour : index (relatif à 0) de l'élément trouvé, ou CB_ERR si aucun.

CB_GETCOUNT
Ce message permet de connaître le nombre d'éléments qu'il y a dans la liste.

wParam : 0.

lParam : 0.

Valeur de retour : le nombre d'éléments, ou CB_ERR en cas d'erreur

CB_GETCURSEL
Ce message permet de connaître l'index de l'élément sélectionné.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
wParam : 0.

lParam : 0.

Valeur de retour : index de l'élément sélectionné (relatif à 0), ou CB_ERR si aucun.

CB_GETDROPPEDSTATE
Ce message permet de savoir si la liste est déroulée ou non.

wParam : 0.

lParam : 0.

Valeur de retour : TRUE si elle déroulée, et FALSE sinon.

CB_GETITEMDATA
Ce message permet de récupérer la valeur associée à un élément de la liste par le message CB_SETITEMDATA.

wParam : index de l'élément (relatif à 0).

lParam : 0.

Valeur de retour : valeur associée, ou CB_ERR en cas d'erreur.

CB_GETLBTEXT
Ce message permet de récupérer le texte d'un élément.

wParam : index de l'élément (relatif à 0).

lParam : pointeur vers la chaîne de caractères qui reçoit le texte.

Valeur de retour : longueur du texte (sans le caractère nul), ou CB_ERR en cas d'erreur.

Utilisez le message CB_GETLBTEXTLEN pour récupérer la longueur du texte, et ainsi éviter les débordements.

CB_GETLBTEXTLEN
Ce message permet de récupérer la longueur du texte d'un élément.

wParam : index de l'élément (relatif à 0).

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
lParam : 0.

Valeur de retour : longueur du texte (sans le caractère nul), ou CB_ERR en cas d'erreur.

CB_INSERTSTRING
Ce message permet d'insérer une chaîne de caractères dans la liste.

wParam : index de la position à laquelle insérer la chaîne, ou -1 pour l'ajouter à la fin de la liste.

lParam : pointeur vers la chaîne de caractères.

Valeur de retour : index de l'élément inséré, ou CB_ERR/CB_ERRSPACE en cas d'erreur.

CB_LIMITTEXT
Ce message permet de limiter le texte écrit par l'utilisateur dans le contrôle EDIT.

wParam : nombre maximum de caractères (caractère nul non compris).

lParam : 0.

Valeur de retour : TRUE

CB_RESETCONTENT
Ce message permet de supprimer tous les éléments de la liste.

wParam : 0.

lParam : 0.

Valeur de retour : CB_OKAY

CB_SETCURSEL
Ce message permet de définir l'élément sélectionné.

wParam : index de l'élément (relatif à 0), ou -1 pour n'en sélectionner aucun et e acer le contrôle EDIT.

lParam : 0.

Valeur de retour : index de l'élément sélectionné, ou CB_ERR en cas d'erreur.

CB_SETITEMDATA

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Ce message permet d'associer une valeur à un élément de la liste.

wParam : index de l'élément (relatif à 0).

lParam : valeur à associer.

Valeur de retour : CB_ERR en cas d'erreur.

CB_SHOWDROPDOWN
Ce message permet de montrer où cacher la liste.

wParam : TRUE pour a icher la liste, et FALSE pour la cacher.

lParam : 0.

Valeur de retour : TRUE

Exemple
Ceci est le code complet d'un exemple utilisant la combobox :

#include <windows.h>
#include <stdio.h>

HINSTANCE instance;

#define ID_COMBOBOX_1 110


#define ID_BUTTON_1 111
#define ID_BUTTON_2 112
#define ID_EDIT_1 113

HWND hComboBox1;
HWND hEdit1;

VOID RemplieFenetrePrincipale(HWND fenetrePrincipale)


{
hComboBox1=CreateWindow(
"COMBOBOX",

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
"",
WS_CHILD|WS_VISIBLE|CBS_DISABLENOSCROLL|CBS_DROPDOWNLIST,
10,10,
180,150,
fenetrePrincipale,
(HMENU)ID_COMBOBOX_1,
instance,
NULL);

hEdit1=CreateWindow(
"EDIT",
"Entrez le texte à ajouter",
WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|WS_BORDER,
10,40,
180,20,
fenetrePrincipale,
(HMENU)ID_EDIT_1,
instance,
NULL);

CreateWindow(
"BUTTON",
"Ajouter",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
10,70,
70,20,
fenetrePrincipale,
(HMENU)ID_BUTTON_1,
instance,
NULL);

CreateWindow(
"BUTTON",

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
"Supprimer",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
90,70,
70,20,
fenetrePrincipale,
(HMENU)ID_BUTTON_2,
instance,
NULL);
}

VOID NotificationControle(HWND fenetrePrincipale,UINT message,WPARAM wParam, LPARAM lParam)


{
UINT iId=LOWORD(wParam);
UINT iCode=HIWORD(wParam);
HWND hCtl=(HWND)lParam;

if(iId==ID_COMBOBOX_1)
{

}
else if(iId==ID_BUTTON_1)
{
CHAR lpText[256];
GetWindowText(hEdit1,lpText,256);

SendMessage(hComboBox1,CB_ADDSTRING,0,(LPARAM)lpText);
}
else if(iId==ID_BUTTON_2)
{
LRESULT lRes=SendMessage(hComboBox1,CB_GETCURSEL,0,0);
if(lRes==CB_ERR)
{
MessageBox(fenetrePrincipale,"Aucun élément sélectionné","Action annulée",MB_OK);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
return ;
}

SendMessage(hComboBox1,CB_DELETESTRING,(WPARAM)lRes,0);
}
}

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND boutons[2] = {NULL};

switch (message)
{
case WM_CREATE:
RemplieFenetrePrincipale(fenetrePrincipale);
return 0;
case WM_COMMAND:
NotificationControle(fenetrePrincipale,message,wParam,lParam);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(fenetrePrincipale,message,wParam,lParam);
}
}

int APIENTRY WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
HWND fenetrePrincipale;
MSG message;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
WNDCLASS classeFenetre;

instance = cetteInstance;

classeFenetre.style = CS_DBLCLKS;// pour attraper les double-clics


classeFenetre.lpfnWndProc = procedureFenetrePrincipale;
classeFenetre.cbClsExtra = 0;
classeFenetre.cbWndExtra = 0;
classeFenetre.hInstance = NULL;
classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);
classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
classeFenetre.lpszMenuName = NULL;
classeFenetre.lpszClassName = "classeF";

// On prévoit quand même le cas où ça échoue


if(!RegisterClass(&classeFenetre))
return FALSE;

fenetrePrincipale=CreateWindow(
"classeF",
"Ma premiere fenetre winAPI !",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
210,140,
NULL,
NULL,
cetteInstance,
NULL);

if (!fenetrePrincipale)
return FALSE;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
ShowWindow(fenetrePrincipale,modeDAffichage);
UpdateWindow(fenetrePrincipale);

while(GetMessage(&message,NULL,0,0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}

return message.wParam;
}

Rédacteur : pamaury

La liste de choix
Une list-Box (liste de choix en français) est un contrôle qui contient une liste d'items que l'utilisateur peut choisir comme dans un menu déroulant. On utilise ce
contrôle quand l'application doit présenter une liste de noms, des noms de fichiers par exemple, parmi lesquels l'utilisateur fait un choix. Il sélectionne une
chaîne en cliquant dessus. La sélection est en surbrillance, et une notification est envoyée à la fenêtre parent.

Création
Pour créer une list-box, il faut appeler CreateWindow en spécifiant "LISTBOX" dans la classe. Ou bien dans un fichier ressource, on écrira par exemple :

CONTROL "", ID_NOMDELALISTBOX, "LISTBOX", WS_CHILD | WS_VISIBLE, x, y, largeur, hauteur

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Vous pouvez aussi utiliser le mot-clé LISTBOX.

Néanmoins, cela ne su it pas, car comme vous vous en doutez, nous avons plusieurs possibilités pour créer notre contrôle. Ce qui va nous intéresser est donc
l'attribut de style. En plus de spécifier les styles habituels (WM_CHILD,WM_VISIBLE), vous pouvez spécifier un ou plusieurs de ces styles spécifiques qui
commencent tous par "LSB_":

LBS_COMBOBOX : notifie à la list-box qu'elle fait partie d'une combo-box (contrôle formé par la réunion d'une list-box et d'un contrôle d'édition). Ceci permet
la coordination entre les deux contrôles, de telle sorte qu'ils présentent une interface utilisateur unifiée (UI). La combo-box doit définir ce style. Si ce style est
spécifié par la list-box, une erreur en résultera.

LBS_DISABLENOSCROLL: a iche une barre verticale de défilement, désactivée quand la boîte ne contient pas assez d'items pour les faire défiler. Si vous ne
définissez pas ce style, la barre de défilement sera cachée quand la list-box ne contiendra pas assez d'éléments.

LBS_EXTENDEDSEL : permet la sélection de plusieurs items, en utilisant la touche SHIFT et la souris, ou une combinaison de touches particulières.

LBS_HASSTRINGS : spécifie que la list-box contient des items constitués de chaînes de caractères. La list-box conserve la mémoire et les adresses des chaînes
de caractères. Ainsi, l'application peut utiliser le message MB_GETTEXT pour rechercher le texte pour un item particulier. Par défaut, toutes les list-box ont ce
style, à l'exception des list-box qui se redessinent elles-mêmes. Vous pouvez créer une list-box qui se redessine soit avec ce style, soit sans ce style.

LBS_MULTICOLUMN : définit une list-box multi-colonnes qui défile horizontalement. Le message LB_SETCOLUMNWIDTH définit la largeur des colonnes.

LBS_MULTIPLESEL : une chaîne est sélectionnée à chaque clic. L'utilisateur peut sélectionner plusieurs chaînes.

LBS_NODATA : définissez ce style quand le nombre d'items dans la list-box dépasse une centaine. Une list-box no-data doit aussi avoir le style
LBS_OWNERDRAWFIXED, mais ne doit pas avoir le style LBS_SORT ou LBS_HASSTRINGS.
Cette list-box ressemble à une list-box qui se redessine, sauf qu'elle ne contient pas de donnée (data), de chaîne ou de bitmap pour un item. Les commandes
pour ajouter, insérer, ou supprimer un item ignorent toujours toute donnée spécifique de l'item ; une requête pour trouver une chaîne à l'intérieur de la list-
box échoue toujours. Le système envoie le message WM_DRAWITEM à la fenêtre propriétaire quand un item doit être dessiné. Le membre itemID de la
structure DRAWITEMSTRUCT passé avec le message WM_DRAWITEM définit le numéro de ligne de l'item à redessiner. Une list-boxno-data ne peut pas envoyer
un message WM_DELEITEM.

LBS_NOINTEGRALHEIGHT : définit si la taille de la list-box est exactement la taille spécifiée par l'application quand elle l'a créée. Normalement, le système
redimensionne la list-box pour qu'elle n'a iche pas d'item partiellement.

LBS_NOREDRAW : spécifie que l'apparence de la list-box n'est pas remise à jour après une modification. Pour changer le mode de mise à jour, utilisez le
message WM_SETREDRAW.

LBS_NOSEL : spécifie que la list-box contient des items qui peuvent être vus mais pas sélectionnés.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
LBS_NOTIFY : notifie la fenêtre parent à l'aide d'un message d'entrée chaque fois que l'utilisateur clique ou double-clique sur une chaîne dans la list-box.

LBS_OWNERDRAWFIXED : spécifie que le "propriétaire" de la list-box gère la réactualisation de son contenu et veille à ce que les items de la list-box
conservent la même hauteur. La fenêtre propriétaire reçoit le message WM_MEASUREITEM quand la list-box est créée, et le message WM_DRAWITEM quand
l'aspect visuel de la list-box a changé.

LBS_OWNERDRAWVARIABLE : spécifie que le propriétaire de la list-box est responsable de l'actualisation de son contenu, et que les items dans la list-box ont
une hauteur variable. La fenêtre propriétaire reçoit le message WM_MEASUREITEM pour chaque item dans une combo-box quand la combo-box est créée, et
WM_DRAWITEM quand l'aspect visuel de la combo-box change.

LBS_SORT : met les chaînes de la list-box dans l'ordre alphabétique.

LBS_STANDARD : met les chaînes de la list-box dans l'ordre alphabétique. La fenêtre parent reçoit un message d'entrée chaque fois que l'utilisateur clique ou
double clique sur une chaîne. La list-box a des bords sur tout son pourtour.

Les notifications
L'utilisateur envoie des requêtes d'édition en utilisant le clavier ou la souris. Le système envoie chaque requête à la fenêtre parent du contrôle dans le message
WM_COMMAND.
J'ai considéré que vous savez comment interagir avec ce message, et je décrirai donc ici uniquement les codes de notification.

LBN_DBLCLK
Notification envoyée par la list-box quand l'utilisateur double-clique sur une chaîne dans la list-box.

LBN_SELCANCEL
Une application envoie cette notification quand l'utilisateur annule la sélection dans une list-box.

LBN_SELCHANGE
Une application envoie cette notification quand la sélection dans une list-box vient de changer.

LBN_SETFOCUS
Une application envoie cette notification quand la list-box reçoit le focus clavier.
Parmi les notifications, il existe également des messages de types WM_, qui seront reçus par la procédure de la fenêtre parent.

WM_CTLCOLORLISTBOX
Ce message est envoyé à la fenêtre parent de la list-box avant que le système ne dessine la list-box. En répondant à ce message, la fenêtre parent peut définir les
couleurs du texte et du fond de la list-box en utilisant le dispositif de handle contextuels spécifique.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
La list-box sera coloriée avec la brosse retournée par ce message.

Les messages
Ces messages peuvent être envoyés au contrôle avec la fonction :

SendMessage(hCtl,iCode,wParam,lParam)

Pour chaque message, je décrirai le rôle et la signification de wParam, de lParam et de la valeur retournée.

LB_ADDFILE
L'application envoie ce message pour ajouter le nom de fichier spécifique à la list-box qui contient une liste de répertoires.

wparam : 0

lParam : pointeur sur un bu er qui définit le nom du fichier à ajouter.

Valeur retournée : index du fichier ajouté dont la série commence à 0, ou LB_ERR si une erreur survient.

La list-box à laquelle on va ajouter le paramètre lParam doit avoir été remplie à l'aide de la fonction DlgDirList.

LB_ADDSTRING
Une application envoie ce message pour ajouter une chaîne dans la list-box. Si la list-box n'a pas le style LBS_SORT, la chaîne est ajoutée à la fin de la liste.
Autrement, la chaîne est insérée dans la liste, et la liste est réorganisée.

wparam : 0

lParam : pointeur sur une chaîne terminée par un caractère nul qui sera ajouté.

Valeur retournée : index d'origine 0 de la chaîne dans la list-box signifie que le message a réussi. LB_ERR indique qu'une erreur est survenue. LB_ERRSPACE
indique qu'il n'y a pas assez de place pour stocker la nouvelle chaîne.

LB_DELETESTRING
Ce message est envoyé par l'application pour supprimer une chaîne dans la list-box.

wparam : index d'origine 0 de la chaîne dans la list-box.

lParam : 0

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Valeur retournée : le nombre de chaînes supprimées dans la liste signifie que l'opération a réussi. LB_ERR indique que l'index spécifié est un index supérieur
au nombre d'items de la liste.

LB_FINDSTRING
Ce message est envoyé par l'application pour trouver la première chaîne dans la list-Box contenant le préfixe précisé.

wparam : index, faisant partie d'une suite commençant par zéro, de l'item placé avant le premier item recherché. Quand la recherche atteint la fin de la liste,
elle se poursuit en revenant au début de la list-box jusqu'à l'item spécifié par le paramètre d'index de départ. Si l'index de départ est -1, la recherche va du
début à la fin de la list-box.

lParam : pointeur sur une chaîne à terminaison nulle qui contient le préfixe recherché. La recherche est indépendante de la case ; ainsi, cette chaîne peut
contenir n'importe quelle combinaison de lettres majuscules ou minuscules.

Valeur retournée : si c'est l'index de l'item associé, le message a réussi. LB_ERR indique que la recherche est infructueuse.

LB_FINDSTRINGEXACT
Ce message est envoyé par une application pour trouver la première chaîne associée à la chaîne précisée dans le paramètre lParam.

wparam : index (série d'origine 0) de l'item situé avant le premier item où commence la recherche. Quand la recherche atteint la fin de la liste, elle se poursuit
en revenant au début de la list-box jusqu'à l'item spécifié par le paramètre d'index de départ. Si l'index de départ est -1, la recherche va du début à la fin de la
list-box.

lParam : pointeur sur une chaîne à terminaison nulle contenant le nom complet du fichier recherché avec son extension. La recherche est indépendante de la
case ; ainsi, cette chaîne peut contenir n'importe quelle combinaison de lettres majuscules ou minuscules.

Valeur retournée : si c'est l'index de l'item associé, le message a réussi. LB_ERR indique que la recherche est infructueuse.

LB_GETCARETINDEX
Ce message est envoyé par une application pour déterminer l'index de l'item ayant le focus dans une list-box à sélection multiple. L'item peut ou ne peut pas être
sélectionné.

wparam : 0

lParam : 0

Valeur retournée : index de l'item de la list-box ayant le focus. Si la list-box est une list-box à sélection unique, la valeur est l'index de l'item sélectionné, s'il y
en a un.

LB_GETCOUNT

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Ce message est envoyé par l'application pour rechercher le nombre d'items qu'il y a dans une list-box.

wparam : 0

lParam : 0

Valeur retournée : nombre d'items dans la list-box si le message réussit. LB_ERR indique qu'une erreur s'est produite.

LB_GETCURSEL
Ce message est envoyé par une application pour recherche l'index de l'item sélectionné, s'il y en a un, dans une list-box à sélection unique.

wparam : 0

lParam :0

Valeur retournée : dans une list-box à une seule sélection, cette valeur est l'index de l'item sélectionné. S'il n'y a pas de sélection, la valeur retournée est
LB_ERR.

Vous ne devez pas envoyer ce message à une list-box à sélection multiple.

LB_GETITEMDATA
Ce message est envoyé par une application pour trouver la valeur 32 bit définie par l'application, et associée à l'item spécifié de la list-box.

wparam : index de l'item

lParam : 0

Valeur retournée : valeur 32 bits associée à l'item, ou LB-ERR si une erreur est survenue. Si l'item est dans une list-box avec une auto-remise à jour, et qui a été
créée sans le style LBS_HASSTRING, cette valeur 32 bits sera dans le paramètre lParam des messages LB_ADDSTRING ou LB_INSERTSTRING, qui ajoutent un
item à la list-box. Autrement, c'est la valeur de lParam du message LB_SETITEMDATA.

LB_GETITEMRECT
Ce message est envoyé par l'application pour rechercher les dimensions du rectangle qui limite un item de la list-box quand il est normalement a iché dans la list-
box.

wparam : index de l'item

lParam : pointeur sur une structure RECT qui reçoit les coordonnées clientes de l'item dans la list-box.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Valeur retournée : LB_ERR s'il y a une erreur.

LB_GETSELITEMS
Ce message est envoyé par une application pour remplir un bu er avec un tableau d'entiers (integer) qui définit les numéros des items dans la sélection d'items
d'une list-box à sélection multiple.

wparam : nombre maximum d'items sélectionnés dont les numéros seront placés dans le bu er.

lParam : pointeur sur le bu er assez grand pour contenir le nombre d'entiers défini dans le paramètre lParam.

Valeur retournée : nombre d'items placés dans le bu er. Si la list-box est à sélection unique, la valeur retournée est LB_ERR. Ce message retourne aussi
LB_ERR si vous passez des paramètres invalides à une list-box à sélection multiple.

LB_GETSELCOUNT
Ce message est envoyé par une application pour rechercher le nombre total d'items sélectionnés dans une list-box à sélection multiple.

wparam : 0

lParam : 0

Valeur retournée : nombre d'items sélectionnés dans la list-box si le message réussit. LB_ERR si la list-box est à sélection unique.

LB_GETTEXT
Ce message est envoyé par une application pour rechercher une chaîne dans une list-box.

wparam : index de la chaîne cherchée.

lParam : pointeur sur un bu er qui reçoit la chaîne. Le bu er doit avoir une taille su isante pour contenir la chaîne avec un caractère nul de terminaison. Un
message LB_GETTEXTLEN peut être envoyé après LB_GETTEXT pour rechercher la longueur, en caractères, de la chaîne.

Valeur retournée : longueur de la chaîne, en caractères sans le caractère nul de terminaison si le message réussit. LB_ERR indique que l'index n'est pas un
index valide.

LB_GETTEXTLEN
Une application envoie le message LB_GETTEXTLEN pour retrouver la longueur d'une chaîne dans la list-box.

wparam : index (origine 0) de la chaîne.

lParam : 0

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Valeur retournée : longueur de la chaîne, en CHAR, en excluant le caractère nul terminal. Sous certaines conditions, cette valeur peut être supérieure à la
longueur du texte.
Si wParam ne définit pas un index valide, cette valeur est LB_ERR.

Pour obtenir à tous les coups l'exacte longueur d'un texte, utilisez les messages WM_GETTEXT, LB_GETTEXT, ou CB_GETLBTEXT , ou la fonction
GetWindowText.

LB_INSERTSTRING
Une application envoie ce message pour insérer une chaîne dans une list-box. Di éremment du message LB_ADDSTING, ce message ne produit pas de liste que
l'on pourrait trier avec le style LBS_SORT.

wparam : définit l'index (d'origine 0) de la position où il faut insérer l'item. Si ce paramètre est 1, la chaîne sera ajoutée à la fin de la liste.

lParam : pointeur sur la chaîne à terminaison nulle que l'on veut insérer.

Valeur retournée : index de la position à laquelle la chaîne doit être insérée. Si une erreur survient, la valeur retournée est LB_ERR. S'il n'y a pas assez de place
pour stocker la nouvelle chaîne, la valeur retournée sera LB_ERRSPACE.

LB_RESETCONTENT
L'application envoie ce message pour supprimer tous les items d'une list-box.

wparam : 0

lParam : 0

Valeur retournée : ne retourne pas de valeur.

LB_SETCURSEL
Une application envoie ce message pour sélectionner une chaîne et la faire apparaître en la faisant défiler dans la zone visible, si nécessaire. Quand la nouvelle
chaîne est sélectionnée, la list-box supprime la surbrillance de la chaîne sélectionnée préalablement.

wparam : définit l'index (d'origine 0) de la chaîne sélectionnée. Si ce paramètre est -1, la list-box est définie comme n'ayant pas de sélection.

lParam : 0

Valeur retournée : si une erreur survient, la valeur est LB_ERR. Si wParam est -1, la valeur retournée est LB_ERR même s'il n'y a pas eu d'erreur.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
N'utilisez ce message qu'avec une list-box à sélection unique. Vous ne pouvez pas utiliser ce message pour définir ou annuler une sélection dans une list-
box à sélection multiple.

LB_SETHORIZONTALEXTENT
Une application envoie ce message pour définir la distance de déplacement horizontal (scrolling), en pixels, d'une list-box. Si la largeur de la list-box est inférieure
à cette valeur, la barre horizontale fait défiler les items horizontalement. Si la largeur de la list-box est égale ou supérieure à cette valeur, la barre horizontale de
défilement est cachée.

wparam : définit le nombre de pixels de déplacement de la list-box.

lParam : 0

Valeur retournée : pas de valeur retournée.

La list-box doit avoir le style WS_HSCROLL pour pouvoir utiliser ce message.

LB_SETITEMDATA
Une application envoie ce message pour définir une valeur associée à l'item spécifié d'une list-box.

wparam : définit l'index (d'origine 0) de l'item. Si cette valeur est -1, la valeur de lParam sera appliquée à tous les items de la list-box.

lParam : définit la valeur à associer à l'item.

Valeur retournée : si une erreur survient, LB_ERR.

LB_SETSEL
Une application envoie ce message pour sélectionner une chaîne dans une list-box à sélection multiple.

wparam : précise comment le sélection va être définie. Si ce paramètre est TRUE, la chaîne est sélectionnée et mise en surbrillance ; si ce paramètre est FALSE,
la surbrillance est annulée et la chaîne n'est pas sélectionnée.

lParam : définit l'index (d'origine 0) de la chaîne choisie. Si ce paramètre est 1, la sélection est ajoutée ou annulée de toutes les chaînes, en fonction du
paramètre wParam.

Valeur retournée : LB_ERR en cas d'erreur.

Exemple

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
#include <windows.h>
#include <stdio.h>

#define ID_BOUTON1 110


#define ID_BOUTON2 111

//variables globales
HINSTANCE inst;
HWND hListBox[2]; //handle des deux contrôles d'édition

//Afficher une list-Box et la remplir


HWND afficheListBox (HWND hwnd)
{
HWND hListBox=CreateWindow(
"LISTBOX","",
WS_VISIBLE|WS_CHILD|WS_BORDER |LBS_NOTIFY,
50,50,150,200,hwnd,NULL,inst,NULL);

//Entrer des items dans la list-box


SendMessage (hListBox, LB_ADDSTRING ,0,(LPARAM)"Première entrée");
SendMessage (hListBox, LB_ADDSTRING ,0,(LPARAM)"Deuxième entrée");
SendMessage (hListBox, LB_ADDSTRING ,0,(LPARAM)"Troisième entrée");
SendMessage (hListBox, LB_ADDSTRING ,0,(LPARAM)"Quatrième entrée");

return hListBox;
}

//Boutons pour la démo


HWND boutonMessage(HWND hwnd,HMENU code,long x, long y, char * texte)
{
HWND hBouton=CreateWindow(
"BUTTON",

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
texte,
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
x,y,
350,30,
hwnd,
code,
inst,
NULL);
return hBouton;
}

LRESULT CALLBACK Procedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

static HWND hBouton[1]={0};


char texte[5]={0},texte2[50]={0};
switch (message)

{
//afficher les contrôles d'édition à la réception du message WM_CREATE
case WM_CREATE:
hListBox[0]=afficheListBox (hwnd);
//afficher les boutons pour la démo
hBouton[0]= boutonMessage(hwnd, (HMENU)ID_BOUTON1,220,90,"Message LB_GETCURSEL: item sélectionné ");
return 0;

case WM_COMMAND:

switch (LOWORD(wParam))
{
//test du message LB_GETCURSEL
case ID_BOUTON1 :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
//Trouver le numéro de la ligne sélectionnée, et transformer le résultat en chaîne
sprintf(texte,"%d",(SendMessage(hListBox[0],LB_GETCURSEL,0,0)+1));
//Afficher une boîte de dialogue
//s'il y a une sélection
if (SendMessage(hListBox[0],LB_GETCURSEL,0,0)!= LB_ERR)
{
strncat(texte2,"Vous avez sélectionné la ligne ",50);
strncat(texte2,texte,50);
}
else //pas de sélection
{
strncat(texte2,"Vous n'avez sélectionné aucune ligne." ,50);
}
MessageBox(hwnd,(LPCTSTR )texte2,"",MB_OK|MB_ICONWARNING);
break;
//ajoutez d'autres tests et d'autres boutons si vous le voulez
//case ID_BOUTON2:
//autre test
//breaks;
}

switch (HIWORD(wParam))
{
case LBN_SELCHANGE :
char temp[256] = "";
SendMessage(hListbox, LB_GETTEXT, SendMessage(hListbox[0], LB_GETCURSEL, 0, 0), temp);
MessageBox(hwnd,temp, "Item sélectionné :", MB_ICONINFORMATION);
break;
}
return 0;

case WM_CLOSE:
DestroyWindow(hwnd);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}

int WINAPI WinMain(HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
//Variables de la fonction principale
MSG msg;
WNDCLASS wc;
HWND hwnd;
inst = cetteInstance;
// Structure de la classe de la fenêtre principale
wc.style = 0 ;
wc.lpfnWndProc = Procedure;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = cetteInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(1+ COLOR_BTNFACE);
wc.lpszMenuName = NULL;
wc.lpszClassName = "ClassePrincipale";

//Enregistrer la classe de fenêtre


if(!RegisterClass(&wc)) return FALSE;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
hwnd = CreateWindow("ClassePrincipale", "Démo du contrôle List-Box",WS_OVERLAPPEDWINDOW ,
200,100,600 ,300, NULL, NULL, cetteInstance, NULL);
if (!hwnd) return FALSE;
ShowWindow(hwnd,SW_SHOW);
UpdateWindow( hwnd );

//Boucle de message
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

Rédactrice : acryline

La glissière
Le slider, ou trackbar, (glissière en français) est très utilisé dans la plupart des programmes d'aujourd'hui. Vous l'avez sûrement utilisé sans même savoir ce qui se
passait derrière, chose que je propose de faire ici. :p

Il est loin d'être particulièrement di icile, et je ne vous cacherai pas que sa préparation est plus l'objet d'erreurs que son utilisation. En e et, il fait partie de la
Common Controls Library, ou bibliothèque des contrôles communs, que vous devrez intégrer et lier au projet.

Préparation préalable
Intégration
Afin de déclarer le slider, ou plutôt sa classe, vous aurez besoin d'insérer dans votre projet :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
#include <commctrl.h>

Linker
Et en ce qui concerne le linker, vous devrez ajouter l'entrée -lcomctl32, ou sous C::B comctl32.
En bref, rien de bien sorcier. La seule source d'erreurs est une potentielle faute d'orthographe. ;)

Création
Concernant sa création, vous pouvez passer comme d'habitude par CreateWindow, ou par les template de ressource. Le mot-clé à utiliser est alors CONTROL. Je
vous l'avais dit qu'il était générique... c'est le mot-clé se rapprochant le plus de CreateWindow. Mais dans les deux cas, le nom de classe à utiliser est
TRACKBAR_CLASS. En plus de spécifier cette constante prédéfinie au 2ème argument de CreateWindow (ou au 3ème de CONTROL), vous pouvez utiliser un ou
plusieurs, par associations de flag, des styles suivants :

TBS_AUTOTICKS : le slider comporte une marque (trait) pour chaque palier d'incrémentation déterminé à partir de ses marges.

TBS_BOTH : le slider comporte des marques sur ses deux côtés.

TBS_BOTTOM : le slider comporte des marques seulement en-dessous de lui.

Style valide uniquement avec un slider horizontal.

TBS_DOWNISLEFT : utilisé avec un slider vertical, il permet d'inverser le sens d'incrémentation.

TBS_FIXEDLENGTH : permet au curseur de changer sa taille en recevant le message TBS_SETTHUMBLENGTH.

TBS_HORZ : style par défaut ; le slider est orienté horizontalement.

TBS_LEFT : le slider comporte des marques sur son côté gauche.

Style valide uniquement quand son orientation est verticale.

TBS_NOTHUMB : le slider ne comporte pas de curseur.

TBS_NOTICKS : le slider ne comporte pas de marques.

TBS_REVERSED : le slider est inversé ; son sens d'incrémentation est alors de la droite vers la gauche.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Supporté uniquement par la version 5.80 ou ultérieure.

TBS_RIGHT : même e et que TBS_LEFT, mais sur le côté droit.

Style valide uniquement quand son orientation est verticale.

TBS_TOOLTIPS : le slider supporte les Tooltip, ou ballons d'informations. Sa position pourra alors être changée avec TBM_SETTIPSIDE.

Supporté uniquement par la version 4.70 ou ultérieure.

TBS_TOP : le slider comporte des marques au-dessus de lui.

Style valide uniquement quand son orientation est horizontale.

TBS_VERT : le slider est alors orienté verticalement.

Il est évident que vous ne devez pas combiner des styles contradictoires, comme des orientations contraires...

Sa création étant maintenant démystifiée, passons maintenant aux notifications que ce contrôle peut envoyer, et ensuite aux messages qu'il peut recevoir et
traiter.

Notifications
Je vais décrire ici les notifications envoyées par le contrôle via le message WM_COMMAND (sauf mention contraire). Il est assumé que vous savez comment
interagir avec ce message, et je décrirai donc ici uniquement les codes de notifications.

Les notifications WM_HSCROLL et WM_VSCROLL ne transitent pas par WM_COMMAND, elles sont traitées en tant que tel à part (comme on traite
WM_COMMAND).

Je vous précise au préalable que le slider envoie, à l'instar du contrôle static, une notification WM_CTLCOLORSTATIC pour colorer son pourtour. Vous
pourrez alors changer sa couleur de fond (cf "Le contrôle Static").

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
WM_HSCROLL ou WM_VSCROLL
Envoyés à la procédure de la fenêtre parent, ces notifications indiquent un drag du curseur par l'utilisateur :
- horizontal, pour un slider orienté horizontalement
- vertical, pour un slider orienté verticalement.

Le mot bas du paramètre wParam contient le code de notification.

TB_THUMBTRACK
Cette notification est envoyée lorsque l'utilisateur bouge le curseur.

Le mot haut du paramètre wParam contient la position changée du curseur.

TB_THUMBPOSITION
Cette notification est envoyée lorsque l'utilisateur a bougé le curseur, puis relâché la souris (équivaut donc à TB_THUMBTRACK + WM_LBUTTONUP).

Le mot haut du paramètre wParam contient la position changée du curseur.

Messages
Ces messages peuvent être envoyés au contrôle avec la fonction :

SendMessage(hCtl,iCode,wParam,lParam)

Pour chaque message je décrirai le rôle et la signification de wParam et lParam, ainsi que la valeur retournée.

TBM_CLEARSEL
Ce message permet de nettoyer la sélection en cours.

wParam : (BOOL) s'il vaut TRUE, redessine le slider.

lParam : 0.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Valeur de retour : aucune.

TBM_CLEARTICS
Ce message permet de supprimer les marques du slider, exceptées la première et la dernière.

wParam : (BOOL) s'il vaut TRUE, redessine le slider.

lParam : 0.

Valeur de retour : aucune.

TBM_GETCHANNELRECT
Ce message permet de récupérer les dimensions du rectangle limite du slider, dans lequel il évolue.

wParam : 0.

lParam : (LPRECT) adresse d'une variable de type RECT qui va recevoir les dimensions.

Valeur de retour : aucune.

TBM_GETPOS
Ce message permet de récupérer la position courante du curseur.

wParam : 0.

lParam : 0.

Valeur de retour : valeur 32 bits représentant la position courante.

TBM_GETRANGEMAX ou TBM_GETRANGEMIN
Ces messages permettent de récupérer la valeur maximale ou minimale que peut prendre le slider (ses bornes).

wParam : 0.

lParam : 0.

Valeur de retour : valeur 32 bits désignant la valeur de la borne spécifiée.

TBM_GETTHUMBLENGTH
Ce message permet de récupérer la longueur du curseur du slider.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
wParam : 0.

lParam : 0.

Valeur de retour : longueur du curseur (en pixels).

TBM_GETTHUMBRECT
Ce message permet de récupérer les coordonnées et dimensions du curseur.

wParam : 0.

lParam : 0.

Valeur de retour : (RECT) dimensions et positions du curseur.

TBM_GETTOOLTIPS
Ce message permet de récupérer un handle sur un ballon de message associé au slider s'il y a lieu.

wParam : 0.

lParam : 0.

Valeur de retour : (HWND) handle du tooltip assigné, s'il y en a un. Dans le cas contraire, NULL.

Le style TBS_TOOLTIPS est évidemment nécessaire ici.

TBM_SETPOS
Ce message permet de définir la position courante du curseur dans le slider.

wParam : (BOOL) définit l'état de dessin du contrôle : s'il vaut TRUE, le slider sera redessiné après.

lParam : (LONG) définit la nouvelle position du curseur, en unités logiques, comprise entre les bornes du slider.

Valeur de retour : aucune.

TBM_SETRANGE
Ce message permet de définir les bornes du slider.

wParam : (BOOL) définit l'état de dessin du contrôle : s'il vaut TRUE, le slider sera redessiné après.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
lParam : (LONG) nouvelles bornes, définies grâce à la macro MAKELONG(min, max)

Valeur de retour : aucune.

TBM_SETRANGEMAX ou TBM_SETRANGEMIN
Ces messages ont la même fonction que TBM_SETRANGE, mais sur une seule des bornes, spécifiée dans leur nom.

wParam : (BOOL) définit l'état de dessin du contrôle : s'il vaut TRUE, le slider sera redessiné après.

lParam : (LONG) définit la nouvelle borne (minimale ou maximale).

Valeur de retour : aucune.

TBM_SETTHUMLENGTH
Ce message permet de définir la longueur du curseur du slider.

wParam : (UINT) longueur du curseur, en pixels.

lParam : 0.

Valeur de retour : aucune.

TBM_SETTICFREQ
Ce message permet de définir la fréquence des marques.

wParam : (WORD) fréquence des marques (1 = chaque palier).

lParam : 0.

Valeur de retour : aucune.

TBM_SETTIPSIDE
Ce message permet de définir le côté du slider où sera a iché le ballon d'infos.

wParam : (int) définit le côté du ballon : peut alors prendre les valeurs TBTS_TOP (haut), TBTS_LEFT (gauche), TBTS_RIGHT (droite), TBTS_BOTTOM (bas).

lParam : 0.

Valeur de retour : précédente position du ballon.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Utile uniquement avec le style TBS_TOOLTIP.

TBM_SETTOOLTIPS
Ce message permet de définir le ballon d'informations associé au slider.

wParam : (HWND) handle d'un ballon déjà créé.

lParam : 0.

Valeur de retour : aucune.

Exemple
Le présent exemple montre quelques fonctions permettant de créer ou manipuler le slider simplement (à utiliser, non compilable tel quel) :

HWND createSlider (HINSTANCE instance, HWND parentWindow)


{
return CreateWindow(TRACKBAR_CLASS, "", WM_CHILD | WM_VISIBLE | TBS_NOTICKS, 20, 20, 300, 20, parentWindow, (HMENU)NULL, in
stance, NULL);
};

void setRange (HWND slider, int min, int max)


{
SendMessage(slider, TBM_SETRANGE, TRUE, MAKELONG(min,max));

return;
}

void setPos (HWND slider, int position)


{
SendMessage(slider, TBM_SETPOS, TRUE, position);

return;
}

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
int getPos (HWND slider)
{
return SendMessage(slider, TBM_GETPOS, 0, 0);
}

Celui-ci est tout bête, mais je ne pense pas que vous vous servirez des autres avant un petit bout de temps. ;)
Rédacteur : Mg++

Le contrôle Static
Ce contrôle est l'un des plus simples et des plus utiles qui soit : il permet d'a icher un libellé de texte, une icône ou une image, mais qui n'interagit pas avec
l'utilisateur, d'où son nom.

Création
Pour créer un STATIC, il faut appeler CreateWindow avec comme classe "STATIC", et ajouter en plus des styles classiques (WS_CHILD,WS_VISIBLE) un ou plusieurs
de ces styles :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Pour une boîte de dialogue, vous devrez utiliser le mot-clé CONTROL, très pratique, qui est un équivalent template de CreateWindow : son premier
paramètre équivaut au 2ème de CreateWindow, son 2ème correspond à son ID, son 3ème à la classe de fenêtre (autrement dit ici STATIC), et son
quatrième, ses styles. Les paramètres suivants désignent les dimensions habituelles. Exemple :

//Affiche un static contenant l'image <gras>img</gras> chargée en ressources (cf ci-après)


CONTROL "img", -1, "STATIC", SS_BITMAP, 10, 10, 0, 0

SS_BITMAP : spécifie une boîte rectangulaire qui permet d'a icher une image bitmap. La taille du contrôle est déterminée automatiquement en fonction de
celle de l'image.

SS_BLACKFRAME : spécifie une boîte rectangulaire avec un cadre de la même couleur que celui des fenêtres (noir par défaut).

SS_BLACKRECT : spécifie une boîte rectangulaire remplie avec la même couleur que le cadre des fenêtres (noir par défaut).

SS_CENTER : spécifie une boîte rectangulaire avec du texte centré. Si le texte est trop long, il est automatiquement réparti en plusieurs lignes.

SS_ETCHEDFRAME : dessine le cadre en utilisant l'attribut EDGE_ETCHED.

SS_ETCHEDHORZ : dessine les angles du haut et du bas en utilisant l'attribut EDGE_ETCHED.

SS_ETCHEDVERT : dessine les angles de gauche et droite en utilisant l'attribut EDGE_ETCHED.

SS_GRAYRECT : spécifie une boîte rectangulaire avec un cadre de la couleur en cours du fond d'écran (gris par défaut).

SS_GRAYFRAME : spécifie une boîte rectangulaire avec la couleur en cours du fond d'écran (gris par défaut).

SS_ICON : spécifie une boîte rectangulaire qui permet d'a icher une icône (ou un curseur animé). La taille du contrôle est déterminée automatiquement en
fonction de celle de l'icône.

SS_LEFT : spécifie une boîte rectangulaire avec du texte aligné à gauche. Si le texte est trop long, il est automatiquement réparti en plusieurs lignes.

SS_LEFTNOWORDWRAP : spécifie une boîte rectangulaire avec du texte aligné à gauche. Si le texte est trop long, il est automatiquement tronqué.

SS_NOPREFIX : prévient l'interprétation du signe & dans le texte comme un raccourci clavier.

SS_NOTIFY : envoie les notifications STN_CLICKED, STN_DBLCLK, STN_DISABLE et STN_ENABLE à la fenêtre parente.

SS_OWNERDRAW : le contrôle doit être dessiné par l'utilisateur.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
SS_REALSIZEIMAGE : utilisé avec SS_ICON. Au lieu de considérer la taille de la ressource comme taille du contrôle, la taille retournée par LoadImage est
utilisée.

SS_RIGHT : spécifie une boite rectangulaire avec du texte aligné à droite. Si le texte est trop long, il est automatiquement réparti en plusieurs lignes.

SS_RIGHTJUST : utilisé avec SS_ICON ou SS_BITMAP. Lors d'un redimensionnement du contrôle, au lieu de changer la position du coin en bas à droite, c'est
la position du coin en haut à gauche qui est modifiée.

SS_SIMPLE : spécifie une boîte rectangulaire avec du texte sur une seule ligne. Aucune modification n'est apportée au texte, même si celui-ci est trop long. Le
texte n'apparaît pas grisé si le contrôle est désactivé.

SS_SUNKEN : dessine un cadre créant l'e et d'un renfoncement dans la fenêtre, autour du contrôle.

SS_WHITEFRAME : spécifie une boîte rectangulaire avec un cadre de la même couleur que le fond de la fenêtre (blanc par défaut).

SS_WHITERECT : spécifie une boîte rectangulaire remplie avec la même couleur que le fond de la fenêtre.

Notifications
Je vais décrire ici les notifications envoyées par le contrôle via le message WM_COMMAND (sauf mention contraire) . Il est supposé que vous savez comment
interagir avec ce message, et je décrirai donc ici uniquement les codes de notifications.

STN_CLICKED
Ce message est envoyé lorsque l'utilisateur clique sur le contrôle.

Vous devez avoir défini le style SS_NOTIFY lors de la création du contrôle.

STN_DBLCLK
Ce message est envoyé lorsque l'utilisateur double-clique sur le contrôle.

Vous devez avoir défini le style SS_NOTIFY lors de la création du contrôle.

STN_DISABLE
Ce message est envoyé lorsque le contrôle est désactivé.

Vous devez avoir défini le style SS_NOTIFY lors de la création du contrôle.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
STN_ENABLE
Ce message est envoyé lorsque le contrôle est activé.

Vous devez avoir défini le style SS_NOTIFY lors de la création du contrôle.

WM_CTLCOLORSTATIC
Ce message est envoyé à la fenêtre parent juste avant que le contrôle ne soit dessiné.
Ceci est principalement utile pour changer la couleur du texte, ou du fond du contrôle pour le dessin .
Les paramètres valent alors:

wparam : handle du DC sur lequel dessiner.

lparam : handle du bouton

Valeur de retour : handle d'une brosse qui sera utilisée pour le dessin du fond.

- Ce message est envoyé directement à la fonction de gestion des messages, et non pas via le message WM_COMMAND
- La brosse retournée ne sera pas automatiquement détruite par le système.

Messages
Ces messages peuvent être envoyés au contrôle avec la fonction :

SendMessage(hCtl,iCode,wParam,lParam)

Pour chaque message, je décrirai le rôle et la signification de wParam, lParam et de la valeur retournée.

STM_GETICON
Ce message permet de récupérer le handle de l'icône associée au contrôle.

wParam : 0.

lParam : 0.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Valeur de retour : handle de l'icône associée, ou NULL si aucune.

STM_GETIMAGE
Ce message permet de récupérer le handle de l'image associée au contrôle.

wParam : spécifie le type de l'image à récupérer. Ce peut être une de ces valeurs :

IMAGE_BITMAP

IMAGE_CURSOR

IMAGE_ENHMETAFILE

IMAGE_ICON

lParam : 0.

Valeur de retour : handle de l'image associée, ou NULL si aucune.

STM_SETICON
Ce message permet de définir l'icône associée au contrôle.

wParam : handle de l'icône.

lParam : 0.

Valeur de retour : handle de l'icône précédemment associée, ou NULL si aucune.

STM_SETIMAGE
Ce message permet de définir l'image associée au contrôle.

wParam : spécifie le type de l'image à définir. Ce peut être une de ces valeurs :

IMAGE_BITMAP

IMAGE_CURSOR

IMAGE_ENHMETAFILE

IMAGE_ICON

lParam : handle de l'image.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Valeur de retour : handle de l'image précédemment associée, ou NULL si aucune.

Exemple
Ceci est le code complet d'un exemple utilisant les STATIC.

#include <windows.h>
#include <stdio.h>

HINSTANCE instance;

#define ID_STATIC_1 110

VOID RemplieFenetrePrincipale(HWND fenetrePrincipale)


{
HWND hCtl=CreateWindow(
"STATIC",
"Double-\ncliquez\nsur moi !!",
WS_CHILD|WS_VISIBLE|SS_CENTER|SS_NOTIFY,
10,10,
100,60,
fenetrePrincipale,
(HMENU)ID_STATIC_1,
instance,
NULL);

hCtl=CreateWindow(
"STATIC",
"",
WS_CHILD|WS_VISIBLE|SS_ICON,
10,80,
0,0,
fenetrePrincipale,
NULL,
instance,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
NULL);

HANDLE hIcon=LoadIcon(NULL,IDI_ERROR);
SendMessage(hCtl,STM_SETICON,(WPARAM)hIcon,0);

hCtl=CreateWindow(
"STATIC",
"",
WS_CHILD|WS_VISIBLE|SS_ICON,
120,10,
0,0,
fenetrePrincipale,
NULL,
instance,
NULL);

HANDLE hImage=LoadImage(NULL,MAKEINTRESOURCE(OCR_NORMAL),IMAGE_CURSOR,0,0,LR_SHARED);
SendMessage(hCtl,STM_SETIMAGE,(WPARAM)IMAGE_CURSOR,(LPARAM)hImage);

hCtl=CreateWindow(
"STATIC",
"",
WS_CHILD|WS_VISIBLE|SS_BITMAP,
120,60,
0,0,
fenetrePrincipale,
NULL,
instance,
NULL);
hImage=LoadImage(NULL,MAKEINTRESOURCE(OBM_CHECK),IMAGE_BITMAP,0,0,LR_SHARED);
SendMessage(hCtl,STM_SETIMAGE,(WPARAM)IMAGE_BITMAP,(LPARAM)hImage);
}

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
VOID NotificationControle(HWND fenetrePrincipale,UINT message,WPARAM wParam, LPARAM lParam)
{
UINT iId=LOWORD(wParam);
UINT iCode=HIWORD(wParam);
HWND hCtl=(HWND)lParam;

switch(iId)
{
case ID_STATIC_1:
if(iCode==STN_DBLCLK)
MessageBox(fenetrePrincipale,"Vous avez double-cliqué sur le premier STATIC","",MB_OK);
break;
}
}

LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND boutons[2] = {NULL};

switch (message)
{
case WM_CREATE:
RemplieFenetrePrincipale(fenetrePrincipale);
return 0;
case WM_COMMAND:
NotificationControle(fenetrePrincipale,message,wParam,lParam);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(fenetrePrincipale,message,wParam,lParam);
}

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
}

int APIENTRY WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance,


LPSTR lignesDeCommande, int modeDAffichage)
{
HWND fenetrePrincipale;
MSG message;
WNDCLASS classeFenetre;

instance = cetteInstance;

classeFenetre.style = CS_DBLCLKS;// pour attraper les double-clics


classeFenetre.lpfnWndProc = procedureFenetrePrincipale;
classeFenetre.cbClsExtra = 0;
classeFenetre.cbWndExtra = 0;
classeFenetre.hInstance = NULL;
classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);
classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
classeFenetre.lpszMenuName = NULL;
classeFenetre.lpszClassName = "classeF";

// On prévoit quand même le cas où ça échoue


if(!RegisterClass(&classeFenetre))
return FALSE;

fenetrePrincipale=CreateWindow(
"classeF",
"Ma premiere fenetre winAPI !",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
200,200,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
NULL,
NULL,
cetteInstance,
NULL);

if (!fenetrePrincipale)
return FALSE;

ShowWindow(fenetrePrincipale,modeDAffichage);
UpdateWindow(fenetrePrincipale);

while(GetMessage(&message,NULL,0,0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}

return message.wParam;
}

Rédacteur : pamaury
Ce sont les principaux contrôles. Les autres vous seront présentés dans un autre chapitre de ce cours. ;)

L'a ichage
Vous allez durant ce chapitre apprendre à gérer l'a ichage manuel d'informations dans votre fenêtre : celles ci peuvent être du texte, des formes
géométriques (dans ce cas ci on parlera de dessin) ou des images (en général des bitmaps).

Les contextes de périphériques

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
L'API windows permet de dessiner dans n'importe quel périphérique (imprimante, écran etc.) sans se préoccuper de son fonctionnement (le reste du travail est
e ectué grâce aux drivers des périphériques), ce qui, évidemment, est très pratique ;) .
Afin de pouvoir dessiner, nous devons obtenir un handle de contexte de périphérique, traduit en anglais par "Handle on Device Context", ou HDC.

Théorique
Un HDC peut être assimilé, pour une meilleure compréhension, à une surface potentiellement dessinable obtenue par l'appel de GetDC. Cette fonction, prenant
comme unique paramètre le handle de la fenêtre dont l'on veut récupérer le DC, retourne un HDC portant sur toute la surface de la fenêtre.
Toutes les fonctions de dessin ne nécessitent généralement qu'un contexte de périphérique. Vous vous demandez alors sûrement comment appliquer des
personnalisations temporaires pour chaque dessin ? Eh bien toutes ces personnalisations se passent sur le DC lui-même. La fonction de dessin, utilisant le DC
courant, sera lors a ectée par les modifications appliquées.
Une fois le DC récupéré, chaque personnalisation possible (changements de couleurs, de fontes...) se fait à l'aide d'une sélection. Cette sélection d'un objet
(personnalisation) dans un contexte de périphérique a pour e et de l'appliquer au DC. C'est alors qu'arrive SelectObject. Cette fonction, prenant comme
deuxième paramètre l'objet à sélectionner dans le HDC spécifié en premier paramètre, retourne l'ancien objet correspondant avant l'application. Ainsi, pour
qu'une couleur seule (par exemple, le vert) soit appliquée sur un HDC, on obtient :

brushDeCouleurAncienne = SelectObject(dcCourant, brushAppliquee);

//Où brushAppliquee = CreateSolidBrush(RGB(0,255,0));

Après utilisation, n'oubliez pas de libérer le DC avec ReleaseDC, qui prend comme unique paramètre le contexte de périphérique à libérer.

Avant de commencer les cas particuliers, un petit cours sur les couleurs (utilisées partout) s'impose :

Les couleurs
Les couleurs sont gérées di éremment de la logique actuelle. Je pense en particulier aux couleurs standards comme le RGB, ou Red Green Blue, avec la teneur de
chaque couleur primaire variant entre 0 et 255 : en winAPI, les couleurs et motifs sont gérées par Brosses, ou Brushes, et donc HBRUSH.

D'accord, mais comment passer d'une couleur RGB à une Brush ?

Eh bien, Microso pense à nous. ;) Nous avons donc à notre disposition CreateSolidBrush prenant comme seul paramètre la valeur hexadécimale de la couleur,
ou une variable COLORREF. Pour transformer la couleur RGB en valeur COLORREF afin de la passer en paramètre à CreateSolidBrush, nous pouvons utiliser la
macro RGB. Au final, la syntaxe à utiliser afin de récupérer une brush de couleur RGB est la suivante :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
const HBRUSH rouge = CreateSolidBrush(RGB(255,0,0));

Les valeurs de chaque couleur primaire se trouvent dans l'ordre des lettres de la macro.

Mais les brosses peuvent aussi être utilisées pour, par exemple, changer de motif. Pour cela, msdn nous propose plusieurs fonctions, parmi lesquelles (à titre
d'exemple) CreateHatchBrush, permettant de créer une brosse de motif de pointillés, traits ou autres par le passage du type de motif en premier paramètre, et de
sa couleur en deuxième.

Où l'intégrer ?
Tous les dessins peuvent être e ectués n'importe où dans le code en récupérant un DC. Seulement, dans le cas d'une superposition d'une autre fenêtre sur celle-
ci, tous les dessins se retrouvent e acés. Afin de le contrer, nous devons utiliser un message envoyé par le système quand la fenêtre a besoin d'être redessinée :
WM_PAINT.

:( Un scintillement désagréable subsiste...

Exact, la cause en est que les dessins sont alors entièrement redessinés, même s'ils sont toujours visibles. Pour y remédier, il est préférable d'utiliser la fonction
BeginPaint à la place de GetDC ; même si elle prend le même paramètre (avec en plus un deuxième : un pointeur sur une structure PAINTSTRUCT pour le
stockage... pas importante pour nous) et renvoie aussi un HDC, elle permet de ne redessiner que le strict nécessaire.

N'oubliez pas alors d'utiliser EndPaint, qui prend les mêmes paramètres que BeginPaint et permet d'arrêter le dessin. Elle a en plus le même e et que
ReleaseDC.

N'oubliez pas ce que vous venez d'apprendre afin de l'appliquer à ce qui suit.
Rédacteur : Mg++

Le texte
Avant de l'a icher, une personnalisation du texte peut être exécutée (police, couleur).

Personnalisation du texte

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Si vous ne savez pas encore ce que signifie le mot fonte, vous devez alors savoir qu'il s'agit d'un modèle d'écriture pour du texte. Pour vous faire une idée, "Times
New Roman", "Arial", "Arial Black", etc... sont des fontes (connues qui plus est).
Si vous n'avez toujours pas compris, des fontes sont des polices de caractères :D .

Afin de pouvoir en utiliser lors de fonctions d'a ichage de texte, nous devons récupérer un handle de fonte, ou HFONT. La récupération est semblable aux deux
précédentes fonctions, et peut être e ectuée grâce à CreateFont ou CreateFontIndirect. Comme CreateFont possède un prototype long et détaillé, je préfère
présenter l'autre, qui passe indirectement (d'où son nom) par une structure détaillant les spécificités de la police (souligné, gras, italique, police, taille etc...) :
LOGFONT.
Avant toute utilisation, certaines structures doivent être remises à zéro : ZeroMemory s'en occupe. Il faut lui passer pour son premier paramètre un pointeur de la
structure ciblée, et en deuxième sa taille, donnée par sizeof.
LOGFONT, faisant partie de ce type de structures, doit être initialisée à zéro.
Ensuite, vous pouvez :

Choisir la police à utiliser en copiant le nom de la police entre guillemets dans le champ lfFaceName de votre structure LOGFONT. Exemple :

LOGFONT strctLogfont;

ZeroMemory(&structLogfont, sizeof(LOGFONT));
strcpy(structLogfont, "Arial");

Régler la taille de la fonte en définissant le champ lfHeight de la structure (en pixels). Exemple :

structLogfont.lfHeight = 32;

Choisir de souligner ou barrer le texte en réglant les champs lfUnderline ou lfStrikeOut à TRUE. Exemple :

structLogfont.lfUnderline = TRUE

Régler la grosseur du texte en choisissant une valeur pour le champ lfWeight entre 0 et 900 (par pas de 100, il existe des constantes, comme FW_BOLD [gras] à
700). Exemple :

structLogfont.lfWeight = FW_BOLD;

Plus de précisions sur cette structure seront présentes dans la documentation ci-jointe.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Une fois la structure définie, vous n'avez plus qu'à passer l'adresse de votre structure au seul paramètre possible de CreateFontIndirect, qui s'occupe de vous
retourner le handle de fonte que vous devez récupérer. Exemple :

fonte = CreateFontIndirect(&structLogfont);

A ichage de texte
L'a ichage du texte à l'écran s'exerce grâce à :

BOOL TextOut (HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString);

Le premier paramètre désigne le DC courant, dans lequel va être dessiné le texte :

HDC hdc

Le deuxième désigne à quelle position d'abscisse le texte va commencer à être dessiné :

int nXStart

Le troisième a le même e et que précédemment, mais en ordonnée :

int nYStart

Le quatrième désigne la chaîne de caractères à a icher :

LPCTSTR lpString

Le dernier paramètre désigne le nombre de caractères à a icher (généralement le strlen de la chaîne, mais dans le cas où le nombre donné y est inférieur, la
chaîne a ichée sera tronquée) :

int cbString

Pour aller plus loin


Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Vous pouvez :

Rendre le fond du texte transparent en utilisant SetBkMode, prenant comme premier caractère le DC du texte, et en deuxième le mode de remplissage du
fond (donc ici TRANSPARENT).

Appliquer une couleur au texte avec SetTextColor, prenant comme premier paramètre le DC du texte, et comme deuxième sa couleur (sous la forme d'une
structure COLORREF).

Code d'exemple
En guise d'exemple, la fonction ci-dessous a iche la chaîne contenue dans chaine, avec les styles spécifiés en arguments, dans la fenêtre présente en argument
n°1 :

void dessineTexte (HWND fenetreCiblee, char *chaine, RECT dimensions, BOOL souligne, char *police, COLORREF couleur)
{
//Déclarations préalables
LOGFONT structFonte;
PAINTSTRUCT ps;
HFONT fonte;
HDC dc;

//Remplissage de la LOGFONT
ZeroMemory(&structFonte, sizeof(LOGFONT));
strcpy(structFonte.lfFaceName, police);
structFonte.lfHeight = dimensions.top-dimensions.bottom;
structFonte.lfWidth = 400;
structFonte.lfUnderline = souligne;

//Création de la fonte à partir de structFonte dans fonte


fonte = CreateFontIndirect(&structFonte);

//Récupération de la surface de dessin dans dc


dc = BeginPaint(fenetreCiblee, &ps);

//Permet au texte d'avoir un fond transparent


SetBkMode(dc, TRANSPARENT);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
//Applique la fonte au dc de texte
SelectObject(dc, fonte);
//Applique la couleur de texte au dc
SetTextColor(dc, couleur);

//Affichage du texte
TextOut(dc, dimensions.left, dimensions.top, chaine, strlen(chaine));

//Libération de la surface et du dc
EndPaint(fenetreCiblee, &ps);

return;
}

Vous avez sûrement noté la présence d'une structure RECT que vous ne connaissez pas.

Son champ le désigne l'abscisse du coin supérieur gauche de la surface spécifiée par le RECT.

Son champ top désigne son ordonnée.

Son champ right désigne l'abscisse du coin inférieur droit de la surface spécifiée par le RECT.

Son champ bottom désigne son ordonnée.

Grâce à de petits calculs, je peux alors déterminer la hauteur du texte à a icher. Vous pouvez en inventer un pour la largeur, je ne vous cache pas que j'en ai la
flegme :-° .
Rédacteur : Mg++

Les formes géométriques


Afin de créer des formes géométriques, vous avez besoin d'un crayon dans la vie réelle, non ? Eh bien en winAPI, c'est pareil.

Cours
Les crayons

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Bon ! Maintenant que vous avez compris le truc (et que vous avez quelques notions de dessin depuis la maternelle :p ), que vous savez donc que le dessin se fait
par outils facilement représentables visuellement, je vais vous parler des crayons. Comme vous le savez, un crayon peut être caractérisé par :

son motif (la manière dont vous vous en servez)

sa taille

sa couleur

Ça tombe bien, ce sont exactement les paramètres de CreatePen (et dans l'ordre en plus, quelle chance :-° ). Celle-ci renvoie un handle sur un crayon, ou HPEN.

Son motif est spécifié par l'envoi de constantes int au premier de ses paramètres (fnPenStyle), qui peuvent être PS_SOLID (pas de motifs), PS_DASH (tirets),
PS_DOTS (pointillés) et j'en passe...

Sa taille est spécifiée par le 2ème paramètre, Width (un int) en pixels.

Sa couleur est déterminée par le dernier paramètre, crColor, dont le type est encore un COLORREF. La macro RGB est alors encore de vigueur ici.

Les di érentes formes


Maintenant que vous avez de quoi dessiner, je vais vous fournir des fonctions de dessin permettant de reproduire, avec le DC courant, une forme géométrique :

pour faire un rectangle :

BOOL Rectangle(HDC hdc,int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

(où hdc désigne le dc courant dans lequel va être dessiné le rectangle, et où les 4 paramètres suivants ont la même désignation que dans la structure RECT (cf
fin "Le texte").

Pour faire une ellipse :

BOOL Ellipse(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

(Ses paramètres ont la même désignation que pour Rectangle.)

Pour faire une ligne, il faut faire une combinaison de :

BOOL MoveToEx(HDC hdc, int X, int Y, LPPOINT lpPoint);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Cela permet de déplacer le curseur virtuel dans le dc désigné par le premier paramètre aux coordonnées (X ; Y). Cette fonction écrit les anciennes
coordonnées du curseur virtuel dans lpPoint (un pointeur de type POINT est un structure toute bête ne possédant que deux champs : x et y).

Si NULL est passé à ce paramètre, la fonction ne renvoie pas l'ancienne position.

BOOL LineTo(HDC hdc, int nXEnd, int nYEnd);

Ce qui a pour rôle de tracer une ligne (a ectée par les objets potentiellement sélectionnés) entre le curseur virtuel et (nXEnd ; nYEnd).

D'autres fonctions de dessin seront peut être présentées : il s'agit des principales.

Codes d'exemples
Voici un ensemble de fonctions permettant de dessiner un rectangle, une ellipse ou une ligne, avec les options passées en paramètre :

Rectangle :

void dessineRectangle (HWND fenetreCiblee, const RECT dimensions, HPEN crayon, HBRUSH brosse)
{
//Déclarations préalables + demande de surface de dessin
PAINTSTRUCT ps;
HDC dc = BeginPaint(fenetreCiblee, &ps);

//Dessine le contour avec le crayon donné


SelectObject(dc, crayon);
//Peint le fond du rectangle avec la brosse donnée
SelectObject(dc, brosse);

//Dessine le rectangle aux positions données


Rectangle(dc, dimensions.left, dimensions.top, dimensions.right, dimensions.bottom);

//Libération de la surface et fin du dessin


EndPaint(fenetreCiblee, &ps);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
return;
}

Ellipse :

void dessineEllipse (HWND fenetreCiblee, const RECT dimensions, HPEN crayon, HBRUSH brosse)
{
//Déclarations préalables + demande de surface de dessin
PAINTSTRUCT ps;
HDC dc = BeginPaint(fenetreCiblee, &ps);

//Dessine le contour avec le crayon donné


SelectObject(dc, crayon);
//Peint le fond du rectangle avec la brosse donnée
SelectObject(dc, brosse);

//Dessine l'ellipse aux positions données


Ellipse(dc, dimensions.left, dimensions.top, dimensions.right, dimensions.bottom);

//Libération de la surface et fin du dessin


EndPaint(fenetreCiblee, &ps);

return;
}

Ligne :

void dessineLigne (HWND fenetreCiblee, const RECT dimensions, HPEN crayon)


{
//Déclarations préalables + récupération de la surface de dessin
PAINTSTRUCT ps;
HDC dc = BeginPaint(fenetreCiblee, &ps);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
//Application du crayon sur le dc
SelectObject(dc, crayon);

//Dessin de la ligne
MoveToEx(dc, dimensions.left, dimensions.top, NULL);
LineTo(dc, dimensions.right, dimensions.bottom);

//Libération de la surface + fin du dessin


EndPaint(fenetreCiblee, &ps);

return;
}

Rédacteur : Mg++

Les images
Les images a ichables en WinAPI sont généralement de type Bitmap. Pour les a icher, vous disposez de deux moyens : par ressources et en passant par un
contrôle STATIC, ou par les contextes de périphériques. Voici donc les méthodes disponibles :

A ichage par contrôle STATIC


Cette méthode est la plus simple à mettre en place, et permet de récupérer des notifications à l'égard du contrôle STATIC. Cependant, c'est la plus gourmande en
ressources, et n'est donc pas recommandée si vous n'avez aucune utilité des notifications.

Chargement du bitmap
Tout ce que vous avez à faire, c'est intégrer le bitmap en ressources en utilisant cette syntaxe :

img1 BITMAP "Images/bitmap.bmp"

Création du STATIC bitmap

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
La création de ce type de static s'e ectue simplement : contentez-vous de créer un static "normal", de mettre l'ID du bitmap entre guillemets en guise de nom de
fenêtre (2ème argument), et d'ajouter le style SS_BITMAP aux autres flag. Les dimensions (6ème et 7ème paramètres) peuvent être mises à 0 pour conserver la
taille originelle de l'image.

Si votre contrôle est situé dans un template, la procédure à suivre est la même.

A ichage par contextes de périphériques


C'est la méthode à suivre si vous préférez ne pas utiliser beaucoup les ressources système. Partez pour commencer d'un code simple comme celui-ci :

void afficheBitmap(HWND fenetreCiblee, char *chemin)


{
HBITMAP bitmap;
HDC hDC;

//Chargement du bitmap
hDC=GetDC(fenetreCiblee);

//Affichage du bitmap

DeleteObject(bitmap);
ReleaseDC(fenetreCiblee,hDC);
}

Si vous avez votre bitmap en ressource, rien de plus simple pour le chargement : LoadBitmap, prenant comme premier paramètre l'instance actuelle, et comme
deuxième, son ID entre guillemets, retourne un handle de bitmap directement manipulable. Dans le cas contraire, nous devons utiliser :

HANDLE LoadImage(
HINSTANCE hinst,
LPCTSTR lpszName,
UINT uType,
int cxDesired,
int cyDesired,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
UINT fuLoad
);

Dont les arguments sont :

l'instance actuelle.

Le chemin de l'image.

Le type de l'image. Ici IMAGE_BITMAP, mais peut-être aussi IMAGE_ICON ou IMAGE_CURSOR.

La largeur voulue de l'image. On utilise ici 0 pour tout prendre.

Idem, mais pour la hauteur.

Le mode de chargement. L'énumération de toutes ses valeurs possibles étant redondante, je vous précise juste que nous le mettrons à LR_LOADFROMFILE
pour le charger à partir du disque.

Donc, dans notre cas ce bout de code ressemblerait alors à ceci :

bitmap = (HBITMAP)LoadImage(NULL,"image.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

Ensuite, en ce qui concerne l'a ichage, vous disposez de deux méthodes possibles, mais la deuxième vous sera présentée plus tard dans une autre de ses
possibilités. Voici donc :

DrawState
Elle a comme prototype :

BOOL DrawState(HDC hdc, HBRUSH hbr, DRAWSTATEPROC lpOutputFunc, LPARAM lData, WPARAM wData, int x, int y, int cx, int cy, UINT
fuFlags);

Cette fonction permet d'a icher l'image avec certains e ets visuels (masques, etc.). Comme ce n'est pas ce que nous voulons faire ici, je passerai sur les
paramètres inutiles pour nous, il vous incombera de les mettre à NULL (avec si nécessaire, un cast).

hdc désigne le dc courant dans lequel va être a ichée l'image.

lData désigne le HBITMAP à a icher (un cast en long sera peut être nécessaire).

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Comme d'habitude, x et y déterminent la position du coin supérieur gauche de l'image, collée dans le dc courant, alors que cx et cy représentent ses
dimensions (donc mises à 0 pour conserver la taille originelle).

fuFlags désigne le type de l'image à a icher : DST_BITMAP, DST_ICON etc..

Alors, dans notre cas :

DrawState(dc,NULL,NULL,(long)bitmap,NULL,10,10,0,0,DST_BITMAP);

Code complet
Voici donc le code complet. Si vous avez votre image en ressources, inversez les commentaires et le code approprié :

case WM_PAINT :
{
HBITMAP bitmap;
HDC dc;
PAINTSTRUCT ps;

bitmap=LoadImage(NULL,"image.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

dc = BeginPaint(fenetrePrincipale, &ps);

DrawState(dc,NULL,NULL,(long)bitmap,NULL,10,10,0,0,DST_BITMAP);

EndPaint(fenetrePrincipale, &ps);

DeleteObject(bitmap);

return 0;
}

Vous pouvez en faire une fonction si vous vous sentez d'attaque ;) .

Un approfondissement de ce chapitre avec des techniques avancées vous permettant de faire plus de choses vous sera présenté plus tard dans le cours :) .

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Rédacteur : Mg++
Je pense que vous avez maintenant assez de bases pour .... oui, un TP ! :D

Euh ... :waw:

Pas de panique, si vous avez bien compris, rien ne sera di icile. Il s'agira probablement d'un lecteur audio sous Fmod ;)

TP : Un lecteur audio
Voici venu le temps du premier TP. :) Ne vous a olez pas, je vous réserve quelque chose d'assez simple, et toutes les étapes un tantinet plus coriaces vous
seront expliquées en guise de pistes.

Temps approximatif..........: 1h - 1h30


Di iculté...........................: Débutant

But
Votre mission, si vous l'acceptez, sera de créer un petit lecteur audio comprenant les fonctions suivantes :

A ichage des informations de la musique courrament jouée à l'écran, ainsi que les temps (écoulé/total).

Fonctions play / pause / stop.

Possibilité de parcourir le disque à la recherche d'une musique (pour le moment une seule, cela sera plus simple pour vous).

Présence d'un seeker, en fait un slider, permettant de rechercher un endroit particulier dans la musique (vous le connaissez forcément ;) ).

C'est pour l'instant tout ce que je vous propose, cela pour ne pas vous compliquer la vie en guise de premier TP WinAPI. Des propositions d'améliorations vous
seront données en fin de tuto, avec quelques éléments utiles pour leur conception.

Cependant si vous attendez, certaines améliorations en suspens trouveront leur solution dans la suite du cours.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Je vous propose l'organisation suivante, mais libre à vous de faire la vôtre. Ce sera votre lecteur après tout ^^ :

(N'ayez pas peur, je l'ai fait sous Paint :-° .)

Donc, avec cette organisation, le contrôle sur la musique se fera à partir du menu Music (qui possèdera donc les entrées-commandes Play / Pause, et Stop), et le
contrôle du player se fera à partir du menu File, qui contiendra donc les entrées-commandes Browse, et Quit.

Maintenant que vous connaissez assez de bases, je me permets de reprendre mon cher anglais. :p

Par conséquent, l'intérieur de la fenêtre ne comportera que les informations générales, et un contrôle de type slider permettant de "seeker" la musique.

Rédacteur : Mg++

Nécessaire
Afin de réaliser le TP, vous avez obligatoirement besoin d'un gestionnaire du son et de la musique. A cet e et, j'ai choisi FMOD, puisqu'il a déjà été étudié dans le
tuto de M@teo21.

Si jamais il y a des choses que vous ne comprenez pas (concernant FMOD), ou si vous voulez améliorer le TP, je vous conseille d'utiliser la documentation
de FSOUND.

De plus, une bonne connaissance du tuto vous sera nécessaire.

Pourquoi nous avoir appris tant de choses si seuls le slider et les menus sont utilisés, ainsi que l'a ichage du texte ?

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Ce TP est une occasion de vous entraîner. Ce que je vous propose est le strict minimum à son fonctionnement : si vous voulez l'améliorer (et ce sera sûrement le
cas, comme je l'espère ;) ), vous aurez besoin de toutes les connaissances acquises : listbox et dialogbox pour la playlist, boutons, textes et j'en passe...
Rédacteur : Mg++

Pistes
Vous aurez sûrement besoin de quelques pistes afin de le créer... je pense notamment au moyen de parcourir le disque dur à la recherche des musiques ;) . Je vais
donc vous les détailler ci-après, afin de vous aider le plus possible.
Voici donc les fameuses pistes (en vrac :-° ) .

Le timer
Afin de changer les informations à chaque seconde, (pour le temps, le slider etc...) vous devrez utiliser un timer. Ceux-ci sont un peu di érents de ceux de la SDL :
un timer, en WinAPI, envoie à la fenêtre parent de celui-ci une notification toutes les X millisecondes. Très pratiques, ils permettent d'exécuter un bloc
d'instructions à chaque intervalle de temps. De plus, ils n'ont pas particulièrement besoin de callback, et sont généralement utilisés sans. Vous devrez donc, à la
création de votre fenêtre, initialiser le timer qui, par défaut, n'est pas présent (logique), par un appel à la fonction SetTimer.

Son premier argument désigne le handle de la fenêtre parent du timer, qui va recevoir la notification régulière.

Son deuxième argument désigne son ID permettant de le distinguer des éventuels autres timer.

Son troisième argument désigne l'intervalle de temps, en millisecondes, entre chaque notification.

Son dernier argument désigne son éventuelle fonction callback associée, de type TIMERPROC (non nécessaire, et souvent mis à NULL).

Une fois le timer lancé, la fenêtre parent de celui-ci recevra la notification WM_TIMER à chaque intervalle de temps.
Pour arrêter le timer, utilisez KillTimer prenant comme premier argument le handle de la fenêtre parent, et en second l'ID du timer.

L'a ichage des textes


L'a ichage des textes en utilisant le dessin peut compliquer les choses inutilement. Je vous propose donc d'utiliser une méthode très pratique, qui consiste à
créer des contrôles static (avec les positions et dimensions nécessaires bien sûr) pour chaque zone d'information (nom de la musique, son état, et son temps),
avec un flag adapté à la zone (pour le temps : SS_RIGHT ; pour le nom : SS_CENTER ; pour le status : SS_LEFT). Et enfin, d'exécuter quand vous voulez changer leur
texte SetWindowText. Cette fonction, prenant comme premier paramètre le handle de la fenêtre (donc du static ici), et comme deuxième, le texte à a icher,
changera les textes des static en les justifiant à la position que vous avez spécifiée.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Si vous changez la couleur de fond de la fenêtre (vous savez, avec le champ hbrBackground), vous devrez changer le fond des static, et rendre le fond de
leurs textes transparents. Pour cela, à la réception de WM_CTLCOLORSTATIC, récupérez le HDC contenu dans le wParam, rendez le texte transparent avec
celui-ci, et enfin retournez une brosse (avec CreateSolidbrush) pour colorer le static.

La sélection de musique
En ce qui concerne la fonction Browse (ou parcourir), la manière la plus e icace reste la boîte de dialogue d'ouverture. Vous la connaissez, n'est-ce pas ? C'est ce
petit explorateur, vous permettant de sélectionner ce que vous voulez ouvrir :

Pour la faire apparaître, nous utiliserons la fonction GetOpenFileName. Cette dernière, qui prend comme seul paramètre une variable de type OPENFILENAME,
retourne TRUE si l'utilisateur a cliqué sur "Open", ou FALSE sur "Cancel". (En gros, vous ne traiterez que le TRUE.) La structure OPENFILENAME n'a pas le même
rôle que PAINTSTRUCT : vous devrez la remplir. Pour cela, je vais vous décrire les champs qui nous sont utiles.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Vous devez au préalable la mettre à zéro comme les autres structures remplies.

Le champ lStructSize doit récupérer la taille de la structure. (Utilisez donc un sizeof.)

Le champ hwndOwner récupère le handle de la fenêtre parent. (Donc celle du player.)

Le champ lpstrFile récupère une chaîne de caractères qui va recevoir le chemin de la musique sélectionnée par l'utilisateur, lorsque la fonction retourne.

Je vous conseille de donner la taille MAX_PATH à votre chaîne de caractères, puisque c'est la taille maximale d'un chemin de fichier.

Le champ nMaxFile récupère la taille maximale, en caractères, acceptée par la chaîne de caractères pointée par lpstrFile (en l'occurrence, MAX_PATH).

Le champ lpstrFilter est le plus dur à comprendre pour un débutant. Il s'agit des filtres utilisés : ce paramètre désigne les filtres possibles (description a ichée
à l'écran) avec leur extension filtrée. Pour cela, Microso a inventé un format de chaîne de caractères (appelé dans le jargon multistring), composée de
plusieurs parties (d'autres chaînes, en fait). Celles-ci sont séparées par des caractères NULL, \0. Les parties fonctionnent par paires : la première partie d'une
paire désigne le descriptif a iché à l'utilisateur (il aura le choix entre tous les descriptifs) ; la deuxième, la ou les extensions filtrées (sous la forme *.extension).
Dans le cas de plusieurs filtres, ils doivent être séparés par des points-virgules. Comme celui-ci est di icile à comprendre, je vous donne sa valeur :
truc.lpstrFilter = "Audio File\0*.mp3;*.wav;*.wma;*.ogg\0\0";

La dernière partie de string doit posséder deux caractères NULL consécutifs.

Le champ nFilterIndex doit toujours être à 1.

Le champ Flags désigne les flag à utiliser : ici, nous utiliserons OFN_PATHMUSTEXIST et OFN_FILEMUSTEXIST. Ceux-ci permettent de spécifier que le fichier
et son chemin doivent exister (pour éviter les bugs).

Une fois ceci fait, vous devrez passer l'adresse de la variable OPENFILENAME remplie à GetOpenFileName. L'appel de cette fonction su it à a icher la boîte de
dialogue, et à remplir le champ pointé par lpstrFile dès que le bouton "Ouvrir" est cliqué.

Le nom de la musique
Afin de trouver le nom de la musique, je vous propose une solution toute bête, en attendant la gestion des tags : utilisez strrchr sur le chemin de la musique avec
le caractère \ (doublé dans le code). Elle retournera alors la fin du chemin, ou la musique elle- même.

Le module de musiques

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
En ce qui concerne le module de son, fsound, vous aurez besoin de quelques fonctions pour coder votre lecteur. Voici les nécessaires :

FSOUND_Init : initialise le module fsound.

FSOUND_Close : ferme le module fsound.

FSOUND_Stream_Open : ouvre une musique.

FSOUND_Stream_Play : joue une musique.

Jusqu'ici, vous les connaissez toutes, du tuto de M@teo21. Mais les suivantes n'y sont pas expliquées, vous aurez donc besoin de vous rendre sur la
doc de fsound pour des informations les concernant.

FSOUND_GetPaused : informe de l'état de la pause.

FSOUND_SetPaused : change l'état de la pause.

FSOUND_Stream_Stop : stoppe la musique.

FSOUND_Stream_GetLengthMs : récupère le temps total de la musique.

FSOUND_Stream_SetTime : définit le temps écoulé / actuel de la musique.

FSOUND_Stream_GetTime : récupère le temps écoulé/actuel de la musique

Fin des pistes :p


Normalement, avec ces pistes et votre bagage intellectuel acquis durant ce tuto, vous pourriez y arriver sans aide.
Vous devez avoir vu au préalable parmi les contrôles : le static et le seeker. En outre, vous devez connaître toutes les bases, mais je suis sûr que vous les avez déjà.
;)
Allez, pour vous faire une idée du programme final :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Si vous n'y arrivez pas, n'hésitez pas à poster dans le forum du SDZ.

Et maintenant, à vous de jouer ! :pirate:


Bonne chance ! :)
Rédacteur : Mg++

Correction
J'espère que vous vous êtes bien débrouillés. ^^ Dans le cas contraire (ou pour voir comment un autre aurait fait, tout simplement), voici une archive contenant le
projet complet (.cbp et codes sources) pour vous faire les dents :magicien: :
Télécharger l'archive du projet !
Si jamais mon site est indisponible ou si le lien est rompu d'une quelconque manière, pour raison d'Etat par exemple, voici une recopie du code source :ninja: :

Resource.rc

/**************************************************
Nom du fichier : Resource.rc
Appartenance au projet : TP d'un lecteur audio pour le SDZ
Créateur : kidpaddle2

Rôle du fichier : Contient le template du menu


**********************************************/

#include <windows.h>

#include "Constants.h"

ID_MENU MENU
BEGIN
POPUP "File"
BEGIN

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
MENUITEM "Browse", ID_B_BROWSE
MENUITEM SEPARATOR
MENUITEM "Quit", ID_B_QUIT
END
POPUP "Music"
BEGIN
MENUITEM "Play/Pause", ID_B_PLAYPAUSE
MENUITEM "Stop", ID_B_STOP
END
END

Constants.h

/*************************************************************************
Nom du fichier : Constants.h
Appartenance au projet : TP d'un lecteur audio pour le SDZ
Créateur : kidpaddle2

Rôle du fichier : Définir les constantes nécessaires aux manipulations


de contrôles (principalement des ID)
**************************************************************************/

///Protection contre les inclusions multiples


#ifndef CONSTANTES_H
#define CONSTANTES_H

///Définition des constantes


#define ID_B_PLAYPAUSE 0
#define ID_B_STOP 1
#define ID_B_BROWSE 2
#define ID_B_QUIT 3

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
///Fin de la protection
#endif

Functions.h

/*************************************************************************
Nom du fichier : Functions.h
Appartenance au projet : TP d'un lecteur audio pour le SDZ
Créateur : kidpaddle2

Rôle du fichier : contient les prototypes des fonctions


**************************************************************************/

///Protection contre les inclusions multiples


#ifndef FUNCTIONS_H
#define FUNCTIONS_H

///Includes nécessaires
#include <windows.h>
#include <commctrl.h>
#include "Music.h"

///Prototypes des fonctions


void loadMusic(HWND, Music*);
void createStatics (HWND[], HWND, HINSTANCE);
void adaptSeeker (HWND, const Music);

///Fin de la protection
#endif

Functions.cpp

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
/*************************************************************************
Nom du fichier : Functions.cpp
Appartenance au projet : TP d'un lecteur audio pour le SDZ
Créateur : kidpaddle2

Rôle du fichier : définir les fonctions nécessaires au fonctionnement


du player
**************************************************************************/

///Includes
#include "Functions.h"

/** Fonction : loadMusic


Paramètre 1 : Fenêtre parent du contrôle
Paramètre 2 : adresse de l'objet "Music" pour charger la musique
Rôle : Charger la musique grâce à une boîte de dialogue d'ouverture,
inscrire le chemin et nom, et déterminer le temps total de la
musique**/
void loadMusic (HWND parentWindow, Music *musicToLoad)
{
//Structure nécessaire à la boîte de dialogue d'ouverture
OPENFILENAME toGetFileName;
//Variable qui va recevoir le chemin de la musique
char filePath[MAX_PATH] = "";

//Remplissage de la structure
ZeroMemory(&toGetFileName, sizeof(OPENFILENAME));
toGetFileName.lStructSize = sizeof(OPENFILENAME);
toGetFileName.hwndOwner = parentWindow;
toGetFileName.lpstrFile = filePath;
toGetFileName.nMaxFile = MAX_PATH;
//Avec un filtre de fichiers audio
toGetFileName.lpstrFilter = "Audio File\0*.mp3;*.wav;*.ogg;*.wma\0\0";

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
toGetFileName.nFilterIndex = 1;
toGetFileName.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

//Si l'utilisateur clique sur "Ouvrir"


if(GetOpenFileName(&toGetFileName) == TRUE)
{
//Copier le chemin récupéré dans le chemin de la musique
strcpy(musicToLoad->path, filePath);
//Inscrire le nom de la musique
strcpy(musicToLoad->name, strrchr(musicToLoad->path, '\\'));
//Si la musique est changée, on ferme la précédente
FSOUND_Stream_Close(musicToLoad->stream);
//Ouverture de la musique
musicToLoad->stream = FSOUND_Stream_Open(musicToLoad->path, 0, 0, 0);
//Récupération du temps total
musicToLoad->totalTime = FSOUND_Stream_GetLengthMs(musicToLoad->stream)/1000;
}

return;
}

/** Fonction : createStatics


Paramètre 1 : tableau de statics à créer
Paramètre 2 : fenêtre parent
Paramètre 3 : Instance actuelle
Rôle : Créer les statics montrant les infos sur la musique**/
void createStatics (HWND statics[], HWND parentWindow, HINSTANCE instance)
{
//Création du premier static (nom de la musique)
statics[0] = CreateWindow("STATIC",
"No musics loaded.",
WS_CHILD | WS_VISIBLE | SS_CENTER | SS_NOPREFIX,
10, 11, 370, 15,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
parentWindow,
(HMENU)NULL,
instance,
NULL);

//Création du deuxième static (status de la musique)


statics[1] = CreateWindow("STATIC",
"Currently idle.",
WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX,
10, 55, 100, 15,
parentWindow,
(HMENU)NULL,
instance,
NULL);

//Création du troisième static (temps de la musique)


statics[2] = CreateWindow("STATIC",
"",
WS_CHILD | WS_VISIBLE | SS_RIGHT | SS_NOPREFIX,
240, 55, 140, 15,
parentWindow,
(HMENU)NULL,
instance,
NULL);

return;
}

/** Fonction : adaptSeeker


Paramètre 1 : seeker
Paramètre 2 : objet musique chargé
Rôle : Adapter les marges du seeker en fonction du temps total de la
musique **/

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
void adaptSeeker (HWND seeker, const Music music)
{
//Définit la marge supérieure du seeker au temps total de la musique
SendMessage(seeker, TBM_SETRANGE, FALSE, MAKELONG(0,music.totalTime));

return;
}

Music.h

#ifndef MUSIC_H
#define MUSIC_H

#include <stdio.h>
#include <fmod/fmod.h>

typedef enum Status


{
playing = 0, paused = 1, stopped = 2, idle = 3
}Status;

typedef struct st1


{
int elapsedTime;
int totalTime;
char allTimes[20];

char name[256];
char path[MAX_PATH];

FSOUND_STREAM *stream;
}Music;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
#endif

main.cpp

/*************************************************************************
Nom du fichier : main.cpp
Appartenance au projet : TP d'un lecteur audio pour le SDZ
Créateur : kidpaddle2

Rôle du fichier : point d'entrée du programme et gestion des évènements


(callbacks)
**************************************************************************/

///Includes
#include <windows.h>
#include <fmod/fmod.h>

#include "Constants.h"
#include "Music.h"
#include "Functions.h"

///Instance actuelle (on en a besoin partout, donc on la déclare globale).


HINSTANCE instance;

///Prototype de la procédure callback du player


LRESULT CALLBACK playerProc(HWND, UINT, WPARAM, LPARAM);

///Winmain
int WinMain (HINSTANCE hThisInstance, HINSTANCE hPreviousInstance,
LPSTR lpCmdLine, int nFursterStill)
{
HWND player = NULL;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
MSG message;
WNDCLASS playerClass;

//Remplissage de l'instance globale avec l'instance actuelle


instance = hThisInstance;

//Définition de la classe de fenêtre


playerClass.style = 0;
playerClass.lpfnWndProc = playerProc;
playerClass.cbClsExtra = 0;
playerClass.cbWndExtra = 0;
playerClass.hInstance = instance;
playerClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
playerClass.hCursor = LoadCursor(NULL, IDC_ARROW);
//Remarquez la brosse employée pour peindre le fond de la fenêtre
playerClass.hbrBackground = CreateSolidBrush(RGB(0,0,0));
//Le menu est associé
playerClass.lpszMenuName = "ID_MENU";
playerClass.lpszClassName = "pClass";

if(!RegisterClass(&playerClass))
return FALSE;

//Création de la fenêtre du player


player = CreateWindow("pClass", "Basic Music Player", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 130,
NULL, NULL, hThisInstance, NULL);
if (!player) return FALSE;

//On l'affiche
ShowWindow(player, nFursterStill);
UpdateWindow(player);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
//Boucle évènementielle
while (GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}

///Procédure callback de la fenêtre du player


LRESULT CALLBACK playerProc(HWND playerWindow, UINT message, WPARAM wParam, LPARAM lParam)
{
/*Variables déclarées statiques pour qu'elles soient toujours valides
tout au long du programme*/
static Music music = {0};
//Handles des 3 statics (pour les infos) et du seeker
static HWND infos[3] = {NULL}, seeker = NULL;
//Status
static Status status = idle;

switch (message)
{
case WM_CREATE:
//Création de tous les contrôles
createStatics(infos, playerWindow, instance);

seeker = CreateWindow((LPCTSTR)TRACKBAR_CLASS,
(LPCTSTR)"",
(DWORD)WS_CHILD|WS_VISIBLE | TBS_NOTICKS,
10, 30, 370, 20,
playerWindow,
(HMENU)NULL,
instance,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
NULL);

//Initialisation de fsound
FSOUND_Init(44100, 32, 0);

//Lancement du timer nécessaire


SetTimer(playerWindow, 0, 1000, (TIMERPROC)NULL);
return 0;

case WM_COMMAND:
switch(LOWORD(wParam))
{
/*Si la commande "Quit" du menu est cliquée, on envoie WM_DESTROY à la fenêtre*/
case ID_B_QUIT:
SendMessage(playerWindow, WM_DESTROY, 0, 0);
break;

/*Si la commande "Browse" du menu est cliquée, on s'occupe de charger la musique*/


case ID_B_BROWSE:
//Donc on charge la musique (voir Functions.cpp)
loadMusic(playerWindow, &music);
/*On adapte les marges du seeker en conséquence (du temps total)*/
adaptSeeker(seeker, music);
//On met à jour le nom de la musique
SetWindowText(infos[0], music.name);
break;

//Si la commande "Play / Pause" du menu est cliquée et :...


case ID_B_PLAYPAUSE:
/*...si aucune musique n'est jouée, et que la pause n'est pas enclenchée*/
if(!FSOUND_IsPlaying(0) && !FSOUND_GetPaused(0))
//Alors on joue la musique chargée
FSOUND_Stream_Play(0, music.stream);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
//...sinon si la pause est enclenchée
else if(FSOUND_GetPaused(0))
//On l'enlève
FSOUND_SetPaused(0, FALSE);
//...sinon si on est en pleine lecture
else if(FSOUND_IsPlaying(0))
//Alors on enclenche la pause
FSOUND_SetPaused(0, TRUE);
//...sinon on fait rien.
else
break;
break;

//Si la commande "Stop" du menu est cliquée...


case ID_B_STOP:
//...on stoppe la musique chargée
FSOUND_Stream_Stop(music.stream);
break;
}
return 0;

//Si le seeker est bougé...


case WM_HSCROLL:
//On trouve la position changée du seeker...
music.elapsedTime = SendMessage(seeker, TBM_GETPOS, 0, 0);
//... et on applique à la musique le temps demandé
FSOUND_Stream_SetTime(music.stream, music.elapsedTime*1000);
break;

//A chaque signal de timer...


case WM_TIMER:
//Et si la musique est jouée
if(FSOUND_IsPlaying(0))

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
{
/*Et si la pause est enclenchée, on rafraîchît le status en conséquence*/
if(FSOUND_GetPaused(0))
{
/* Seulement si ça ne l'est pas déjà */
if(status != paused)
{
SetWindowText(infos[1], "Paused.");

//Le status est changé


status = paused;
}
}
//Si la pause ne l'est pas
else
{
//On rafraîchit aussi le status en conséquence
/* Seulement si ça ne l'est pas déjà */
if(status != playing)
{
SetWindowText(infos[1], "Playing...");

//Le status est changé


status = playing;
}

//On récupère le temps actuel de la musique


music.elapsedTime = FSOUND_Stream_GetTime(music.stream)/1000;

/*On fabrique une chaine de caractères montrant l'avancée du temps*/


sprintf(music.allTimes,
"%d\' %d\" / %d\' %d\"",
music.elapsedTime/60,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
music.elapsedTime%60,
music.totalTime/60,
music.totalTime%60);

//... et on l'affiche dans l'emplacement prévu


SetWindowText(infos[2], music.allTimes);
//Et enfin on met à jour le seeker
SendMessage(seeker, TBM_SETPOS, TRUE, music.elapsedTime);
}
}
//Si la musique n'est pas en train d'être jouée
else
{
/*On rafraîchit le status et l'avancée du temps en conséquence*/
/* Seulement si ça ne l'est pas déjà */
if((status != stopped) && (status != idle))
{
SetWindowText(infos[1], "Stopped.");
SetWindowText(infos[2], "");

//Et on met à zéro le seeker


SendMessage(seeker,TBM_SETPOS, TRUE, 0);

//Le status change


status = stopped;
}
}
return 0;

//Si le sontrôle demande à être recoloré...


case WM_CTLCOLORSTATIC:
{
//On récupère un DC dessus...

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
HDC textDC = (HDC)wParam;
SetTextColor(textDC, RGB(0,255,0));
//Qui permet de nous donner la main sur le texte à rendre transparent
SetBkMode(textDC, TRANSPARENT);

static HBRUSH brush = CreateSolidBrush(RGB(0,0,0)); /* Il vaut mieux la mettre en static pour éviter des bugs gr
aphiques au chargement */

/*Et finalement on retourne une brosse pour colorer son fond. (la même que la fenêtre principale)*/
return (LRESULT)brush;
}

//Si on demande à quitter


case WM_DESTROY:
//On ferme fsound
FSOUND_Close();
//et on quitte...fini.
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(playerWindow, message, wParam, lParam);
}
}

Rédacteur : Mg++

Améliorations
Ce lecteur est un bon début, mais il n'est pas parfait (nooon sans blague ? :p ). Je vous propose ici quelques idées d'améliorations avec, si besoin est, quelques
astuces pour les concrétiser.

Sélection multiple
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Vous pourriez permettre au lecteur de récupérer plusieurs musiques au lieu d'une dans la boîte de dialogue d'ouverture. Comme vous avez pu le voir, elle ne le
permet pas. Pour cela, ajoutez à la liste de flags OFN_MULTISELECT, qui permettra de faire une sélection multiple. Mais... je ne vous en ai pas parlé car c'est un
peu plus dur que pour la sélection unique. ;) En e et, vous ne disposez que d'une chaîne de sortie (lpszFile). Pas de panique, Microso est là. Dans le cas d'une
sélection multiple, la chaîne se transforme alors en une multistring, dont je vous ai parlé plus haut. Le chemin du dossier où se trouvent les musiques, ainsi que
chaque nom de musique sélectionnée qu'il précède, sont alors séparés par un caractère NULL, et le dernier caractère est doublé. Il va donc falloir que vous
inventiez une fonction (je ne vais pas la donner, sinon ce n'est pas drôle :lol: ) permettant de découper la chaîne en un tableau de string, que vous stockerez alors.
Voici alors son format, en guise de coup de pouce ^^ :

"C:\\Dossier1\\Dossier2\\Musique1.mp3\0Musique2.wav\0Musique3.ogg\0\0"

Gestion de plusieurs musiques


Après l'avoir intégré, un système de progression entre les musiques serait intéressant : l'ajout de 'Next', 'Previous' serait alors adapté, et un choix entre lecture
normale ou aléatoire pourrait être ajouté.

Ajout d'une playlist


Une playlist pourrait alors être ajoutée, pour représenter visuellement les musiques chargées. Un double-clic sur une entrée de celle-ci lançerait alors la musique.

Fonctions habituelles
Après, pourraient être insérées les fonctions normales, tel que réglage du volume, etc.

Possibilités autres
D'autres possibilités seront vues plus en détail lors de la progression du cours, comme un skin élaboré dans une fenêtre non rectangulaire en utilisant les régions,
la possibilité de minimiser l'application, etc.
Déjà, si vous intégrez toutes ces idées, cela prouvera que vous vous débrouillez bien avec le winAPI. Quoiqu'il arrive, gardez une organisation propre, et les ajouts
se feront sans problème. :ange:
Rédacteur : Mg++
Et voilà, ce premier TP est fini :) Je vous retrouve après dans la suite du cours, et j'espère que ce TP vous a fait du bien. ;)
Rédacteur : kidpaddle2

Les événements

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Vous avez jusqu'ici exclusivement travaillé avec des contrôles pour intéragir avec la fenêtre. Je vous propose ici de traiter manuellement les principaux
événements du clavier et de la souris.

Ces événements sont captés sous forme de messages (notifications) par la fenêtre concernée, si elle a le focus.

Evénements "clavier"
Il y a trois événements vraiment utilisés :

WM_KEYDOWN

WM_CHAR

WM_KEYUP

Chacun de ces messages survient l'un après l'autre (dans l'ordre), à chaque fois qu'une touche est utilisée.

Si la touche enfoncée n'est pas un caractère, WM_CHAR n'est pas envoyé.

Voici un schéma résumant le tout :

Schéma des messages générés tout au long de l'utilisation d'une touche


Comme vous pouvez le voir, WM_KEYDOWN survient lors de l'enfoncement d'une touche, WM_CHAR si cette touche désigne un caractère, et WM_KEYUP lors du
relâchement de la touche.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Tous ces messages prennent comme paramètre :

WPARAM : code virtuel de la touche

LPARAM : informations de répétition, d'état de touche système etc.

Le paramètre LPARAM n'est souvent pas utilisé. Par contre, le premier permet de déterminer la touche qui a généré l'événement, à travers une correspondance
code/touche, dont le tableau est disponible à l'adresse suivante (je n'ai pas eu le courage de tout retranscrire dans un tableau zCode, mais si une âme charitable
pouvait le faire, je lui en serait reconnaissant ^^ ).

Pour les caractères (A->Z :p ), leur code virtuel n'est autre que leur valeur. Par exemple, le code virtuel de la touche a n'est autre que 'a' (ou 97 en ASCII), ou
'A' (ou 65 en ASCII), si la touche est majuscule. Naturellement, vous connaissez tout ça ;)

Il n'y a pas grand-chose à dire d'autre, donc un code complet devrait su ire à vous mettre en tête leur utilisation.

Les codeurs C++ pourraient alors avoir l'occasion d'utiliser le conteneur standard "map" pour la correspondance entre le nom de la touche, et son code
virtuel.

Pour ceux que ça intéresse, vous pouvez récupérer l'état actuel d'une touche du clavier en utilisant GetKeyState(), prenant comme paramètre le code
virtuel de la touche visée (attention, pour les caractères le paramètre passé doit être leur valeur ASCII). Son retour est (j'ai simplifié) inférieur à 0 si la
touche est enfoncée.

Exemple
Voici donc un exemple de traitement des trois messages (non compilable), qui permet simplement de quitter le programme à l'appui de la touche "Echap", et
d'ajouter à une string les éventuels caractères entrés.

//Soit wParam et lParam les WPARAM et LPARAM (normal ^^ )


//Soit buffer une instance de std::string

/* switch du MSG dans la callback de la fenêtre */


case WM_KEYDOWN:
//ou WM_KEYUP
switch(wParam)
{

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
case VK_ESCAPE:
PostQuitMessage(0);
break;

default:
break;
}
return 0;

case WM_CHAR:
buffer += (char)wParam;
return 0;

C'est tout bête, n'est-ce pas ?


Rédacteur : Mg++

Evénements "souris"
Les boutons
La souris génère deux messages consécutifs à l'appui d'un de ses bouton, chacun décliné en trois messages, selon le bouton concerné. La nomenclature de tels
message est alors WM_BOUTONMESSAGE où :

BOUTON est l'identifiant du bouton ayant généré le message pouvant être :

L (bouton gauche)

R (bouton droit)

M (bouton du milieu)

MESSAGE le type d'événement, pouvant être :

BUTTONDOWN

BUTTONUP

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
On retrouve ici les su ixes -DOWN et -UP, montrant que durant l'utilisation d'un bouton, WM_(L, R ou M)BUTTONDOWN est envoyé quand il est enfoncé, et WM_(L,
R ou M)BUTTONUP quand il est relâché.
Ces messages ont tous les mêmes paramètres WPARAM et LPARAM : le paramètre WPARAM contient un masque de bouton, c'est-à-dire le code virtuel de
touches/boutons étant enfoncés lorsque l'événement survient (équivalent à la traduction d'appuis simultanés), dont les valeurs peuvent être :

MK_CONTROL : la touche Ctrl est enfoncée

MK_LBUTTON : le bouton gauche est enfoncé

MK_RBUTTON : Le bouton droit est enfoncé

MK_SHIFT : la touche SHIFT est enfoncée

Ces flags pouvant être combinés, vous pouvez retrouver la présence de l'un ou l'autre en utilisant l'opérateur &. Pour plus d'informations, reportez-vous au
tutorial sur les flags.

Par ailleurs, le paramètre LPARAM contient les coordonnées du curseur lors de l'émission du message : le LOWORD contient son abscisse, et le HIWORD son
ordonnée. Ces coordonnées peuvent êtres récupérées à l'aide des macros GET_X_LPARAM(LPARAM) (pour l'abscisse) et GET_Y_LPARAM(LPARAM) (pour
l'ordonnée), ou encore MAKEPOINTS(LPARAM) (pour récupérer une structure POINTS).

Un autre message similaire (de même nomenclature et paramètres) existe, envoyé lors d'un double clic de la souris : WM_(L, R ou M)DBLCLK. Attention,
pour pouvoir le recevoir votre fenêtre doit comporter le style CS_DBLCLKS.

La molette
L'événement WM_MOUSEWHEEL, généré lors de l'utilisation de la molette, possède les mêmes paramètres, excepté le fait que le masque de bouton expliqué plus
haut est contenu par le HIWORD du WPARAM.

Pourquoi ?

J'y viens :p : le LOWORD est en fait utilisé par l'angle parcouru par la molette, défini à partir de la constante WHEEL_DELTA (valant 120, et correspondant en
général à un "cran" de la molette). Si ce paramètre est positif, c'est que la molette a été tournée vers le "haut", ou à l'opposé de l'utilisateur. A l'inverse, une valeur
négative traduit un mouvement vers le "bas", ou vers l'utilisateur.

Le déplacement

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Nous avons vu jusqu'ici les événements des boutons, et de la molette de la souris. Mais qu'en est-il de son mouvement ?
Quand la souris est déplacée, le message WM_MOUSEMOVE est envoyée à la fenêtre située sous le curseur. Celui-ci (chance ! :p ) possède exactement les mêmes
paramètres que les messages correspondant à l'utilisation des boutons de la souris, à savoir les boutons pressés simultanément, et les coordonnées du curseur.

Cet événement survenant à des intervalles très rapprochés, je ne vous conseille pas de le traiter avec de lourdes opérations, ou votre processeur en
sou rira ;)

Divers
Vous pouvez récupérer la position de la souris à n'importe quel endroit de votre code, avec la fonction GetCursorPos(), prenant comme paramètre un pointeur de
POINT. Vous l'aurez deviné, la fonction SetCursorPos() permettrait de définir la position du curseur, en prenant un POINT en paramètre.

Exemple
Voici un code récapitulatif tout simple, déduisant simplement la distance parcourue par le curseur (quand le bouton gauche de la souris est enfoncé), et par la
molette (non compilable, comme d'habitude ;) ).

#include <math.h>

#define RADIUS (2*PI)

double linearDistance(POINT start, POINT end)


{
return sqrt(pow((end.x - start.x), 2) + pow((end.y - start.y), 2))
}

int DEG_TO_RAD(int deg)


{
return (deg*PI)/180
}

double angularDistance(int angle)


{
return abs(angle)*RADIUS;
}

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
/* Soit cursorDistance et wheelDistance des static double, représentant respectivement
la distance parcourue par le curseur et la molette (en pixels), ainsi que
BOOL lBtnDown l'état du bouton gauche de la souris. (TRUE pour
enfoncé, FALSE pour relâché) (FALSE par défaut) */

//WindowProc, switch MSG (avec LPARAM lParam et WPARAM wParam)

case WM_LBUTTONDOWN:
lBtnDown = TRUE;
return 0;

case WM_LBUTTONUP:
lBtnDown = FALSE;
return 0;

case WM_MOUSEMOVE:
{
if(lBtnDown)
{
static POINT old = {0,0};
POINT current;
current.x = GET_X_LPARAM(lParam);
current.y = GET_Y_LPARAM(lParam);

cursorDistance += linearDistance(old, current);

old = current;
}

return 0;
}

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
case WM_MOUSEWHEEL:
wheelDistance += angularDistance(DEG_TO_RAD(LOWORD(lParam)));
return 0;

DEG_TO_RAD devrait être précisé inline en C++, je n'aime pas utiliser des macros...

Rédacteur : Mg++
Ce fut une courte introduction aux événements principaux du clavier et de la souris. Un prochain chapitre sera dédié en partie aux événements système, comme
le Drag And Drop.

Si vous comptez envoyer ces messages à une fenêtre, préférez PostMessage() à SendMessage(), puisqu'en général on n'attend pas de réponse de la part de
la fenêtre visée (elle possède les mêmes paramètres que cette dernière).

Certains des messages necessitent des LPARAM/WPARAM contenant un LOWORD et un HIWORD. Dans ce cas, vous pouvez en créer en utilisant les macros
MAKELPARAM(WORD, WORD) et MAKEWPARAM(WORD, WORD).

Esthétique avancée
Je suis certain que vous avez déjà éprouvé le désir de concevoir des applications ayant un design plus évolué à base de skins, formes fantaisistes etc.,
comme le proposent la plupart des logiciels sur la toile.
Eh bien, je vous propose ici de le réaliser ;) . Vous verrez donc ici comment tailler votre fenêtre comme bon vous semble. Pour cela, il est bien entendu
necessaire que vous ayiez lu auparavant les autres chapitres de ce tutorial, et en particulier L'a ichage (pour les images), et Les événements (surtout pour
les tests relatifs à la souris, les boutons étant pour le moment incrustés au skin*).

Comme vous le savez tous à ce stade, l'API Windows est particulièrement tordue, ou tout du moins un tantinet compliquée lorsqu'il s'agit de dessin.
Par conséquent, je ne vous exposerai pas ici les moyens de faire des boutons hovers (changeant d'état selon le stade de la souris). Vous le verrez plus
tard, durant un chapitre du même thème, mais plus avancé.

Commençons tout d'abord par tailler fenêtre, non pas avec un burin, mais avec les régions.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Les régions
En premier lieu, il est nécessaire de définir ce qu'est une région. En fait, vous pouvez vous la modéliser comme un moule. Je ne sais pas si l'image vous interpelle,
mais c'est comme les formes métalliques que vous appliquez sur un gâteau pour qu'il en prenne justement la forme ^^ .
L'usage de ces régions se définit en plusieurs étapes :

Création d'une région

Application de la région à une fenêtre.

Procédons dans l'ordre (tant qu'à faire :p ), et commençons dont par la création des régions proprement dite.

Important : veillez à donnner le style WS_POPUP à la fenêtre sur laquelle va être appliquée la région crée, car dans le cas contraire elle ne le sera pas
(WS_OVERLAPPEDWINDOW est, rappelons-le, incompatible avec WS_POPUP. Vous devrez donc le remplacer par celui-ci).

Création d'une région


A l'instar des contrôles, une région possède un handle permettant de la manier. Celui-ci, dont le type est HRGN, contient les informations relatives à la région
visée. Cette structure est remplie à partir de fonctions de création de région, autorisant un large éventail de formes possibles, à travers di érentes fonctions.
Voyez-plutôt :

CreateRectRgn()

CreateRoundRectRgn()

CreateEllipticRgn()

CreatePolygonRgn()

...

Celles ci-dessus étant les principales, nous ne verrons que celles-ci (la liste complète se trouvant bien entendu sur msdn).

CreateRectRgn()
CreateRectRgn() permet de créer une région de forme rectangulaire, dont les coordonnées des coins supérieur gauche et inférieur droit sont données.
Le prototype de CreateRectRgn() est le suivant :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
HRGN CreateRectRgn(
int nLeftRect, //Abscisse du coin supérieur gauche de la région
int nTopRect, //Ordonnée du coin supérieur gauche de la région
int nRightRect, //Abscisse du coin inférieur droit de la région
int nBottomRect //Ordonnée du coin inférieur droit de la région
);

Variante : vous pouvez utiliser CreateRectRgnIndirect() à partir d'une simple structure (CONST) RECT*.

CreateRoundRectRgn()
CreateRoundRectRgn() permet de créer une région de la forme d'un rectangle ayant des coins arrondis, et dont les coordonnées des coins supérieur gauche et
inférieur droit, ainsi que les dimensions de l'éllipse (permettant d'obtenir ces arrondis) sont données.

Le prototype de CreateRoundRectRgn() est le suivant :

HRGN CreateRoundRectRgn(
int nLeftRect, //Abscisse du coin supérieur gauche de la région
int nTopRect, //Ordonnée du coin supérieur gauche de la région
int nRightRect, //Abscisse du coin inférieur droit de la région
int nBottomRect //Ordonnée du coin inférieur droit de la région
int nWidthEllipse, //Largeur de l'ellipse inscrite
int nHeightEllipse //Hauteur de l'ellipse inscrite
);

CreateEllipticRgn()
CreateEllipticRgn() permet de créer une région de forme élliptique, dont les coordonnées des coins supérieur gauche et inférieur droit du rectangle dans lequel
elle est inscrite sont données.
Le prototype de CreateEllipticRgn() est le suivant :

HRGN CreateEllipticRgn(
int nLeftRect, //Abscisse du coin supérieur gauche du rectangle circonscrit

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
int nTopRect, //Ordonnée du coin supérieur gauche du rectangle circonscrit
int nRightRect, //Abscisse du coin inférieur droit du rectangle circonscrit
int nBottomRect //Ordonnée du coin inférieur droit du rectangle circonscrit
);

Variante : vous pouvez utiliser CreateEllipticRgnIndirect() à partir d'une simple structure (CONST) RECT*.

CreatePolygonRgn()
CreatePolygonRgn() n'est certes pas la fonction la plus pratique de celles exposées, mais reste la plus intéressante. En e et, en procurant à la fonction un tableau
de coordonnées de points (sous la forme d'un tableau de POINT (CONST) POINT*), leur nombre ainsi que le mode de remplissage (voir ci-après), vous pouvez
créer exactement la région que vous souhaitez.
Son prototype est le suivant :

HRGN CreatePolygonRgn(
CONST POINT *lppt, //Tableau de points
int cPoints, //Nombre de points dans le tableau
int fnPolyFillMode //Mode de remplissage du polygone
);

Une petite mise au point s'impose quant au mode de remplissage. Celui-ci peut prendre les valeurs ALTERNATE, et WINDING. ALTERNATE est souvent conseillé, et
décrit le procédé suivant : selon l'algorithme scanline, la zone comprise entre les arêtes impaires et paires du polygone correspondra à la région créée. (pour plus
amples informations, cherchez sur la Toile :-° )

Opérations diverses
Parfois, ces fonctions ne su isent pas pour obtenir les formes dont vous avez envie (par exemple quand vous n'avez pas envie de récupérer des points pour créer
votre région >_ ). Dans ces cas là, on les complète par d'autres fonctions, comme CombineRgn(), pour étendre encore plus les possibilités.
Celle-ci permet de combiner deux régions, selon le mode de combinaison dont les valeurs possibles sont :

RGN_AND : La région obtenue est l'intersection des deux régions données

RGN_DIFF : La région obtenue est la combinaison des parties de la première des deux régions données, qui n'intersectent pas la deuxième.

RGN_OR : La région obtenue est l'union des deux régions données.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
RGN_XOR : [Comme RGN_OR, sans les intersections des deux régions.]

Voici donc son prototype :

int CombineRgn(
HRGN hrgnDest, //Handle de la région de destination
HRGN hrgnSrc1, //Handle de la première des deux régions à combiner
HRGN hrgnSrc2, //Handle de la deuxième des deux régions à combiner
int fnCombineMode //Mode de combinaison des deux régions
);

La fonction peut alors retourner :

NULLREGION : La région obtenue est vide

SIMPLEREGION : La région obtenue est un rectangle

COMPLEXREGION : La région obtenue est plus qu'un simple rectangle

ERROR : Aucune région ne fut générée

Le but de ce tuto, c'est un peu d'avoir une fenêtre de la forme de son skin, non ? Je vais mettre des années à créer ma région !

Pas de panique, ces fonctions ne sont que des bases (pouvant néanmoins vous servir ultérieurement) à une fonction parfaitement adaptée : BmpToRgn() :ange:
Cette fonction (que j'ai découverte sur cppfrance.com à mes débuts, et créée par anthraxx) permet de récupérer une région à partir d'une image bitmap (donc
d'une image 32bits) et d'une couleur de transparence (par défaut, noir).
Voici le code complet de la fonction :magicien: :

HRGN BmpToRgn (HBITMAP hBmp, COLORREF cTransparentColor)


{
#define ALLOC_UNIT 100

int y, x;
HRGN hRgn = NULL;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
if (!hBmp) return 0; // si bitmap invalide retourne

BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm); // met les infos d'en tete du bitmap dans bm
UINT siz=bm.bmWidth*bm.bmHeight*4; // enregistre la taille des donnes de l'image

char *lpBmpBits=(char*)LocalAlloc(LMEM_FIXED,siz); // fait de la place pour les bits du bitmap


GetBitmapBits(hBmp,siz,lpBmpBits); // obtient les bits de l'image dans l'espace qu'on a reservé
bm.bmBits=lpBmpBits; // complete la strucutre bm avec les bits

while (bm.bmWidthBytes % 4) bm.bmWidthBytes++; // bmWidthBytes doit être divisible par 4

DWORD maxRects = ALLOC_UNIT;


HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES;
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);

BYTE *p32 = (BYTE *)bm.bmBits;


for (y = 0; y < bm.bmHeight; y++) // parcourt toutes les lignes de l'image, de haut en bas
{
for (x = 0; x < bm.bmWidth; x++) // parcourt tous les pixels de la ligne, de gauche à droite
{
// Recherche une suite continue de pixels non transparents
int x0 = x;
LONG *p = (LONG *)(p32 + 4*x);
while (x < bm.bmWidth)
{
if ((unsigned)*p==cTransparentColor)
break; // ce pixel est transparent
p++;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
x++;
}
if (x > x0)
{
// ajoute les pixels (de (x0, y) à (x, y+1)) à la region en tant que rectangle
if (pData->rdh.nCount >= maxRects)
{
GlobalUnlock(hData);
maxRects += ALLOC_UNIT;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) +
(sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pr = (RECT *)&pData->Buffer;
SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y+1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y+1;
pData->rdh.nCount++;

// Il parait que sous Windows 98, ExtCreateRegion() ne marche pas s'il y a trop de rectangles
// Pas de panique: on construit la region en deux fois
if (pData->rdh.nCount == 2000)
{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
// On passe à la ligne suivante
p32 += bm.bmWidthBytes;
}
// On cree la region
// (et, s'il y avait plus de 2000 rectangles, on la combine avec celle créee precedemment)
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else hRgn = h;
LocalFree((HLOCAL)lpBmpBits);
return hRgn;
}

Je ne vous demande evidemment pas de la comprendre, mais juste de savoir l'utiliser (c'est pour votre bien, hein :p ) : le handle de bitmap doit bien entendu être
obtenu par le chargement d'une image avec LoadImage() ou LoadBitmap, et la structure COLORREF (la couleur de transparence) par un appel à RGB(). (voir
L'a ichage)

Testez quand même dans chacun des cas si la région obtenue vaut NULL ou pas (retour des fonctions si la création de la région a échoué).

Application de la région à une fenêtre

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Alors là, il n'y a rien de plus simple, un appel de SetWindowRgn() avec comme paramètres le handle de la fenêtre à laquelle on veut appliquer la région, le handle
de la région à appliquer, et enfin le "Redraw Flag" (booléen à fixer à TRUE si la fenêtre doit être redessinée, ou FALSE sinon).

Exemple
Voici un code illustratif de la manipulation des régions (non compilable) :

HRGN rectRegion,
roundRectRegion,
ellipticRegion,
polygonRegion,
combinedRegion,
bitmapRegion;
RECT rect = {10,10,300,100};
POINT pointArray[5];
//Soit bitmap ayant été chargé au préalable
//Soit hwnd ayant été créé au préalable

rectRegion = CreateRectRgnIndirect(&rect);

/* La plupart du temps, les deux dernières valeurs sont déterminées "au feeling" ;) */
roundRectRegion = CreateRoundRectRgn(10,10,300,100,10,10);

ellipticRegion = CreateEllipticRgnIndirect(&rect);

pointArray[0].x = 0; pointArray[0].y = 1;
pointArray[1].x = 3; pointArray[1].y = 3;
pointArray[2].x = 6; pointArray[2].y = 1;
pointArray[3].x = 5; pointArray[3].y = -2;
pointArray[4].x = 2; pointArray[4].y = -2;

polygonRegion = CreatePolygonRgn(pointArray, 5, ALTERNATE);

//RGN_XOR, par exemple


CombineRgn(combinedRegion, rectRegion, ellipticRegion, RGN_XOR);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
//Le blanc est la couleur transparente
bitmapRegion = BmpToRgn(bitmap, RGB(255,255,255));

//Et enfin :
SetWindowRgn(hwnd, /* region */);

Si vous n'avez plus besoin d'une région, libérez-la avec DeleteObject(). Pensez-y...

Si vous utilisez BmpToRgn(), n'allez pas croire que cette fonction a iche l'image en même temps. (regardez le prototype... est-ce que vous voyez un HDC ?
^^ ) Bien entendu, vous devrez l'a icher postérieurement, en utilisant les méthodes décrites au chapitre L'a ichage.

Rédacteur : Mg++

Gestion de la fenêtre
Maintenant que vous avez une fenêtre taillée par vos soins (dans la majorité des cas, sans barre de titre), peut-être voudriez-vous donner la possiblité à
l'utilisateur de la bouger ? :-°
Pour cela, nous allons utiliser une notification très pratique (car ne servant fort heureusement pas qu'à ça), qui n'est autre que WM_NCHITTEST.
Cette notification est envoyée lorsqu'un événement, dont la source est la souris, survient sur la fenêtre d'un programme. Il s'agit d'un test antérieur aux messages
WM_MOUSEMOVE, WM_LBUTTONDOWN etc. (tout comme WM_KEYDOWN est antérieur à WM_CHAR après test), pour déterminer dans quelle zone de la fenêtre se
trouve la souris. Une fois traitée (si c'est le cas), nous devons renvoyer une constante indiquant la zone de la fenêtre correspondante (après test des coordonnées,
forcément).
Ici, la constante à retourner est HTCAPTION (caption pour titre). Cependant, d'autres constantes peuvent être envoyées, représentant d'autres zones de la fenêtre
:

HTBOTTOM : bordure inférieure (agrandissement vertical possible de la fenêtre)

HTBOTTOMLEFT/HTBOTTOMRIGHT : bordure inférieure gauche/droite (agrandissement possible de la fenêtre)

HTLEFT/HTRIGHT : bordure gauche/droite (agrnadissement horizontal possible de la fenêtre)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
HTMAXBUTTON/HTMINBUTTON : bouton "maximiser"/"minimiser"

HTCLOSE : bouton de clôture

HTGROWBOX - HTSIZE : zone de redimensionnement

HTHELP : bouton d'aide

etc.

Par contre, si la zone visée n'est tout simplement qu'une zone client, vous devez renvoyer HTCLIENT (logique).

Toutes les possiblités de WM_NCHITTEST, comme celles citées ci-dessus, ne sont pas exposées ici, car ce n'est pas le but de cette partie, mais rien ne vous
empêche d'aller vous renseigner sur msdn.

Comment déterminer dans quelle zone le curseur se trouve ?

Je l'ai dit plus haut, il faut tester les coordonnées du curseur. Pour cela, pas besoin de GetCursorPos(), elles se trouvent dans le LPARAM du message (le WPARAM
étant non-utilisé). Par conséquent, vous pourrez les récupérer à l'aide des macros GET_X_LPARAM() et GET_Y_LPARAM(), ou MAKEPOINTS(), expliquées
antérieurement.

Attention ! Les coordonnées retournées sont relatives au coin supérieur gauche de l'écran, et non à la zone client de la fenêtre (normal, puisque la
notification est envoyée avant même que la fenêtre ne traite l'événement correspondant). Vous devrez donc utiliser la fonction GetWindowRect() de
prototype :

BOOL GetWindowRect(
HWND hWnd, //Fenêtre visée
LPRECT lpRect //Pointeur de RECT
);

Ainsi, vous pourrez récupérer les coordonnées du curseur, relatives à la zone client de la fenêtre, par une bête soustraction des coordonnées contenues
dans WM_NCHITTEST par celles retournées par GetWindowRect().

Exemple

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
/* Soit hwnd le handle de la fenêtre, et lParam le LPARAM de la callback */

//WindowProc avec switch du MSG


case WM_NCHITTEST:
{
LRESULT ret = HTCLIENT;

//Coordonnées de la fenêtre
RECT wCoord;
GetWindowRect(hwnd, &wCoord);

//Coordonnées relatives à la zone client de la fenêtre


POINT cCoord;
cCoord.x = GET_X_LPARAM(lParam) - wCoord.left;
cCoord.y = GET_Y_LPARAM(lParam) - wCoord.top;

//tests des coordonnées


if(/* zone dite "de déplacement" */)
ret = HTCAPTION;

//...

return ret;
}

Avec cette méthode, votre fenêtre devrait pouvoir bouger fluidement (en tout cas, autant qu'avec des barres de titre "normales" ;) )
Rédacteur : Mg++
Vous êtes d'orénavant capables de tailler vos fenêtres comme bon vous semble, tout en personnalisant sa gestion (redimensionnements, déplacements etc.).
Dans une prochaine mise à jour du chapitre, nous verrons quelque chose de nettement plus intéressant, à savoir les listbox dites "ownerdraw", les boutons hover
(boutons changeant d'état en fonction du stade de la souris), en utilisant les masques etc., et sûrement à partir de l'élaboration d'une hiérarchie de classes, etc.
Le cours n'est pas terminé, d'autres leçons suivront ;)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Documentation
Vous trouverez ici une mini-documentation remplie au fur et à mesure de l'avancement du tuto.

Fonctions
Voici la liste de toutes les fonctions de l'API Windows que vous avez découvertes dans ce tutoriel.
Pour chaque fonction, j'explique le rôle, ses paramètres et sa valeur de retour.

WinMain

int WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
);

Description
Cette fonction est le point d'entrée de tout programme Windows, c'est elle qui est appelée en premier dans votre programme. C'est en quelque sorte l'équivalent
du main en programme console.

Paramètres

HINSTANCE hInstance

Ce paramètre est l'instance de votre programme, c'est-à-dire une sorte d'identifiant unique qui représente votre programme. Ce paramètre est très important,
puisqu'il est utilisé dans de nombreuses fonctions ou structures comme WNDCLASS ou CreateWindow.

HINSTANCE hPrevInstance

Ce paramètre est obsolète depuis la fin de Windows 16-bit, il est toujours mis à NULL.

LPSTR lpCmdLine

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Ce paramètre est une chaîne de caractères qui contient une copie conforme de la ligne de commande. Ainsi, contrairement aux programmes console, la ligne de
commande n'est pas découpée en arguments mais conservée telle quelle.

int nCmdShow

Ce paramètre a un lien avec ShowWindow, puisqu'il représente l'état dans lequel doit être a ichée la fenêtre du programme : maximisée, minimisée,...

Valeur de retour
Si le WinMain se termine avant la boucle des messages (voir GetMessage), alors elle doit retourner 0.
Sinon, lorsqu'elle reçoit le message WM_QUIT, elle doit renvoyer la valeur contenue dans wParam (voir l'exemple dans la première partie).

RegisterClass

ATOM RegisterClass(
CONST WNDCLASS *lpWndClass
);

Description
Cette fonction enregistre une classe de fenêtre pour une utilisation avec CreateWindow ou CreateWindowEx.
Cette fonction a maintenant été remplacée par une autre, plus puissante : RegisterClassEx, mais elle peut très bien continuer à être utilisée.

Paramètres
Le seul paramètre de cette fonction est un pointeur vers une structure de type WNDCLASS. Pour plus de précision, voir la description de la structure WNDCLASS.

Valeur de retour
Si la fonction réussit, la valeur retournée est un identifiant unique qui représente cette classe.
Si elle échoue, elle renvoie 0.

CreateWindow

HWND CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);

Description
Cette fonction, comme son nom l'indique, sert à créer une fenêtre.

Sous Windows, il faut prendre le terme fenêtre au sens large : un contrôle (par exemple un bouton) est aussi une fenêtre.

Paramètres

LPCTSTR lpClassName

Ce paramètre est le nom d'une classe précédemment enregistrée avec RegisterClass.

Il existe certaines classes prédéfinies pour les contrôles comme


"BUTTON" pour un bouton.
Voir la liste en annexe.

LPCTSTR lpWindowName

Ce paramètre est le nom de la fenêtre lorsque l'on crée une "vraie" fenêtre.
Lorsqu'il s'agit d'un contrôle, ce paramètre peut être utile (ou non). Voilà une liste non exhaustive :

Bouton : texte du bouton

Liste : inutile

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Zone d'édition : texte initial

DWORD dwStyle

Ce paramètre représente le style de la fenêtre, il résulte en fait de la combinaison de nombreuses styles.


Vous pourrez trouver une liste en annexe.
Il existe une série de styles qui s'appliquent à toutes les fenêtres, et d'autres qui ne s'appliquent qu'à certains contrôles.

int x,
int y,
int nWidth,
int nHeight

Ces paramètres représentent la position et la taille initiales de la fenêtre.


Si x=CW_USEDEFAULT, alors le système choisit automatiquement la position de la fenêtre.

CW_USEDEFAULT n'est autorisée que si la fenêtre a le style WS_OVERLAPPED, ou un style qui inclut WS_OVERLAPPED comme WS_OVERLAPPEDWINDOW.

Si nWidth=CW_USEDEFAULT, alors le système choisit automatiquement la taille par défaut de la fenêtre.

La même remarque que ci-dessus s'applique ici.

HWND hWndParent

Ce paramètre est l'identifiant du parent de la fenêtre à créer.


Si ce paramètre vaut NULL, la fenêtre a pour parent le Bureau.

HMENU hMenu

Ce paramètre, lors de la création d'une "vraie" fenêtre, est l'identifiant d'un menu qui s'a ichera en haut de la fenêtre (vous savez comme 'Fichier', 'Édition', 'Aide',
...).
Lors de la création d'un contrôle, celui-ci représente un entier utilisé pour identifier le contrôle sans son HWND.
Par exemple:

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
HMENU identifiantControle=(HMENU)1000;

Il est conseillé de lui donner une valeur supérieure à 100 pour éviter les conflits avec le système.

Si ce paramètre vaut NULL, la fenêtre n'a pas de menu, ou pas d'identifiant selon le cas.

HINSTANCE hInstance

Ce paramètre est l'instance du programme qui crée la fenêtre ; ici en l'occurrence, le vôtre qui est passé en paramètre à WinMain.

LPVOID lpParam

Ce paramètre est un pointeur vers ce que vous voulez, il est utilisé pour passer un paramètre supplémentaire lors de la création de la fenêtre.
Voir la notification WM_CREATE en annexe.

Valeur de retour
Cette fonction renvoie un handle (poignée) sur votre fenêtre, c'est-à-dire une sorte d'identifiant unique, qui vous servira à communiquer avec votre fenêtre pour
(par exemple) créer des contrôles dans votre fenêtre, ou changer sa taille.
Si la valeur de retour vaut NULL, alors la création a échoué.

ShowWindow

BOOL ShowWindow(
HWND hWnd,
int nCmdShow
);

Description
Cette fonction sert à modifier la visibilité d'une fenêtre.

Paramètres

HWND hWnd

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Ce paramètre est le handle sur la fenêtre dont vous voulez modifier la visibilité.
Vous l'obtenez lors de l'appel à CreateWindow par exemple.

int nCmdShow

Ce paramètre peut prendre plusieurs valeurs selon la visibilité que vous voulez appliquer.

SW_HIDE : cache la fenêtre (celle-ci deviendra invisible à l'utilisateur).

SW_MAXIMIZE : la fenêtre prendra la taille de l'écran.

SW_MINIMIZE : la fenêtre sera réduite en barre des tâches.

SW_RESTORE : l'inverse de WS_MINIMIZE, la fenêtre retrouvera son état précédent.

SW_SHOW : rend la fenêtre visible.

SW_SHOWDEFAULT : trop compliqué pour l'instant, il faut avoir une connaissance plus approfondie de Windows pour le comprendre.

SW_SHOWMAXIMIZED : c'est équivalent à SW_SHOW + SW_MAXIMIZE.

SW_SHOWMINIMIZED : c'est équivalent à SW_SHOW + SW_MINIMIZE

SW_SHOWMINNOACTIVE : idem que SW_SHOWMINIMIZED, mais la fenêtre n'est pas activée.

SW_SHOWNA : idem que SW_SHOW mais la fenêtre n'est pas activée.

SW_SHOWNOACTIVATE : idem que SW_SHOWNORMAL, mais la fenêtre n'est pas activée.

SW_SHOWNORMAL : active et montre la fenêtre, si celle-ci est minimisée, cela équivaut à SW_RESTORE.

Je fais une petite remarque :


vous avez sûrement remarqué que j'utilise le mot activé en parlant des fenêtres.
Qu'est-ce que cela veut dire ?
Simplement sous Windows, il y a UNE seule fenêtre active à un moment donné, on appelle ça le focus. C'est elle qui reçoit les événements venant du
clavier et de la souris.

Valeur de retour
Cette fonction renvoie TRUE si elle a réussi, et FALSE si elle a échoué.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
UpdateWindow

BOOL UpdateWindow(
HWND hWnd
);

Description
Cette fonction met à jour la zone client de la fenêtre, en la forçant à être redessinée en envoyant un message WM_PAINTdirectement à la fenêtre, au lieu de placer
le message dans la file des messages.

Paramètres

HWND hWnd

handle de la fenêtre dont la zone client est à redessiner.

Valeur de retour
La fonction renvoie TRUE en cas de succès, et FALSE en cas d'échec.

GetMessage

BOOL GetMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax
);

Description
Cette fonction récupère un message dans la file du thread appelant.

La précision est importante, car si votre programme possède plusieurs thread, il faut faire attention à qui gère l'interface.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Paramètres

LPMSG lpMsg

Ce paramètre est un pointeur vers une structure de type MSG (voir annexe) qui contiendra, après l'appel à la fonction, le message récupéré.

HWND hWnd

Ce paramètre représente l'identifiant de la fenêtre dont on veut récupérer le message.


S'il ce paramètre vaut NULL, alors la fonction récupère un message qui appartient à n'importe quelle fenêtre créée par le thread.

L'intérêt de paramètre est de permettre une granularité plus fine sur les messages que l'on veut faire passer.

UINT wMsgFilterMin,UINT wMsgFilterMax

Ces paramètres représentent respectivement les identifiants des messages les plus "bas" et les plus "hauts" à faire passer.
Si ces paramètres valent 0, tous les messages sont passés.
Valeurs particulières :

WM_KEYFIRST, WM_KEYLAST pour tous les événements clavier.

WM_MOUSEFIRST, WM_MOUSELAST pour tous les événements souris.

Valeur de retour
Cette fonction retourne TRUE si elle réussit, et FALSE si elle échoue.

translatemessage

BOOL TranslateMessage(
const MSG *lpMsg
);

Description

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Cette fonction est uniquement utile pour les messages de type clavier, elle traduit les événements de type Touche Virtuelle (voir note) en événement de types
Caractère (voir note), et poste le message obtenu dans la file des messages.

Qu'est-ce que c'est donc que ça ?


En fait, lorsque vous appuyez sur une touche, le clavier envoie à Windows un nombre qui est le numéro physique de la touche, ensuite Windows traduit ce
numéro en nombre qui est le numéro logique ou virtuel de la touche (les VK_*).
Le problème, c'est que pour les éditeurs de textes, ce n'est pas pratique de savoir quelle touche a été enfoncée ; ce qui les intéressent, c'est le caractère
correspondant à cette touche.
C'est pourquoi cette fonction fait la traduction.

Paramètres

const MSG *lpMsg

Ce paramètre est un pointeur vers le message récupéré par GetMessage.

Valeur de retour
Si le message a été traduit, cette fonction renvoie TRUE.
Si le message est WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN ou WM_SYSKEYUP, cette fonction renvoie TRUE.
Sinon, elle renvoie FALSE.

DispatchMessage

LRESULT DispatchMessage(
const MSG *lpmsg
);

Description
Cette fonction envoie le message à la fonction de callback de la fenêtre concernée.
En quelque sorte, c'est elle qui appelle votre fonction qui gère les messages.

Paramètres

const MSG *lpMsg

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Ce paramètre est un pointeur vers le message récupéré par GetMessage.

Valeur de retour
Cette fonction renvoie la valeur retournée par votre fonction de callback.
Par exemple, si dans votre de fonction de gestion des messages vous faites : "return 1000;",
alors, cette fonction retournera 1000.

WindowProc

LRESULT CALLBACK WindowProc


HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);

Description
Ceci n'est pas vraiment une fonction de l'API Windows à proprement parler : c'est la fonction de gestion des messages envoyée à votre (vos) fenêtre(s).

Paramètres

HWND hwnd

Ceci est le handle de la fenêtre concernée par le message.

UINT uMsg

Ceci est l'identifiant du message.

WPARAM wParam,
LPARAM lParam

Ces paramètres sont entièrement dépendant du message envoyé.


Voir l'annexe sur les messages.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Valeur de retour
Ceci est la valeur retournée par vous-mêmes, ou la fonction DefWindowProc.

DefWindowProc

LRESULT DefWindowProc(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);

Description
Cette fonction appelle la fonction de gestion des messages par défaut du système. Elle est utile lorsque vous ne gérez pas vous-mêmes le message.
En pratique, à chaque fois que vous ne gérez pas un message, vous appelez cette fonction.

Paramètres
Vous devez passer les paramètres de votre fonction de gestion des messages (voir WindowProc) tels quels..

Valeur de retour
Ceci est la valeur retournée par la fonction de gestion des messages. Vous devez retourner cette valeur :

return DefWindowProc(hwnd,uMsg,wParam,lParam);

SendMessage

LRESULT SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Description
Cette fonction permet d'envoyer un message à une fenêtre ou à un contrôle. C'est-à-dire qu'elle va appeler la fonction de gestion des messages de la fenêtre avec
les paramètres que vous spécifiez.
Par exemple, si vous faites :

SendMessage(hwnd,WM_QUIT,0,0);

Ceci va appeler une fonction de type WindowProc, associée à hwnd, avec exactement les mêmes paramètres que vous avez spécifiés.

Paramètres
Ce sont les même que pour WindowProc sauf que hWnd est l'identifiant de la fenêtre à laquelle vous envoyez le message.

Valeur de retour
Cette fonction renvoie la valeur retournée par la fonction de gestion des messages.

MessageBox

int MessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
);

Description
Cette fonction extrêmement pratique permet d'a icher une petite fenêtre avec du texte dedans pour informer l'utilisateur, ou lui demander quelque chose.

Par exemple, lorsque vous fermez votre éditeur de texte préféré, vous obtenez un message :
Voulez-vous sauvegarder votre travail ?
Et un choix Oui / Non. Eh bien vous pouvez faire ceci avec MessageBox.

Paramètres

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
HWND hWnd

Ce paramètre est le handle de la fenêtre qui sera le parent du message a iché.

Mais quel intérêt ?


Vous savez que quand ce message s'a iche dans votre éditeur de texte préféré, vous ne pouvez plus activer votre éditeur de texte, sinon vous obtenez un
'Beeeeeep'.
Eh bien c'est parce que le parent du message est la fenêtre de votre éditeur de texte.

LPCTSTR lpText

Ce paramètre est la chaîne de caractères à a icher dans le message.

Si dans la chaîne de caractères vous mettez ' ', alors cela passera à la ligne suivante comme dans la console.

LPCTSTR lpCaption

Ce paramètre est la chaîne de caractères à a icher comme titre de la fenêtre.

Si dans la chaîne de caractères vous mettez ' ', le résultat est indéfini.

UINT uType

Ce paramètre est le type de message à a icher.


Il peut être la combinaison de plusieurs paramètres grâce au OU binaire(|).
Le premier groupe de paramètres spécifie les boutons à a icher :

MB_ABORTRETRYIGNORE : trois boutons : 'Abandonner', 'Réessayer', 'Ignorer'.

MB_OK : un bouton : 'Ok'.

MB_OKCANCEL : deux boutons : 'Ok', 'Annuler'.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
MB_RETRYCANCEL : deux boutons : 'Réessayer', 'Annuler'.

MB_YESNO : deux boutons : 'Oui', 'Non'.

MB_YESNOCANCEL : trois boutons : 'Oui', 'Non', 'Annuler'.

Le deuxième groupe spécifie l'icône à a icher :

MB_ICONEXCLAMATION : un point d'exclamation.

MB_ICONWARNING : un point d'exclamation.

MB_ICONINFORMATION : un i dans un cercle.

MB_ICONASTERISK : un i dans un cercle.

MB_ICONQUESTION : un point d'exclamation (ce paramètre est déconseillé par Microso ).

MB_ICONSTOP : une icône STOP.

MB_ICONERROR : une icône d'erreur.

MB_ICONHAND : une icône de main.

Le troisième groupe spécifie le bouton par défaut.

C'est quoi le bouton par défaut ?


Vous savez, quand vous avez un message et que vous appuyez sur Entrée, cela "appuie" sur le bouton qui apparaît di érent des autres.

MB_DEFBUTTON1 : le premier bouton de la liste.

MB_DEFBUTTON2 : le deuxième bouton de la liste.

MB_DEFBUTTON3 : le troisième bouton de la liste.

MB_DEFBUTTON4 : le quatrième bouton de la liste.

Le quatrième groupe spécifie le type de fenêtre :

MB_APPLMODAL : l'utilisateur doit répondre, mais peut activer les autres fenêtres du Bureau, sauf la fenêtre parent du message.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
MB_SYSTEMMODAL : même chose que MB_APPLMODAL, mais si la fenêtre parent n'est pas la fenêtre au premier plan, elle le devient, et y reste jusqu'à ce que
l'utilisateur réponde.

MB_TASKMODAL : même chose que MB_APPLMODAL, mais si la fenêtre parent vaut NULL, toutes les fenêtres du thread appelant sont désactivées en
attendant la réponse.

Le dernier groupe spécifie d'autres options :

MB_RIGHT : le texte est justifié à droite.

MB_RTLREADING : le texte est a iché de droite à gauche.

MB_SETFOREGROUND : le fenêtre du message passe au premier plan.

MB_TOPMOST : la fenêtre du message passe au premier plan, et le reste jusqu'à ce que l'utilisateur réponde.

Valeur de retour
Si la fonction échoue, elle renvoie 0.
Si elle réussit, elle renvoie:

IDABORT : l'utilisateur a pressé 'Abandonner'.

IDCANCEL : l'utilisateur a pressé 'Annuler'.

IDCONTINUE : l'utilisateur a pressé 'Continuer'.

IDIGNORE : l'utilisateur a pressé 'Ignorer'.

IDNO : l'utilisateur a pressé 'Non'.

IDOK : l'utilisateur à pressé 'Ok'.

IDRETRY : l'utilisateur à pressé 'Réessayer'.

IDTRYAGAIN : l'utilisateur à pressé 'Essayer encore'.

IDYES : l'utilisateur à pressé 'Oui'.

CreateMenu

HMENU CreateMenu(VOID);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Description
Cette fonction permet de créer un menu. Ce menu est initialement vide.

Paramètres
Valeur de retour
Le handle du menu en cas de succès, et NULL en cas d'échec.

AppendMenu

BOOL AppendMenu(
HMENU hMenu,
UINT uFlags,
UINT_PTR uIDNewItem,
LPCTSTR lpNewItem
);

Description
Cette fonction permet d'ajouter un élément à un menu existant.

Par élément, on entend aussi bien un libellé (texte) qu'une case à cocher, une image ou un sous-menu.

Paramètres

HMENU hMenu

Le handle du menu auquel on va ajouter l'élément.

UINT uFlags

Ce paramètre peut être la combinaison d'un ou plusieurs de ces paramètres :

MF_BITMAP : utilise une image comme élément ; dans ce cas, lpNewItem contiendra alors le handle de l'image.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
MF_CHECKED : place une case à cocher à gauche de l'élément.

MF_DISABLED : désactive l'élément, il ne peut être sélectionné ; mais ce paramètre ne le fait pas apparaître comme grisé.

MF_ENABLED : active l'élément, il peut être sélectionné et n'est pas grisé.

MF_GRAYED : désactive l'élément et le fait apparaître grisé.

MF_MENUBARBREAK : place l'élément dans une nouvelle colonne.

MF_MENUBREAK : même chose que MF_MENUBARBREAK

MF_OWNERDRAW : l'élément est dessiné par l'utilisateur.

MF_POPUP : l'élément ouvre un menu déroulant.

MF_SEPARATOR : l'élément est un séparateur, il ne peut être sélectionné ni mis en surbrillance ; dans ce cas, lpNewItem et uIDNewItem sont ignorés.

MF_STRING : l'élément est un libellé (texte) ; dans ce cas, lpNewItem est pointeur sur le texte à a icher.

MF_UNCHECKED : l'élément n'a pas de case à cocher à sa gauche (c'est le comportement par défaut).

Les groupes suivants ne peuvent être utilisés ensemble :

MF_BITMAP, MF_STRING et MF_OWNERDRAW

MF_CHECKED et MF_UNCHECKED

MF_DISABLED, MF_ENABLED et MF_GRAYED

MF_MENUBARBREAK et MF_MENUBREAK

UINT_PTR uIDNewItem

Spécifie soit l'identifiant du menu, ou si uFlags est mis à MF_POPUP, le handle du sous-menu.

LPCTSTR lpNewItem

Ce paramètre dépend de la valeur de lpNewItem :

MF_BITMAP : handle du bitmap.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
MF_OWNERDRAW : pointeur vers des données utilisateur, utilisables lors du dessin grâce au paramètre lParam.

MF_STRING : pointeur sur la chaîne de caractère à a icher.

Valeur de retour
La fonction renvoie TRUE en cas de succès, et FALSE en cas d'échec.

SetMenu

BOOL SetMenu(
HWND hWnd,
HMENU hMenu
);

Description
Cette fonction permet de définir le menu associé à une fenêtre.

Paramètres

HWND hWnd

handle de la fenêtre à laquelle on assigne un nouveau menu.

HMENU hMenu

handle du nouveau menu, ou NULL pour que la fenêtre n'ait plus de menu associé.

Valeur de retour
Elle renvoie TRUE en cas de succès, et FALSE en cas d'erreur.

En aucun cas cette fonction ne détruit le menu associé, vous devez appelez destroymenu pour accomplir cette tâche.

EnableMenuItem

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
BOOL EnableMenuItem(
HMENU hMenu,
UINT uIDEnableItem,
UINT uEnable
);

Description
Cette fonction permet d'activer, désactiver et griser un élément d'un menu.

Paramètres

HMENU hMenu

handle du menu auquel appartient l'élément à modifier.

UINT uIDEnableItem

Ce paramètre est l'indice ou l'identifiant de l'élément du menu à modifier selon le paramètre uEnable.

UINT uEnable

Ce paramètre peut prendre une ou plusieurs de ces valeurs :

MF_BYCOMMAND : le paramètre uIDEnableItem spécifie l'identifiant de l'élément (comportement par défaut).

MF_BYPOSITION : le paramètre uIDEnableItem spécifie l'indice de l'élément (relatif à 0).

MF_DISABLED : désactive l'élément (celui-ci ne sera pas grisé).

MF_ENABLED : active l'élément et supprime son attribut grisé.

MF_GRAYED : désactive et grise l'élément.

Valeur de retour
La fonction retourne l'état précédent de l'élément modifié (MF_DISABLED, MF_ENABLED ou MF_GRAYED), ou -1 en cas d'échec.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
CheckMenuItem

DWORD CheckMenuItem(
HMENU hmenu,
UINT uIDCheckItem,
UINT uCheck
);

Description
Cette fonction permet de définir l'état de la boîte à cocher de l'élément d'un menu.

Paramètres

HMENU hmenu

handle de l'élément auquel appartient le menu.

UINT uIDCheckItem

Ce paramètre est l'indice ou l'identifiant de l'élément du menu à modifier selon le paramètre uEnable.

UINT uEnable

Ce paramètre peut prendre une ou plusieurs de ces valeurs :

MF_BYCOMMAND : le paramètre uIDEnableItem spécifie l'identifiant de l'élément (comportement par défaut).

MF_BYPOSITION : le paramètre uIDEnableItem spécifie l'indice de l'élément (relatif à 0).

MF_CHECKED : coche la boîte à cocher de l'élément.

MF_UNCHECKED : décoche la boîte à cocher de l'élément.

Valeur de retour
La fonction retourne l'état précédent de l'élément modifié (MF_CHECKED ou MF_UNCHECKED), ou -1 en cas d'échec.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
LoadMenu

HMENU LoadMenu(
HINSTANCE hInstance,
LPCTSTR lpMenuName
);

Description
Cette fonction permet de charger un menu contenu dans une ressource de l'exécutable.

Paramètres

HINSTANCE hInstance

Instance du programme qui contient la ressource à charger.

LPCTSTR lpMenuName

Nom de la ressource à charger.


Peut être une chaîne de caractères, ou un identifiant formé avec la macro MAKEINTRESOURCE.

Valeur de retour
Elle renvoie le handle du menu en cas de succès, et NULL en cas d'échec.

CreateDialog

HWND CreateDialog(
HINSTANCE hInstance,
LPCTSTR lpTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc
);

Description

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Cette fonction permet de créer une boîte de dialogue stockée en ressource dans l'exécutable.

Paramètres

HINSTANCE hInstance

Instance du programme auquel appartient la ressource.

LPCTSTR lpTemplate

Nom de la ressource de type boîte de dialogue.


Peut être un pointeur sur une chaîne de caractères, ou une valeur formée par la macro MAKEINTRESOURCE.

HWND hWndParent

handle de la fenêtre parent de la boîte de dialogue.

DLGPROC lpDialogFunc

Pointeur vers la fonction de gestion des messages de la boîte de dialogue.

Valeur de retour
Cette fonction renvoie le handle de la boite de dialogue, ou NULL en cas d'échec.

DialogBox

INT_PTR DialogBox(
HINSTANCE hInstance,
LPCTSTR lpTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc
);

Cette fonction (qui en fait est une macro) fait la même chose que CreateDialogBox, sauf qu'elle ne rend le contrôle que lors de la destruction de la boîte de
dialogue avec la fonction EndDialog.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Paramètres
Ceux sont les mêmes que pour la fonction CreateDialogBox.

Valeur de retour
Cette fonction renvoie la valeur passée au paramètre nResult de la fonction EndDialog.

EndDialog

BOOL EndDialog(
HWND hDlg,
INT_PTR nResult
);

Description
Cette fonction détruit la boîte de dialogue, et rend le contrôle au thread lorsque celle-ci a été créée avec la fonction DialogBox qui est bloquante.

Paramètres

HWND hDlg

handle de la boîte de dialogue à détruire.

INT_PTR nResult

Spécifie une valeur à retourner à l'application lors de la destruction.

Cette fonction ne détruit pas instantanément la boîte de dialogue, mais attend que la fonction qui a créé la boîte de dialogue rende le contrôle.

Messages
Voici la liste de tous les messages de l'API Windows que vous avez découverts dans ce tutoriel, et qui sont envoyés à la fonction de gestion des messages .
Pour chaque message, j'expliquerai sa signification ainsi que celle des paramètres wParam et lParam et de la valeur retournée.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
WM_CREATE
Description
Ce message est envoyé lors de la création d'une fenêtre avec CreateWindow et CreateWindowEx.

wParam
Ce paramètre est inutilisé.

lParam
Pointeur vers une structure de type CREATESTRUCT.
Voir Annexe sur les structures.

Valeur de retour
Retournez 0 pour continuer la création de la fenêtre, ou -1 pour annuler la création.

WM_DESTROY
Description
Ce message est envoyé lorsqu'une fenêtre va être détruite.

wParam
Ce paramètre est inutilisé.

lParam
Ce paramètre est inutilisé.

Valeur de retour
Retournez 0.

WM_COMMAND
Description
Ce message est utilisé lorsque l'utilisateur interagit avec un contrôle.

wParam

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Le mot haut (récupérable avec HIWORD) est le code de notification du contrôle. Celui-ci est spécifique à chaque classe de contrôle. Il vaut 1 si le message vient
d'un raccourci clavier, et 0 si le message vient d'un menu.
Le mot bas (récupérable avec LOWORD) est l'identifiant de la fenêtre spécifié lors de la création avec CreateWindow et le paramètre hMenu.

lParam
handle du contrôle (fils de la fenêtre qui reçoit le message) qui a envoyé le message.
Il vaut NULL si ce n'est pas un contrôle.

Valeur de retour
Retournez 0.

Structures
Voici la liste de toutes les structures de l'API Windows que vous avez découvertes dans ce tutoriel.
Pour chaque structure, j'expliquerai le rôle de chacun des membres.

WNDCLASS

typedef struct {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
} WNDCLASS, *PWNDCLASS;

Description

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Cette structure est utilisée lors de la création d'une classe de fenêtre.
Elle est passée en paramètre à RegisterClass.

Membres

UINT style

Spécifie les styles de la classe, ce peut être une combinaison avec le OU binaire (|) de n'importe quel paramètre :

CS_BYTEALIGNCLIENT : aligne la zone client des fenêtres sur la frontière d'un octet. Ce style a ecte la taille et la position horizontale des fenêtres.

CS_BYTEALIGNWINDOW : même chose que CS_BYTEALIGNCLIENT, mais concernant la zone fenêtre, et non pas sa zone client.

CS_CLASSDC : les fenêtres de cette classe partagent toutes le même DC (device context) utilisé lorsque l'on dessine dans les fenêtres.

CS_DBLCLKS : les fenêtres reçoivent des événements de type double-clic.

CS_GLOBALCLASS : cette classe est globale au système et non pas locale au programme.

CS_HREDRAW : redessine la fenêtre en cas de changement de largeur des fenêtres.

CS_NOCLOSE : la fenêtre ne peut pas être fermée.

CS_OWNDC : chaque fenêtre à son propre DC.

CS_PARENTDC : permet d'optimiser le dessin dans le DC en récupérant le DC du parent et en empêchant le dessin en dehors de sa surface.

CS_SAVEBITS : lorsqu'une portion de fenêtre est cachée par une autre, sauvegarde cette portion puis la restaure ultérieurement au lieu de redessiner.

CS_VREDRAW : redessine la fenêtre en cas de changement de hauteur.

Mais qu'est-ce qu'un DC ?


Un DC (Device Context) est utilisé lors du dessin dans la zone client d'une fenêtre.
Par exemple, lorsque vous créez des boutons dans une fenêtre, ceux-ci sont dessinés dans des DC, puis ces DC sont copiés sur le DC du parent qui est
ensuite a iché.
On peut voir un DC comme une zone de dessin.
Le paramètre CS_PARENTDC permet, au lieu de copier les DC des fils dans celui du parent (ce qui est lent), de dessiner directement le fils dans le DC du
parent.
Les DC sont principalement utilisé avec les fonctions du GDI qui permettent de dessiner des rectangles, carrés, du texte, des polygones, etc.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
WNDPROC lpfnWndProc

Ce membre est un pointeur vers la fonction de gestion des messages arrivant à toutes les fenêtres de cette classe.

int cbClsExtra

Spécifie le nombre d'octets supplémentaires à allouer dans la structure de la classe.


Cela permet de stocker des données supplémentaires associées à cette classe.

int cbWndExtra

Spécifie le nombre d'octets supplémentaires à allouer dans la structure d'une fenêtre.


Cela permet de stocker des données supplémentaires associées à chaque fenêtre.

HINSTANCE hInstance

Instance du programme qui crée la classe.


Cette variable est passée en paramètre au WinMain.

HICON hIcon

handle de l'icône à a icher dans la barre de titre des fenêtres de cette classe.

HCURSOR hCursor

handle du curseur à a icher quand le pointeur de la souris est au-dessus de la fenêtre.

HBRUSH hbrBackground

Brosse à utiliser pour dessiner le fond de la fenêtre (c'est en rapport avec le GDI).
Il y en a quelques-unes prédéfinies :

COLOR_ACTIVEBORDER

COLOR_ACTIVECAPTION

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
COLOR_APPWORKSPACE

COLOR_BACKGROUND

COLOR_BTNFACE

COLOR_BTNSHADOW

COLOR_BTNTEXT

COLOR_CAPTIONTEXT

COLOR_GRAYTEXT

COLOR_HIGHLIGHT

COLOR_HIGHLIGHTTEXT

COLOR_INACTIVEBORDER

COLOR_INACTIVECAPTION

COLOR_MENU

COLOR_MENUTEXT

COLOR_SCROLLBAR

COLOR_WINDOW

COLOR_WINDOWFRAME

COLOR_WINDOWTEXT

Si ce paramètre est NULL, le programme doit dessiner lui-même le fond de la fenêtre lors des notification WM_PAINT ou WM_ERASEBKGND.

LPCTSTR lpszMenuName

Nom de la ressource à utiliser comme menu pour les fenêtres de la classe (voir note).

LPCTSTR lpszClassName

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Nom de la classe. Il doit être unique dans le programme pour que la classe soit enregistrée avec succès.

Qu'est-ce qu'une ressource ?


Une ressource est une donnée spéciale intégrée à l'exécutable avec un nom.
Par exemple, on peut intégrer une image, un menu, un raccourci clavier, une fenêtre, etc.
Chaque ressource est identifiée par un nom qui peut être une chaîne de caractères ou un identifiant.
Les ressources peuvent aussi être intégrées à l'exécutable avec un fichier .rc.

MSG

typedef struct {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *PMSG;

Description
Cette structure représente un message dans la file des messages envoyés à une fenêtre.

Membres

HWND hwnd

Ceci est le handle de la fenêtre qui doit recevoir le message.

UINT message

Identifiant du message (c'est le même que celui passé à la fonction de gestion des messages).

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
WPARAM wParam
LPARAM lParam

Ce sont des paramètres supplémentaires passés à la fonction de gestion des messages.

DWORD time

L'heure à laquelle le message a été posté.

POINT pt

Position du curseur lorsque le message a été posté.

CREATESTRUCT

typedef struct tagCREATESTRUCT {


LPVOID lpCreateParams;
HINSTANCE hInstance;
HMENU hMenu;
HWND hwndParent;
int cy;
int cx;
int y;
int x;
LONG style;
LPCTSTR lpszName;
LPCTSTR lpszClass;
DWORD dwExStyle;
} CREATESTRUCT, *LPCREATESTRUCT;

Description
Cette structure est passée en paramètre avec le message WM_CREATE.
Elle permet de connaître les paramètres exacts avec lesquels la fenêtre a été créée.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Membres
Les membres sont exactement les mêmes que pour CreateWindow.
Seules précisions :

int x int y int cx int cy


Si, lors de la création, vous avez spécifié CW_USEDEFAULT ou 0, la valeur vaudra alors la taille réelle de la fenêtre.

RECT

typedef struct _RECT {


LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT;

Description
Cette structure permet de stocker di érents paramètres qui ont à voir avec des rectangles comme des dimensions, des marges ou des positions...

Membres

LONG left

Coordonnée en abscisse du coin supérieur gauche.

LONG top

Coordonnée en ordonnée du coin supérieur gauche.

LONG right

Coordonnée en abscisse du coin inférieur droit.

LONG bottom

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Coordonnée en ordonnée du coin inférieur droit.
La documentation sera remplie au fur et à mesure de l'avancement du tuto, et de notre temps libre. ;)

Glossaire
Voici donc les termes que vous ne connaissez peut être pas. N'hésitez pas à regarder si vous avez des doutes.

Termes
msdn : véritable bible du codeur winAPI, c'est en fait la documentation anglaise de Microso accessible ici.

Bas niveau (langage, fonction, instruction, etc.) : peu développé, proche du système voire du matériel. Exemple : langage bas niveau.

Pop-up : se dit d'une fenêtre ou d'un menu apparaissant soudainement après une action de l'utilisateur.

Haut niveau : développé, proche de l'utilisateur ou codeur. Exemple : langage haut niveau.

Instance : utilisé généralement dans les langages orientés objets, désigne une occurrence d'un objet. Elle est dans ce tuto votre programme en lui-même
(c'est un objet après tout). Exemple :

//variable est une instance de Objet


Objet variable;

Fonction callback : fonction chargée de traiter les messages envoyés à une fenêtre, ou à un contrôle. Aussi dénommée procédure. Exemple :

LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);

Template, ou modèle : sorte de schéma situé en ressource décrivant l'organisation d'un objet, comme un menu ou une boîte de dialogue. En C++, c'est une
fonction applicable à n'importe quel type d'argument. Exemple :

ID_MENU MENU
BEGIN
POPUP "Menu"

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
BEGIN
MENUITEM "Commande 1", ID_CMD1
MENUITEM "Commande 2", ID_CMD2
END
END

Cast, ou transtypage : action de transformer le type d'une variable en une autre. Exemple :

long lVariable = (long)iVariable

Flag, ou drapeau : caractère spécial donné à un objet, pouvant être combiné avec l'opérateur logique |. Généralement utilisé pour les styles. Exemple :

truc.uFlags = F_TRUC | F_MACHIN;

Focus : fait, généralement pour un contrôle, de recevoir tous les évènements clavier. Pour une fenêtre, on parle d'active.

Le glossaire n'est pas fini, il est rempli au fur et à mesure de l'avancement du tuto ;)

Manipulation du registre
Vous allez ici apprendre à manier les clés registre en utilisant des fonctions définies dans l'API win32.
A la fin de ce chapitre, vous saurez, en modifiant manuellement (avec le winAPI) ou semi-manuellement (en modifiant les clés à la main) :

Lancer votre programme au démarrage de windows

Changer l'icône d'un type de fichiers

Associer votre programme avec un ou plusieurs types de fichiers

Pour ce faire, lisez ce qui suit attentivement et ne modifiez surtout pas ce que vous ne connaissez pas.

Quelques notions de BDR


Avant de commencer, nous allons vous inculquer quelques notions de BDR.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Mais que diable est-ce, la BDR ?

La BDR est une base de données où sont stockées les informations nécessaires au bon fonctionnement de Windows. On y trouve :

les configurations de l'ordinateur (matériel, etc.)

la personnalisation de Windows (a ichage, sons, etc.)

les préférences utilisées pour les programmes et jeux (historiques, tableaux de scores, options, chemins d'accès, etc.)

etc.

Ainsi, chaque fois que vous modifiez ne serait-ce qu'une chose (si petite soit elle) dans votre ordinateur, la BDR s'en trouve sensiblement changée.
Les informations sont classées dans des dossiers dans l'arborescence, et se présentent sous la forme de clés registre. Celles-ci sont des informations, possédant
un type, un ID et une valeur.

Normalement, les clés registre sont les dossiers présents dans l'arborescence, et les informations des valeurs, mais j'ai préféré garder cette syntaxe pour
une meilleure compréhension.

Vous pouvez accéder à la BDR en tapant 'regedit' (comme registry edit) dans la boîte de dialogue 'Exécuter...', présente dans le menu 'Démarrer'.

Pour ceux qui ne l'ont jamais vue, voici sous quelle forme se présente la BDR :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Comme vous pouvez le voir sur cette capture d'écran, les répertoires à la racine de la BDR sont :

HKEY_LOCAL_MACHINE : contient les informations communes à tous les utilisateurs de la machine.

HKEY_CLASSES_ROOT : contient les informations sur les extensions de fichiers, donc des associations.

HKEY_CURRENT_USER : contient les informations (préférences en général) spécifiques à l'utilisateur actuel.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
HKEY_USERS : contient les paramètres propres à chaque utilisateur.

HKEY_CURRENT_CONFIG : contient les configurations de l'utilisateur actuel.

Bien ! Je pense que vous savez maintenant le minimum pour débuter. Direction la prochaine partie.

Rédacteur : Mg++

Changement d'icône de fichiers


Commençons progressivement. Nous allons voir comment, à partir du répertoire racine HKEY_CLASS_ROOT, changer l'icône associée à un type de fichier.

1ère méthode : méthode semi-manuelle (manipulation au travers de regedit)


Voilà comment est organisée la BDR de ce côté-ci : un dossier portant comme nom une extension contient une clé registre (default) portant comme valeur le nom
descriptif du fichier. Alors, le dossier portant ce nom descriptif à l'intérieur de HKEY_CLASSES_ROOT (donc un niveau en arrière) contient un dossier intitulé
DefaultIcon. Dans celui-ci, la clé (default) porte comme valeur le chemin de l'icône associée à ce type de fichiers.

Il se peut que le chemin de l'icône ne vous porte pas à croire que cela en est un : parfois (souvent en fait pour Windows), ce chemin est en fait le chemin
d'accès vers une DLL (Dynamic Link Library), contenant dans ses ressources l'icône demandée. Il est alors suivi d'une virgule, et d'un nombre étant son ID
en ressource.

Voici concernant le descriptif de son organisation. Concrètement, les étapes permettant de changer l'icône peuvent être représentées sur un schéma comme ceci :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Comme voir est mieux que croire, je vais vous indiquer pas à pas comment changer l'icône d'un fichier XML (par exemple).
En premier lieu, ouvrez la BDR et rendez-vous dans HKEY_CLASSES_ROOT.
Vous devriez voir ceci :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Ensuite, recherchez le dossier portant comme nom '.xml', et ouvrez-le.

Information bien pratique et souvent oubliée : vous pouvez accéder directement au dossier recherché en tapant les premiers caractères du dossier en
question. Vous vous retrouverez avec le dossier trouvé en surbrillance. ;)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Mémorisez ensuite la valeur du (default) contenue dedans. Il s'agit du nom descriptif du fichier concerné.
Vous aurez ceci :

Puis, rendez-vous au dossier portant ce nom descriptif, sachant qu'il est contenu au même niveau de HKEY_CLASSES_ROOT que les extensions, et ouvrez-le. Vous
verrez à l'intérieur un dossier intitulé DefaultIcon, le dossier que nous cherchons.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Rendez-vous y et vous pourrez alors contempler le chemin de l'icône concernée, contenu dans la valeur du (default) de ce dossier.
En fait, vous voyez normalement ceci :

Pour modifier l'icône, faites un clic droit sur la clé (default) et sélectionnez Modify. Une boîte de dialogue s'ouvre, et vous pourrez alors sélectionner le chemin de
l'icône voulue dans le champ Valeur avant de quitter.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Une illustration :

L'icône est ainsi changée. :)

2ème méthode : méthode manuelle (utilisation du winAPI) dans un code en C


Pour modifier le registre Windows dans votre code, vous aurez besoin d'inclure la bibliothèque nécessaire dans votre code, à savoir :

#include <windows.h>

Celle-ci, seule bibliothèque à intégrer au code pour se servir du winAPI, définit les fonctions permettant de manipuler le registre dont nous aurons besoin :

RegOpenKeyEx()

RegCreateKeyEx()

RegQueryValueEx()

RegSetValueEx()

RegCloseKey()

Ces fonctions agissent sur une variable de type "handle de clé" ou HKEY.
Maintenant que vous avez les informations nécessaires, allons créer notre code ;) .
Une fonction sera beaucoup plus pratique, pour la maintenance et la lisibilité du code. Je vous propose donc cette forme de fonction :

void changeIcon(const char *ext, const char *icon);

ext désigne l'extension dont on veut modifier l'icône

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
icon désigne le chemin de l'icône voulue

Voyons maintenant son contenu :

Les déclarations de variables

Le handle de clé :

HKEY key;

Une string qui va nous permettre de mémoriser ce dont nous avons besoin :

char mem[MAX_PATH] = "";

Une variable indiquant la taille de la string récupérée, pour queryValue :

DWORD kSize /* = 8192 */;

Etapes

Ouverture du dossier portant l'extension comme nom :

RegOpenKeyEx(
HKEY_CLASSES_ROOT, //Nom de la branche principale
ext, //Nom de la sous-clé (dossier), ici l'extension
0, //réservé
KEY_ALL_ACCESS, //Tout accès
&key //Taille de la donnée, en bytes
);

Récupération dans mem de la valeur du default :

RegQueryValueEx(
key,
NULL, //NULL, donc valeur de (default)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
0,
NULL, //Taille de data (inutile)
(BYTE*)mem, //Buffer de sortie
&kSize
);

Ouverture du dossier DefaultIcon situé dans celui portant le nom descriptif du fichier :

strcat(mem, "\\DefaultIcon");
RegOpenKeyEx(
HKEY_CLASSES_ROOT,
mem,
0,
KEY_ALL_ACCESS,
&key
);

Remplacement du chemin d'accès à l'icône par celui de l'icône voulue :

RegSetValueEx(
key,
NULL, //(default)
0,
REG_SZ, //Type de data
(BYTE*)icon,
strlen(icon)+1 //Taille de data
);

On n'oublie pas de fermer la clé :

RegCloseKey(key);

Nous avons maintenant fait le tour, je pense... Voici donc le code complet de la fonction :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
#include <windows.h>

void changeIcon(const char *ext, const char *icon)


{
HKEY key;
DWORD kSize;
char mem[MAX_PATH] = "";

RegOpenKeyEx(HKEY_CLASSES_ROOT, ext, 0, KEY_ALL_ACCESS, &key);

RegQueryValueEx(key, NULL, 0, NULL, (BYTE*)mem, &kSize);

strcat(mem, "\\DefaultIcon");
RegOpenKeyEx(HKEY_CLASSES_ROOT, mem, 0, KEY_ALL_ACCESS, &key);

RegSetValueEx(key, NULL, 0, REG_SZ, (BYTE*)icon, strlen(icon)+1);

RegCloseKey(key);

return;
}

Je n'explique pas ici comment revenir en arrière. Alors si c'est pour un test, prévoyez une méthode de rattrapage. Ce n'est pas bien compliqué, je vous
propose de créer une clé de backup que vous pourrez copier dans le (default) quand vous en aurez marre. Vous avez normalement tout ce qu'il faut pour,
mais si vous avez du mal, le forum est là. ;)

Rédacteur : Mg++

Lancement au démarrage de windows

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Maintenant que vous avez normalement compris comment manipuler, que cela soit à partir de regedit ou du winAPI, la BDR, inutile de détailler autant. (C'est
surtout que je n'ai plus de place pour les images. :p )
Alors dans cette partie, je vais vous apprendre comment lancer votre application au démarrage de Windows. C'est pas bien long, et pas bien compliqué, mais si
vous n'avez pas entièrement compris le principe de la BDR ou comment la manier, je vous renvoie à la sous-partie n°2.

1ère méthode : semi-manuelle (au travers de regedit)


Afin d'ajouter un programme à la liste de démarrage (au startup, dans le jargon), il faut juste ouvrir le dossier So ware\Microso \Windows\CurrentVersion\Run,
situé dans la branche d'arborescence HKEY_CURRENT_USER (pour l'utilisateur actuel seulement, c'est préférable), et ajouter une clé registre portant comme ID
votre nom de programme, et comme valeur son chemin d'accès.

Pour cela, placez-vous dans le dossier Run dont la place a été citée, faites un clic droit sur la zone d'énumération des clés registre (partie droite), sélectionnez New
-> Key et spécifiez comme dit plus haut :

comme ID : votre nom de programme (peu importe)

comme valeur : son chemin d'accès.

Veillez à ne pas bouger votre programme entre temps, sinon l'ouverture du programme au startup échouera. Pour le parer, vous pouvez le placer dans
un répertoire permanent, ou changer la clé à chaque fois.

Vous pouvez aussi spécifier des paramètres à votre exécutable (comme d'habitude), en délimitant le chemin d'accès des arguments (avec des
guillemets), et en les plaçant à sa suite entre des espaces.

En ce qui conçerne sa suppression de la liste de démarrage, vous n'avez qu'à vous rendre dans le répertoire Run, et supprimer la clé que vous avez créée.

2ème méthode : manuelle (en utilisant le winAPI)


Pareil ici, rien de compliqué ou de long. Pour faire ce travail, je vous propose la fonction suivante :
2ème méthode : manuelle (en utilisant le winAPI)
Pareil ici, rien de compliqué ou de long. Pour faire ce travail, je vous propose la fonction suivante :

Association de fichiers

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Dans cette partie, je vais vous apprendre comment associer votre programme avec un type défini de fichiers.

1ère méthode : semi-manuelle (à l'aide de regedit)


Ici, retour à la branche d'arborescence HKEY_CLASSES_ROOT, puisque c'est là que la gestion des extensions est faite.
Le processus est assez semblable au changement d'icône : un dossier portant l'extension du fichier comporte un (default) pointant vers un autre dossier (contenu
au même endroit que l'extension) étant le nom descriptif du type de fichier. Mais comme vous avez pu le voir sur les captures d'écran, il y a d'autres dossiers dans
celui-ci, autres que DefaultIcon. Dans un de ceux-ci, Shell, se trouve Open, et dedans se trouve enfin command.

Il se peut que pour certains types de fichiers (comme les fichiers musicaux), Open ne soit pas la seule commande disponible : il peut y avoir notamment
Play... Dans ce cas-là, normalement on doit répéter l'opération, mais les entrées sont supprimées, si ce n'est pas le chemin de WMP (alala, Microso ). Mais
si vous voulez plus de précisions sur ces cas-ci, envoyez-moi un MP.

C'est sa valeur (default) qui va déterminer quel programme va lancer ce type de fichier à la commande Open du clic droit d'un ou plusieurs fichiers. En e et, il
comporte le chemin d'accès au programme, suivi de soit "%1", si le programme n'ouvre qu'un fichier à la fois, soit "%L", s'ils sont plusieurs et donc listés.

En e et, %1 et %L sont des opérateurs batch : le premier sera remplacé par le seul, ou le premier fichier ouvert (puisqu'il n'en autorise qu'un), alors que
l'autre sera remplacé par la liste des fichiers ouverts. Chacun se fait remplacer par des chemins d'accès absolus. Par exemple, "C:\Folder\Program.exe"
/open "%1" enverra à l'exécution du programme "C:\Folder\Program.exe" comme premier argument, /open comme deuxième, et le chemin absolu du
fichier ouvert en troisième.

Maintenant que vous avez vu l'organisation des associations, voici un exemple de nouvelle association de fichiers. Je vais vous expliquer comment associer
Notepad++ aux fichiers .txt par exemple.
Voici la marche à suivre, comme vous l'avez deviné ;) :

ouvrez HKEY_CLASSES_ROOT

Repérez le dossier portant le nom .txt et ouvrez-le.

Mémorisez le (default) contenu à l'intérieur (à savoir txtfile).

Retournez dans HKEY_CLASSES_ROOT, et ouvrez txtfile.

Ouvrez maintenant successivement Shell, Open, et enfin command.

Modifiez la valeur du (default) par le chemin de NotePad++ entre guillemets (puisqu'il n'est pas la seule information), suivi d'un espace et de "%1"

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Cette manoeuvre n'est qu'à titre indicatif, je ne sais pas si NotePad++ ne possède aucun argument excepté le fichier ouvert.

Voilà, l'association est terminée :)

2ème méthode : manuelle (en utilisant le winAPI)


Passons maintenant au codage.
Cette fois-ci, je vous propose la fonction suivante :

void associate(const char *ext, const char *path);

ext désigne l'extension à associer

path désigne le chemin d'accès à votre programme

Vous aurez besoin comme d'habitude de :

un handle de clé :

HKEY key;

une string tampon :

char mem[MAX_PATH];

Une taille d'info nécessaire à RegQueryValueEx() en bytes :

DWORD kSize /* = 8192*/;

Pour transcrire cette manoeuvre en code, vous n'aurez ni plus ni moins besoin que des fonctions citées précédemment.

Voici les étapes requises :

Ouverture du dossier portant l'extension comme nom :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
RegOpenKeyEx(
HKEY_CLASSES_ROOT,
ext,
0,
KEY_ALL_ACCESS,
&key
);

Récupération dans mem de la valeur du default :

RegQueryValueEx(
key,
NULL,
0,
NULL,
(BYTE*)mem,
&kSize
);

Ouverture du dossier pointé, en précisant la commande d'ouverture du shell :

strcat(mem, "\\Shell\\Open\\command");
RegOpenKeyEx(
HKEY_CLASSES_ROOT,
mem,
0,
KEY_ALL_ACCESS,
&key
);

Remplacement du chemin d'accès par celui de votre programme :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
//Changez le %1 par %L dans le cas d'une sélection multiple possible
sprintf(mem,"\"%s\"/*arguments possibles*/ \"%1\"", path);
RegSetValueEx(
key,
NULL,
0,
REG_SZ,
(BYTE*)mem,
strlen(mem)+1
);

Fermeture du handle de clé :

RegCloseKey(key);

Et voici la fonction complète (incluant la prise en compte des erreurs) :

Je n'ai pas prévu dans cette fonction de moyen de retour, donc prévoyez un système de copie comme celui que j'ai décrit dans la deuxième partie pour le
changement d'icônes au cas où...

void associate(const char *ext, const char *path)


{
HKEY key;
DWORD kSize;
char mem[MAX_PATH] = "";

if(RegOpenKeyEx(HKEY_CLASSES_ROOT, ext, 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)


{
RegQueryValueEx(key, NULL, NULL, NULL, (BYTE*)mem, &kSize);

strcat(mem, "\\Shell\\open\\command");

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
if(RegOpenKeyEx(HKEY_CLASSES_ROOT, mem, 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
{
sprintf(mem,"\"%s\" \"%1\"", path);
RegSetValueEx(key, NULL, 0, REG_SZ, (BYTE*)mem, strlen(mem)+1);
}
}
RegCloseKey(key);

return;
}

Et vous avez votre association. :)

Veillez à ne pas bouger votre exécutable après, sinon l'ouverture échouera.

Rédacteur : Mg++
Si vous avez des questions de précision ou des problèmes, n'hésitez pas à poster dans le forum, il est fait pour ça ;) .
Les fonctions n'ont pas été testées mais marchent sans doute possible. Néammoins dans le cas contraire, veuillez m'adresser un MP.

N'oubliez pas de prévoir une solution de suppression pour chacun des cas.

Divers

Utiliser le style du Windows courant


Vous allez ici apprendre à donner le style de votre Windows actuel à votre application.

Téléchargement préalable
Pour cela, vous aurez besoin d'un fichier manifeste, se présentant sous la forme d'un fichier xml.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Commencez donc par télécharger celui-ci.
(Clic droit + Enregistrer sous...)
Si le téléchargement échoue, sachez qu'il s'agit seulement d'un fichier codé en ASCII (donc avec NotePad, par exemple) et renommé en .xml, contenant le code
suivant :

<assembly manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="CompanyName.ProductName.YourApplication" type="win3
2"/>
<description>Description de votre application ici.</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
</assembly>

Association
Pour associer le manifeste à votre application, vous disposez de deux méthodes :

dynamiquement, donc pendant l'exécution

en utilisant les ressources, ceci pour l'intégrer à l'exécutable.

Dynamiquement
En utilisant cette méthode, l'exécutable utilisera le manifeste situé dans le même dossier que celui-ci.
Commencez par renommer votre manifeste avec le nom de votre exécutable comme radical, et avec ".manifest" comme extension. Par exemple, si votre
exécutable s'appelle "Programme.exe", alors renommez "manifest.xml" en "Programme.exe.manifest".
Vous n'avez plus qu'à placer le manifeste renommé dans le répertoire contenant votre exécutable.

En utilisant les ressources


Vous avez peut-être envie de vous débarrasser de quelques fichiers entourant l'exécutable, en les intégrant aux ressources ? Comme le manifeste, par exemple ? :p
Bien. Alors tout se passe à la compilation. Rajoutez à votre script ressource (*.rc) le code d'intégration suivant :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
1 24 "manifest.xml"

Dans ce cas-ci, 1 est l'ID du manifeste, 24 son type, et "manifest.xml" son chemin.

Modifiez-le en conséquence s'il ne se trouve pas dans le répertoire des codes sources.

Attention, dans certains cas (je n'en connais pas la raison à ce jour), vous obtiendrez une fenêtre vide. Alors, la procédure à observer est la suivante :
Inclure <commctrl.h>.
Appeler InitCommonControls() au début du programme.
Linker le projet avec comctl32.lib ou libcomctl32.a (selon le compilateur utilisé).

Pour les feignants utilisant Code::Blocks, vous pouvez passer outre ces étapes, simplement en accédant à l'entrée Windows XP look'n'feel via le menu
Plugin.

Vous n'avez plus qu'à contempler votre application disposer du style du Windows courant. ;)
Rédacteur : Mg++

La notation hongroise

La notation hongroise est une notation largement employée par Microso , qui consiste à faire apparaître, dans le nom de chaque variable, le type de celle-
ci.

Les avis sont partagés à son sujet : à savoir si elle est utile ou non, productive ou non, mais toujours est-il qu'elle reste employée, et qu'on a tout intérêt à la
comprendre.

Principe
Nous allons donc ici décrire les sigles qui reviennent le plus souvent.
En fait, elle consiste à préfixer en minuscules le nom de la variable (qui commence alors par une majuscule) par le sigle de son type.

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Exemple:

HANDLE hWnd;
INT iX;
CHAR cCode;

Les préfixes
Les préfixes utilisés sont:

i : entier (int ou INT en général)

n : entier court (short int ou SHORT)

l : entier long (long int ou LONG)

f : nombre à virgule flottante simple précision (float ou FLOAT)

d : nombre à virgule flottante double précision (double ou DOUBLE)

c : caractère (char ou CHAR) ou un dénombrement

ch : caractère (char ou CHAR)

b : booléen (bool ou BOOL)

s : chaîne de caractères (CHAR *, PCHAR, LPSTR, LPCSTR, ...)

sz : chaîne de caractères terminée par un zéro (CHAR *, PCHAR, LPSTR, LPCSTR, ...)

w : mot ou "word" en anglais (WORD)

dw : double-mot ou "double word" en anglais (DWORD)

h : handle (HANDLE, HWND, HFILE, HBITMAP, ...)

pt : point (POINT)

rgb : couleur (RGB) [rarement utilisée]

str : encore une autre façon de préciser une chaîne de caractères.

Les modificateurs
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Il existe aussi quelque modificateurs:

u : non-signé. Exemple : ul pour ULONG

lp, p ou p_ : pointeur sur quelque chose. Exemple : lpstr ou psz...

a ou ar : tableau (ou "array" en anglais) [rarement utilisé]

m_ : membre d'une classe (C++) ou d'une structure

g_ : variable globale

s_ : variable statique (correspondant au mot-clé static en C/C++).

Exemples
Ainsi, en mélangeant les deux, on peut obtenir ceci par exemple :

LPSTR g_szName;// variable globale qui est une chaîne de caractères terminée par zéro.

struct Truc
{
PPOINT m_lpptPosition;// variable membre d'une structure, pointeur sur une structure de type point.
};

INT cbExtra;// nombre(le 'c') d'octets(le 'b') supplémentaires (à allouer par exemple)

Évidemment, il ne faut pas en abuser. Dans l'exemple précédent, cela alourdit inutilement l'expression ; on pourra omettre le "pt".
Rédacteur : Pamaury

Quelques codes...
Depuis la parution de mon tutoriel, j'ai répondu à diverses questions, parfois en fournissant un code fonctionnel. J'ai donc décidé de répertorier ici-même ces
di érents codes afin que vous puissiez en profiter ;)

Gestion du presse-papier

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Le presse-papier revient souvent sur les forums, en particulier en ce qui concerne les futurs traitements de texte en WinAPI. C'est pour cela que j'ai créé deux
petites fonctions toutes simples permettant sa gestion, GetClipboardText() et SetClipboardText(), qui conviendront aux moins exigeants, tout en inspirant les plus
exigeants :) :

#include <windows.h>

/* goto peut être utilisé si la redirection est dans le sens direct de la lecture du code (on évite le code spaguetti), et que
son utilisation est claire... Pour moi, ça l'est. */
#define REDIRECT_IF(condition, label) if(condition) goto label

#define EXIT_LABEL local_exit


#define EXIT_IF(condition) REDIRECT_IF(condition, EXIT_LABEL)

/* Quand "on colle" : */


char *GetClipboardText()
{
char *text = NULL;

EXIT_IF(!IsClipboardFormatAvailable(CF_TEXT));

EXIT_IF(!OpenClipboard(NULL));

{
char *textMem = (char*)GetClipboardData(CF_TEXT);

/* free devra être utilisé une fois le texte utilisé */


text = malloc((lstrlen(textMem)+1) * sizeof *text);
lstrcpy(text, textMem);
}

CloseClipboard();

EXIT_LABEL:
return text;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
}

/* Quand "on copie" : */


int SetClipboardText(char const *text)
{
int ret = 0;

HANDLE hGlobalMem = GlobalAlloc(GHND, lstrlen(text)+1);


char *lpGlobalMem = NULL;

EXIT_IF(hGlobalMem == NULL);

lpGlobalMem = (char*)GlobalLock(hGlobalMem);

EXIT_IF(lpGlobalMem == NULL);

lstrcpy(lpGlobalMem, text);

GlobalUnlock(hGlobalMem);

EXIT_IF(!OpenClipboard(NULL));

EmptyClipboard();

if(SetClipboardData(CF_TEXT, hGlobalMem) != NULL)


ret = 1;

CloseClipboard();

EXIT_LABEL:
return ret; /* 1 : Succeed, 0 : Failure */
}

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
En ce qui concerne la détection du copier-coller, mieux vaut se fier à des fonctions dédiées à ces opérations, en spécifiant sa fenêtre listener des opérations
de copier-coller, grâce à SetClipboardViewer(). Ainsi, toute modification du presse papier se traduira par la réception du message WM_DRAWCLIPBOARD,
qu'il faudra traiter.

Gestion du drag and drop


La question du drag-and-drop est aussi quelque peu récalcitrante, puisque l'API Windows ne fournit pas de système direct pour s'en charger. J'en ai jadis proposé
un, qui se résume à une unique fonction GetDroppedFilesPaths() :
Citation : Moi

Un petit exemple censé écrire les chemins des fichiers lâchés sur la fenêtre dans un fichier (situé dans le même répertoire que l'exécutable)
nommé "Result.txt" (pas compilable tel quel).
/* Callback procedure : Soit hwnd (HWND) et wParam (WPARAM), passés en paramètre à la procédure. */
case WM_CREATE:
/* Ne pas oublier d'accepter les drag-and-drop ;) */
DragAcceptFiles(hwnd, TRUE);
return 0;

case WM_DROPFILES:
{
CHAR **paths = NULL;

UINT count = GetDroppedFilesPaths((HDROP)wParam, paths);

WritePathsToFile(paths, count, "Result.txt");

/* On n'oublie pas de libérer la mémoire allouée */


{
UINT i = 0;
while(i < count)
free(paths[i++]);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
free(paths);
}

/* Ne pas oublier de finir la procédure de drag */


DragFinish((HDROP)wParam);

return 0;
}

Avec :
/* Il aurait mieux fallu utiliser le système de gestion des fichiers de l'API, mais bon... */
#include <stdio.h>
#include <windows.h>

VOID WritePathsToFile(
CONST CHAR ** CONST paths,
CONST UINT count,
LPCSTR resPath
)
{
FILE *file = NULL;
file = fopen(resPath, "a");

if(file != NULL)
{
for(UINT i = 0 ; i < count ; i++)
fputs(paths[i], file);

fclose(file);
}
}

static UINT GetDroppedFilesCount(HDROP hDrop)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
{
return DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
}

static UINT GetDroppedFileLen(HDROP hDrop, CONST UINT index)


{
return DragQueryFile(hDrop, index, NULL, 0);
}

UINT GetDroppedFilesPaths(HDROP hDrop, CHAR **paths)


{
const UINT count = GetDroppedFilesCount(hDrop);

paths = malloc(count * sizeof *paths);


if(paths == NULL)
return 0;

for(UINT i = 0 ; i < count ; i++)


{
const UINT droppedFilePathLen = GetDroppedFileLen(hDrop, i);

paths[i] = malloc(droppedFileLen * sizeof *paths[i]);


if(paths[i] == NULL)
return i;

DragQueryFile(hDrop, i, paths[i], droppedFileLen);


}
return count;
}

Il faut bien évidemment autoriser la fenêtre au drag-and-drop via les styles de la fenêtre ou DragAcceptFiles()...

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
N'oubliez pas de libérer la mémoire allouée par les chemins des fichiers récupérés ! Gare aux fuites de mémoire dans le cas contraire...

Gestion d'une icône dans la barre des tâches


Voici deux fonctions toutes simples permettant de minimiser et de restaurer une application :

/* Cache ton application et place une icône dans la barre de tâches,


dont le handle est hIcon, szTip le message affiché dans une petite bulle (due au
survol prolongé de la souris), et msg le message callback, permettant de traiter
les événements */
NOTIFYICONDATA *Minimize(HWND handler, HICON hIcon, LPCTSTR szTip, UINT msg)
{
NOTIFYICONDATA *nim = malloc(sizeof *nim);

nid->cbSize = sizeof(NOTIFYICONDATA);
nid->hWnd = handler;
nid->uID = 0;
nid->hIcon = hIcon;
nid->uCallbackMessage = msg;
nid->uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;

strcpy(nid->szTip, szTip);

Shell_NotifyIcon(NIM_ADD, nid);
ShowWindow(handler, SW_HIDE);

return nid;
}

void Restore(NOTIFYICONDATA *data)


{
ShowWindow(data->hWnd, SW_SHOW);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Shell_NotifyIcon(NIM_DELETE, data);
}

Et voilà un exemple d'utilisation :

/* Par exemple, la zone utilisateur étant située après WM_USER */


#define TI WM_USER+1

/* On minimise la fenêtre en récupérant une structure qui servira à la restaurer */


NOTIFYICONDATA *data = Minimize(hwnd, LoadIcon(hInstance, "Icon"), "Je suis une TrayIcon", TI);

/* ... */

/* On restaure la fenêtre */
Restore(data);
/* Et on n'oublie pas de libérer la mémoire... */
free(data);

/* ... */

/* Quant au switch du low-word du message : */


case TI:
/* Traitement, par exemple avec TrackPopupMenuEx(), voir msdn */

Encore une fois, n'oubliez pas de libérer la mémoire occupée par l'instance de NOTIFYICONDATA nouvellement créée !

Une idée à fouiller lors de l'encapsulation


Un jour on m'a demandé si c'était possible de spécifier une méthode comme callback, et voici ce que je lui ai répondu :
Citation : Moi

Le fait est que... C'est impossible ^^ La callback doit être statique. Edit: Question de signature... Ca paraît logique avec la structure
WNDCLASSEX
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Tu dois donc contourner le problème. Voici ce que je te propose : Utilise SetWindowLongPtr() après création de ta fenêtre pour passer
l'objet courant (obtenu à travers la structure CREATESTRUCT passée par le LPARAM de la callback statique) en tant que pointeur
récupérable grâce à GetWindowLong() (par exemple, à l'emplacement GWLP_USERDATA) dans la callback statique qui se chargera alors de
rediriger les événements perçus vers les callbacks virtuelles correspondantes.
Fouille cette idée, si tu as du courage :
class Wnd
{
HWND m_handle;

//...

static LRESULT StaticProc(HWND, UINT, WPARAM, LPARAM);


static LRESULT DefProc(HWND, UINT, WPARAM, LPARAM);

//...

virtual LRESULT virtualProc(UINT, WPARAM, LPARAM); //Pure ou pas

//...
};

class MyWnd : public Wnd


{
//...

virtual LRESULT virtualProc(UINT, WPARAM, LPARAM); //Override


};

LRESULT Wnd::StaticProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)


{
LRESULT ret = 0;

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
//Si la fenetre est en creation, le pointeur n'a pas ete encore initialise
if(uMsg == WM_NCCREATE)
{
/* SetWindowLongPtr() de 'this' contenu dans lParam grâce au dernier paramètre
de CreateWindowEx() -> Voir CREATESTRUCT structure */
SetObjectFromCreateStruct(hWnd, lParam); //A toi de la créer...
}

Wnd *pObj = reinterpret_cast<Wnd*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));


if(pObj != NULL)
ret = pObj->virtualProc(uMsg, wParam, lParam);
else
ret = DefProc( hWnd, uMsg, wParam, lParam);

return ret;
}

Cela reste primitif, mais c'est une solution à envisager lorsqu'on est nous-même Orienté Objet ( ^^ ) et que l'on est réticent à utiliser MFC. Cela permet en outre de
bien contrôler les rouages d'une API ainsi simplifiée.

Utiliser les Dynamic Link Library


Ou DLL qui vous permettent de découper le code dans d'autres fichiers joints à l'exécutable, soit afin de l'alléger (on lie tout de même statiquement pour
s'a ranchir des contraintes de chargement dynamiques, tout se passe comme s'il s'agissait d'une bibliothèque statique [.a, .lib] à la génération, mais les
bibliothèques sont stockées à part dans des DLL), soit liées dynamiquement (chargement de la DLL et de ses fonctions à l'exécution, dans le code, aucune
opération de linker). Les DLL permettent une maintenance facilitée, pour par exemple des mises à jour sur des points particuliers, simplement en remplaçant
uniquement des DLL, sans toucher au reste. Elles sont particulièrement utiles pour les plugin.
DavySharp974, que je remercie au passage, nous propose une bibliothèque qui regroupe le code de liaison dynamique des DLL dans 3 fonctions. On ne détaille
pas la création desdites DLL et d'une manière générale leur fonctionnement, mais cela peut vous faciliter la vie. Et qui sait, cela sûrement complété.
Citation : DavySharp974

Dans cette partie, vous pourrez apprendre comment charger dynamiquement une DLL sous Windows :) Pour ce faire, il vous faut
télécharger libDLL

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Dézippez les fichiers et mettez-les dans les bons emplacements (excepté le fichier 'test_dll.dll' qui doit être dans le même répertoire que
votre projet de test).
Au cas où le lien soit cassé, ou pour simple information, voilà le code de la bibliothèque :
sqdll.h

/*
Library for DLL loading.
by Davy Sharp

This program is free software: you can redistribute it and/or modify


it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,


but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __SQ_EXT_DLL_H
#define __SQ_EXT_DLL_H

#if !defined _WIN32 && !defined __Win32__


#error "libDLL was designed to be used uner Windows only !"
#endif

#ifdef __cplusplus
extern "C"
{

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
#endif

typedef struct sq_dll_struct_t* sqdll_t;

sqdll_t dll_load(const char* file_name);


void dll_free(sqdll_t dll_ptr);

void* dll_function(sqdll_t dll_ptr, const char* function_name);

#ifdef __cplusplus
}
#endif

#endif // __SQ_EXT_DLL_H

sqdll.c
#include <windows.h>

#include "sqdll.h"

struct sq_dll_struct_t
{
HINSTANCE h_dll;
};

void* dll_function(sqdll_t dll_ptr, const char* function_name)


{
if (dll_ptr != NULL)
{
return GetProcAddress(dll_ptr->h_dll, function_name);
}
else
{

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
return NULL;
}
}

sqdll_t dll_load(const char* file_name)


{
sqdll_t ptr = malloc(sizeof(*ptr));

if (ptr != NULL)
{
ptr->h_dll = LoadLibrary(file_name);

if (ptr->h_dll == NULL)
{
free(ptr);

ptr = NULL;

return ptr;
}
}

return ptr;
}

void dll_free(sqdll_t dll_ptr)


{
if (dll_ptr != NULL)
{
FreeLibrary(dll_ptr->h_dll);

free(dll_ptr);

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
}
}

Nos pouvons à présent commencer à coder notre programme de test.


Ecrivez un main vide, avec un 'return 0' à la fin.
int main(int argn, char** argv)
{
return 0;
}

Dans le header 'libdll.h', libDLL définit trois fonctions, les trois seules dont vous aurez besoin pour utiliser une DLL.
la première fonction s'appelle sqdll_t* dll_load(const char* nomDuFichierDLL) . Comme son nom l'indique (où pas :p ), elle sert à
charger la DLL.
Nous avons donc:
int main(int argn, char** argv)
{
sqdll_t maDLL = dll_load("test_dll.dll"); // Chargement de la dll 'test_dll.dll' qui devrait être dans le répertoire de
votre projet

return 0;
}

Ensuite, la fonction la plus importante, celle qui permet d'utiliser les fonctions de la DLL, s'appelle
void* dll_function(sqdll_t*, const char* nomDeLaFonction)

Elle prend en premier paramètre le pointeur de Handle de DLL et en second paramètre le nom de la fonction à charger.
Son retour est de type void* car elle ne sait pas le type de retour et celui des arguments de la fonction qu'on charge.
En revanche, nous, on le connait :) la DLL 'test_dll.dll' contient une fonction int ajouter(int a, int b)

Nous déclarons donc le pointeur sur la fonction ajouter comme ceci: int (*ajouter)(int, int)

Je récapitule, finalement, le code écrit est

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
int main(int argn, char** argv)
{
sqdll_t maDLL = NULL; // On initialise à NULL
int (*ajouter)(int, int) = NULL; // On initialise à NULL

maDLL = dll_load("test_dll.dll"); // Chargement de la dll 'test_dll.dll' qui devrait être dans le répertoire de votre
projet

if (!maDLL) // Si le chargement a échoué...


{
printf("Erreur, impossible de trouver 'test_dll.dll' !"); // On affiche un message d'erreur...

return -1; // Et on renvoie un code d'erreur


}

ajouter = dll_function(maDLL, "ajouter"); // On charge la fonction 'ajouter' depuis la DLL

if (!ajouter) // Si le chargement a échoué...


{
printf("Erreur, impossible de trouver la fonction 'ajouter' dans 'test_dll.dll'); // On affiche un message...

dll_free(maDLL); // Ne pas oublier de libérer la DLL, même si la fonction n'a pas été trouvée dedans

return -2; // Et on renvoie un code d'erreur


}

// Si on arrive jusqu'ici, c'est que tout s'est bien passé

printf("La somme de %d et %d est %d", 429, 763, ajouter(429, 763)); // On utilise la fonction 'ajouter'

dll_free(maDLL); // on n'oublie pas de libérer la DLL en quittant

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
return 0;
}

Il me semblait en avoir d'autres en réserve, mais je vous avoue que j'ai un peu la flegme de me plonger dans mon courrier dans une chasse aux codes :-°
D'autres surgiront peut-être ?
Rédacteur : Mg++
Les annexes ne sont pas finies, elles sont avancées au fur et à mesure de la progression du tuto ;)

Programmes
Ici seront recensés les programmes créés en WinAPI, dont vous m'aurez fait part.

Neoblast, de Kidpaddle2 (ex-Mg++)


Image utilisateur

Bonjour !
Je poste ici pour vous présenter un programme que j'ai jadis créé : NeoBlast.

Qu'est ce que c'est ?


NeoBlast (en français : "Sou le Nouveau") est un lecteur audio avancé pouvant lire la totalité des fichiers audios présents sur vos ordinateurs respectifs :

Wave

mp3

Wma

Ogg

etc...

Comment ?

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
J'ai utilisé la bibliothèque fmod afin d'avoir le plus de fonctions possible permettant de manipuler les fichiers audio pour les implémenter dans mon programme.
[Malheureusement, même si celle-ci est portable, la bibliothèque graphique utilisée (GUI) étant le windows API ou API win32 n'est pas portable, et ne fonctionnera
que sous Windows.]

Que fait-il de spécial ?


NeoBlast ne fait rien de vraiment "spécial", mais se contente d'avoir la plupart des fonctionnalités des lecteurs audio "pro" présents sur le net :

lecture des fichiers audio (logique)

gestion de playlist

Drag and drop dans la playlist

Seeker

a ichage en temps réel des infos de la musique (temps, titre, etc.)

fonctions principales (Play / Pause / Stop / Next / Previous)

ouverture simple des fichiers musicaux en unic ou multi select à travers une boite de dialogue d'ouverture

chargement / Sauvegarde de playlist au format m3P (format propriétaire)

scan du / des disques pour trouver automatiquement les fichiers audio

possibilité de rejouer la playlist arrivée à la fin

Shu le

possibilité de lancer NeoBlast au démarrage :

minimisé

avec une playlist spécifiée

Skin améliorés

Parlons-en des skin... ils sont comment ?


Pour vous faire une idée, voici :
Le skin principal :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Le skin de la playlist :

Un grand merci à Musethebest pour la conception des skin... d'ailleurs un peu de pub :p .
[Le noir est utilisé pour la présentation : l'utilisation des régions m'a permis de pouvoir avoir des fenêtres ayant la forme de ces skins (avec la couleur noire
comme transparente) sans barre de titre.]
Pour bouger les fenêtres modélisées par les skins, exécutez un drag avec le bouton droit de la souris. (voir "Help" pour quelques précisions).

Génial ! Où le télécharger ?
(Bin quoi, c'est possible non ? :-° )
Vous pourrez le télécharger (en étant équipé d'un extracteur de rar / zip) à partir des liens ci-dessous :
(N'oubliez pas de lire le fichier "Help" situé dans le menu Démarrer, et s'il vous plaît, ne sautez pas la licence.)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Liens :
Télécharger NeoBlast v1.0 (Anglais

Télécharger NeoBlast v1.0 (Français)

Place aux tests


Voilà la présentation est terminée, place aux tests !
Vous pourrez consulter les codes sources (C) présents dans le répertoire d'install de NeoBlast ; attention, ils sont très indigestes, je l'ai créé à mes débuts, n'étant à
cette époque pas rigoureux.
Si vous avez des avis, des commentaires, des critiques [constructives] ou encore des suggestions, n'hésitez pas à écrire dans mon livre d'or situé sur mon site e-
Synapse, où une présentation dudit logiciel est aussi présente (au cas où).

Le prochain programme à paraître est PlayTyle, nettement pus évolué et codé à l'aide d'MFC. Sa sortie n'est toutefois pas prévue pour demain, même s'il
est bien avancé :lol:

Remerciements :
Musethebest qui s'est occupé des skins

Médinoc qui m'a beaucoup aidé sur le forum de developpez.com

___________________________________|

|_________________________________

DdPop, de damien.09
Qu'est ce que c'est ?
En quoi cela consiste t'il : (principales caractéristiques)

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Programme permettant de s'échanger des messages sur un réseau local comme sur internet. (avec l'adresse IP ou le nom du PC distant)

Possibilité de s'échanger des fichiers (depuis la version 3.0 du 14/04/07)

Mettre en contact jusqu'a 8 personnes. (il faut pour cela le module DDpop-Serveur : vous pourez virer les utilisateurs qui sont pas sages :p )

Faire en sorte que le programme démarre et se connecte automatiquement à l'ouverture d'une session.

Possibilité de minimiser l'application dans la systray (=barre d'icône à coté de l'horloge).

Choix du port utilisé.

Choix de la police de caractère ainsi que des couleurs (couleur de fond et couleur du texte).

Vous pouvez aussi envoyer des Wizz (comme sur MSN).

Quelques sons pour agrémenter le tout.

Points n'ayant pu être développés :


Le multiplateforme : il marche que sous Windows :o (je me suis tout de même e orcé d'assurer la compatibilité avec Windows98 :) ).

Un aperçu

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Lien et contact
Voici l'adresse ou vous pouvez télécharger DDpop : http://damien09.programmes.site.voila.fr. Il est conseillé de télécharger également le module DDpop-Serveur
(ça va avec DDpop) comme ça vous pourrez être 8 à dialoguer ;) .
Les téléchargements (DDpop et DDpopServeur) incluent une Documentation expliquant le fonctionnement du programme correspondant, n'hésitez pas à la
consulter.

Infos
Les caractéristiques indiquées ci-dessus ne sont peut être pas celles de la dernière version, si vous voulez les caractéristiques de la version actuelle référez vous à
cette page.
DDpop et DDpop-Serveur sont des programmes codés en C++ avec l'API Windows par Dando.D.
N'hésitez pas à laisser des commentaires ici ou à me poser des questions :) et prevenez moi si vous trouvez des bugs.
La liste n'est pas complète, n'hésitez pas à rajouter les votres !
Sauf mention contraire, tous les projets sont sous licence GPL, et peuvent donc être étudiés (pas d'appropriation, et les modifications entraîneront
obligatoirement une citation du créateur originel).

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Pour ajouter votre projet à cette liste, créez un chapitre (mini-tuto), rédigez votre présentation avec une dernière sous-partie étant "Liens", puis copiez-
collez vos rédactions (en zCode) dans un MP que vous m'enverrez ; je m'occuperais de la mise à jour.

Si vous avez des problèmes, contactez nous par MP.

Pour en savoir plus :

Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD