Partager via


Création d'applications Win32 (C++)

Cette procédure pas à pas montre comment créer une application Win32 de base qui affiche « Hello, World! » dans une fenêtre. Vous pouvez utiliser le code que vous développez dans cette procédure pas à pas comme modèle pour la création d'autres applications Win32.

L'API Win32 (également connue sous le nom d'API Windows) est une infrastructure basée sur le langage C qui permet de créer des applications Windows. Pour plus d'informations sur l'API Win32, consultez API Windows.

Important

Pour pouvoir expliquer plus clairement certains segments de code contenus dans les étapes de ce document, nous omettons parfois des instructions de code qui sont en fait nécessaires au bon fonctionnement d'une application ; c'est le cas, par exemple, des directives Include et des déclarations de variables globales. La section Exemple à la fin de ce document montre le code complet.

Composants requis

Pour compléter cette procédure pas à pas, vous devez comprendre les notions de base du langage C++. Si vous commencez l'apprentissage du C++, nous recommandons « C++ Beginner's Guide » (en anglais) écrit par Herb Schildt, qui est disponible à l'Espace formations pour développeurs débutants (éventuellement en anglais) sur le site Web MSDN.

Pour une présentation vidéo, consultez Vidéo : Comment créer des applications Win32 (C++) (page éventuellement en anglais) dans la documentation de Visual Studio 2008.

Pour créer un projet Win32

  1. Dans le menu Fichier, cliquez sur Nouveau, puis sur Projet.

  2. Dans la boîte de dialogue Nouveau projet, dans le volet gauche, cliquez sur Modèles installés, sur Visual C++, puis sélectionnez Win32. Dans le volet central, sélectionnez Projet Win32.

    Dans la zone Nom, tapez un nom pour votre projet, par exemple win32app. Cliquez sur OK.

  3. Dans la page d'accueil de l'Assistant Application Win32, cliquez sur Suivant.

  4. Dans la page Paramètres de l'application, sous Type d'application, sélectionnez Application Windows. Sous Options supplémentaires, sélectionnez Projet vide. Cliquez sur Terminer pour créer le projet.

  5. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le projet Win32app, cliquez sur Ajouter, puis sur Nouvel élément. Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Fichier C++ (.cpp). Dans la zone Nom, tapez un nom pour le fichier, par exemple GT_HelloWorldWin32.cpp. Cliquez sur Ajouter.

Pour démarrer une application Win32

  1. De même que toute application C ou C++ doit avoir une fonction main comme point de départ, toute application Win32 doit avoir une fonction WinMain. La syntaxe de WinMain est la suivante.

    int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nCmdShow);
    

    Pour plus d'informations sur les paramètres et la valeur de retour de cette fonction, consultez Fonction WinMain.

  2. Dans la mesure où le code d'application doit utiliser des définitions existantes, ajoutez des instructions Include au fichier.

    #include <windows.h>
    #include <stdlib.h>
    #include <string.h>
    #include <tchar.h>
    
  3. Outre la fonction WinMain, chaque application Win32 doit également avoir une fonction de procédure de fenêtre. En règle générale, cette fonction se nomme WndProc. La syntaxe de WndProc est la suivante.

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

    Cette fonction traite les nombreux messages qu'une application reçoit du système d'exploitation. Par exemple, dans une application qui comporte une boîte de dialogue avec un bouton OK, lorsque l'utilisateur clique sur le bouton, le système d'exploitation envoie à l'application un message indiquant qu'un clic a eu lieu sur le bouton. WndProc est responsable de la réponse à cet événement. Dans l'exemple ci-dessus, la réponse appropriée peut être de fermer la boîte de dialogue.

    Pour plus d'informations, consultez Procédures de fenêtre.

Pour ajouter des fonctionnalités à la fonction WinMain

  1. Dans la fonction WinMain, créez une structure de classe de fenêtre de type WNDCLASSEX. Cette structure contient des informations concernant la fenêtre, par exemple l'icône de l'application, la couleur d'arrière-plan de la fenêtre, le nom à afficher dans la barre de titre, le nom de fonction de la procédure de fenêtre, et ainsi de suite. L'exemple suivant illustre une structure WNDCLASSEX classique.

        WNDCLASSEX wcex;
    
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    

    Pour plus d'informations sur les champs de cette structure, consultez WNDCLASSEX.

  2. Maintenant que vous avez créé une classe de fenêtre, vous devez l'inscrire. Utilisez la fonction RegisterClassEx et passez la structure de la classe de fenêtre en tant qu'argument.

        if (!RegisterClassEx(&wcex))
        {
            MessageBox(NULL,
                _T("Call to RegisterClassEx failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
  3. Vous pouvez à présent créer une fenêtre. Utilisez la fonction CreateWindow.

    static TCHAR szWindowClass[] = _T("win32app");
    static TCHAR szTitle[] = _T("Win32 Guided Tour Application");
    
    // The parameters to CreateWindow explained:
    // szWindowClass: the name of the application
    // szTitle: the text that appears in the title bar
    // WS_OVERLAPPEDWINDOW: the type of window to create
    // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
    // 500, 100: initial size (width, length)
    // NULL: the parent of this window
    // NULL: this application does not have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindow(
        szWindowClass,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 100,
        NULL,
        NULL,
        hInstance,
        NULL
    );
    if (!hWnd)
    {
        MessageBox(NULL,
            _T("Call to CreateWindow failed!"),
            _T("Win32 Guided Tour"),
            NULL);
    
        return 1;
    }
    

    Cette fonction retourne un HWND, qui est un handle à une fenêtre. Pour plus d'informations, consultez Types de données Windows.

  4. À présent, utilisez le code suivant pour afficher la fenêtre.

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindow
    // nCmdShow: the fourth parameter from WinMain
    ShowWindow(hWnd,
        nCmdShow);
    UpdateWindow(hWnd);
    

    À ce stade, le contenu de la fenêtre affichée est très limité, car vous n'avez pas encore implémenté la fonction WndProc.

  5. Ajoutez maintenant une boucle de messages pour écouter les messages envoyés par le système d'exploitation. Lorsque l'application reçoit un message, cette boucle le distribue à la fonction WndProc pour traitement. Le code de la boucle de messages ressemble au code suivant.

        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return (int) msg.wParam;
    

    Pour plus d'informations sur les structures et fonctions de la boucle de messages, consultez MSG, GetMessage, TranslateMessage et DispatchMessage.

    À ce stade, le code de la fonction WinMain doit ressembler au code suivant.

    int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nCmdShow)
    {
        WNDCLASSEX wcex;
    
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    
        if (!RegisterClassEx(&wcex))
        {
            MessageBox(NULL,
                _T("Call to RegisterClassEx failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
        hInst = hInstance; // Store instance handle in our global variable
    
        // The parameters to CreateWindow explained:
        // szWindowClass: the name of the application
        // szTitle: the text that appears in the title bar
        // WS_OVERLAPPEDWINDOW: the type of window to create
        // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
        // 500, 100: initial size (width, length)
        // NULL: the parent of this window
        // NULL: this application dows not have a menu bar
        // hInstance: the first parameter from WinMain
        // NULL: not used in this application
        HWND hWnd = CreateWindow(
            szWindowClass,
            szTitle,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT,
            500, 100,
            NULL,
            NULL,
            hInstance,
            NULL
        );
    
        if (!hWnd)
        {
            MessageBox(NULL,
                _T("Call to CreateWindow failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
        // The parameters to ShowWindow explained:
        // hWnd: the value returned from CreateWindow
        // nCmdShow: the fourth parameter from WinMain
        ShowWindow(hWnd,
            nCmdShow);
        UpdateWindow(hWnd);
    
        // Main message loop:
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return (int) msg.wParam;
    }
    

Pour ajouter des fonctionnalités à la fonction WndProc

  1. Pour permettre à la fonction WndProc de gérer les messages que l'application reçoit, implémentez une instruction switch.

    Le premier message à gérer est le message WM_PAINT. L'application reçoit ce message lorsqu'une partie de sa fenêtre affichée doit être mise à jour. (Lorsque la fenêtre est affichée pour la première fois, elle doit être mise à jour en totalité.)

    Pour traiter un message WM_PAINT, appelez d'abord BeginPaint, gérez ensuite toute la logique de disposition du texte, des boutons et des autres contrôles de la fenêtre, puis appelez EndPaint. Pour cette application, la logique entre l'appel de début et l'appel de fin consiste à afficher la chaîne « Hello, World! » dans la fenêtre. Dans le code suivant, notez que la fonction TextOut est utilisée pour afficher la chaîne.

    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR greeting[] = _T("Hello, World!");
    
    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
    
        // Here your application is laid out.
        // For this introduction, we just print out "Hello, World!"
        // in the top left corner.
        TextOut(hdc,
            5, 5,
            greeting, _tcslen(greeting));
        // End application-specific layout section.
    
        EndPaint(hWnd, &ps);
        break;
    }
    
  2. Une application gère généralement beaucoup d'autres messages, par exemple WM_CREATE et WM_DESTROY. Le code suivant illustre une fonction WndProc élémentaire mais complète.

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT ps;
        HDC hdc;
        TCHAR greeting[] = _T("Hello, World!");
    
        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
    
            // Here your application is laid out.
            // For this introduction, we just print out "Hello, World!"
            // in the top left corner.
            TextOut(hdc,
                5, 5,
                greeting, _tcslen(greeting));
            // End application specific layout section.
    
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
            break;
        }
    
        return 0;
    }
    

Exemple

Pour générer cet exemple

  1. Créez un projet Win32 comme indiqué dans « Pour créer un projet Win32 » précédemment dans cette procédure pas à pas.

  2. Copiez le code correspondant à ces étapes, puis collez-le dans le fichier source GT_HelloWorldWin32.cpp.

  3. Dans le menu Générer, cliquez sur Générer la solution.

  4. Pour exécuter l'application, appuyez sur F5. Une fenêtre qui contient le texte « Hello, World! » doit apparaître dans l'angle supérieur gauche de l'affichage.

Code

// GT_HelloWorldWin32.cpp
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

// Global variables

// The main window class name.
static TCHAR szWindowClass[] = _T("win32app");

// The string that appears in the application's title bar.
static TCHAR szTitle[] = _T("Win32 Guided Tour Application");

HINSTANCE hInst;

// Forward declarations of functions included in this code module:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(NULL,
            _T("Call to RegisterClassEx failed!"),
            _T("Win32 Guided Tour"),
            NULL);

        return 1;
    }

    hInst = hInstance; // Store instance handle in our global variable

    // The parameters to CreateWindow explained:
    // szWindowClass: the name of the application
    // szTitle: the text that appears in the title bar
    // WS_OVERLAPPEDWINDOW: the type of window to create
    // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
    // 500, 100: initial size (width, length)
    // NULL: the parent of this window
    // NULL: this application does not have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindow(
        szWindowClass,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 100,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
    {
        MessageBox(NULL,
            _T("Call to CreateWindow failed!"),
            _T("Win32 Guided Tour"),
            NULL);

        return 1;
    }

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindow
    // nCmdShow: the fourth parameter from WinMain
    ShowWindow(hWnd,
        nCmdShow);
    UpdateWindow(hWnd);

    // Main message loop:
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR greeting[] = _T("Hello, World!");

    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);

        // Here your application is laid out.
        // For this introduction, we just print out "Hello, World!"
        // in the top left corner.
        TextOut(hdc,
            5, 5,
            greeting, _tcslen(greeting));
        // End application-specific layout section.

        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
        break;
    }

    return 0;
}

Étapes suivantes

Précédent : Création d'applications Windows (C++) | Suivant : Création d'une application Windows Forms à l'aide du .NET Framework (C++)

Voir aussi

Tâches

Création d'applications Windows (C++)

Historique des modifications

Date

Historique

Motif

Décembre 2010

Mention de l'omission éventuelle de certaines instructions de code normalement obligatoires afin de rendre plus claire l'explication d'autres parties du code.

Commentaires client.