Programmation Windows/Les bases de l'API Win32

Un livre de Wikilivres.
Sauter à la navigation Sauter à la recherche


Section 1 : les bases de Windows[modifier | modifier le wikicode]

Section 2 : API Win32 et contrôles d'interface utilisateur[modifier | modifier le wikicode]

Section 3 : Microsoft Foundation Classes (MFC)[modifier | modifier le wikicode]

Section 4 : Dynamic Data Exchange (DDE), ActiveX et COM[modifier | modifier le wikicode]

Section 5 : programmation des pilotes de périphériques[modifier | modifier le wikicode]

Section 6 : programmation shell[modifier | modifier le wikicode]

Annexes[modifier | modifier le wikicode]

Go-previous-grey.svg [[Programmation Windows/|]]

Ce premier chapitre va vous apprendre les bases de l'API Win32.

Code de base[modifier | modifier le wikicode]

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.

La Bibliothèque est installée par défaut sur la Quasi-totalité des IDE. 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 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 :

#include <windows.h>

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

É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. 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 autre... 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) :

      LPSTR lignesDeCommande

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

Le petit dernier ne vous servira probablement pas souvent : il s'agit du mode d'affichage (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 à :

En compilant en Unicode [1]: un wchar_t Sinon : un char

Et voilà pour une présentation restreinte.

Vous savez maintenant ne rien afficher sans erreur de compilation ! Génial, non ? Vous en voulez plus ? D'accord, direction "Votre première fenêtre" .

Pour ceux qui veulent absolument un "Hello World" avant de commencer ,voici la formule magique à rajouter dans le WinMain :

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


Votre première fenêtre[modifier | modifier le wikicode]

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


Le Code de base[modifier | modifier le wikicode]

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

#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...".

Les variables nécessaires[modifier | modifier le wikicode]

Nous aurons besoin pour afficher 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.


  • 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'.
  • classeFenetre est la classe de fenêtre 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++.)

Références[modifier | modifier le wikicode]

  1. En 2013, Unicode est le standard le plus aboutit pour gérer la plupart des systèmes d'écritures du monde entier. À ce sujet lire par exemple le wikibooks À la découverte d'Unicode