Condividi tramite


Creazione di applicazioni basate su Win32 (C++)

In questa procedura dettagliata viene illustrato come creare un'applicazione basata su Win-32 che visualizza "Hello, World!" in una finestra. È possibile utilizzare il codice sviluppato in questa procedura dettagliata come modello per creare altre applicazioni basate su Win-32.

L'API Win32, nota anche come API di Windows, è un framework basato sul linguaggio C per la creazione di applicazioni Windows. Per ulteriori informazioni sull'API Win32, vedere API di Windows.

Nota importanteImportante

Per poter illustrare più chiaramente segmenti specifici di codice nei passaggi di questo documento, è possibile che vengano omesse alcune istruzioni di codice altrimenti necessari per un'applicazione funzionante, ad esempio le direttive di inclusione e le dichiarazioni di variabili globali. Nella sezione Esempio alla fine di questo documento viene illustrato il codice completo.

Prerequisiti

Per completare questa procedura dettagliata è necessario comprendere le nozioni di base del linguaggio C++. Coloro che stanno iniziando ad apprendere le prime nozioni di C++ troveranno particolarmente utili le informazioni per utenti principianti di C++ di Herb Schildt, disponibile nel sito Beginner Developer Learning Center sul sito Web MSDN (informazioni in lingua inglese).

Per una dimostrazione video, vedere il video sulla creazione di applicazioni Win32 (C++) nella documentazione di Visual Studio 2008.

Per creare un progetto basato su Win32

  1. Scegliere Nuovo dal menu File, quindi fare clic su Progetto.

  2. Nel riquadro di sinistra della finestra di dialogo Nuovo progetto fare clic su Modelli installati, scegliere Visual C++ e quindi Win32. Nel riquadro centrale selezionare Progetto Win32.

    Nella casella Nome digitare un nome per il progetto, ad esempio win32app. Scegliere OK.

  3. Nella pagina introduttiva della Creazione guidata applicazione Win32 fare clic su Avanti.

  4. Nella pagina Impostazioni applicazione in Tipo di applicazione selezionare Applicazione Windows. In Opzioni aggiuntive selezionare Progetto vuoto. Scegliere Fine per creare il progetto.

  5. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto Win32app, scegliere Aggiungi, quindi Nuovo elemento. Nella finestra di dialogo Aggiungi nuovo elemento scegliere File di C++ (.cpp). Nella casella Nome digitare un nome per il file, ad esempio GT_HelloWorldWin32.cpp. Scegliere Aggiungi.

Per avviare un'applicazione basata su Win32

  1. Proprio come ogni applicazione C e C++ che deve disporre di una funzione main come punto iniziale, ogni applicazione basata su Win32 deve disporre di una funzione WinMain. WinMain presenta la sintassi seguente.

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

    Per informazioni sui parametri e sul valore restituito di questa funzione, vedere Funzione WinMain.

  2. Poiché il codice dell'applicazione deve utilizzare definizioni esistenti, aggiungere istruzioni di inclusione al file.

    #include <windows.h>
    #include <stdlib.h>
    #include <string.h>
    #include <tchar.h>
    
  3. Oltre alla funzione WinMain, ogni applicazione basata su Win32 deve disporre anche di una funzione routine di finestra. Questa funzione viene in genere denominata WndProc. WndProc presenta la sintassi seguente.

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

    Questa funzione gestisce i molti messaggi ricevuti da un'applicazione dal sistema operativo. Ad esempio, in un'applicazione con una finestra di dialogo con un pulsante OK, quando l'utente fa clic sul pulsante, il sistema operativo invia all'applicazione un messaggio per segnalare che è stato fatto clic sul pulsante. WndProc è responsabile della risposta a questo evento. Nell'esempio la risposta appropriata può essere la chiusura della finestra di dialogo.

    Per ulteriori informazioni, vedere Routine della finestra.

Per aggiungere funzionalità alla funzione WinMain

  1. Nella funzione WinMain creare una struttura della classe della finestra di tipo WNDCLASSEX. Questa struttura contiene informazioni sulla finestra, ad esempio l'icona dell'applicazione, il colore di sfondo della finestra, il nome da visualizzare nella barra del titolo, il nome della funzione della ruotine della finestra e così via. Nell'esempio che segue è illustrata una struttura WNDCLASSEX tipica.

        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));
    

    Per informazioni sui campi della struttura, vedere WNDCLASSEX.

  2. Dopo aver creato la classe della finestra, è necessario registrarla. Utilizzare la funzione RegisterClassEx e passare la struttura della classe della finestra come argomento.

        if (!RegisterClassEx(&wcex))
        {
            MessageBox(NULL,
                _T("Call to RegisterClassEx failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
  3. A questo punto è possibile creare una finestra. Utilizzare la funzione 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;
    }
    

    Questa funzione restituisce un HWND che rappresenta un handle per una finestra. Per ulteriori informazioni, vedere Tipi di dati Windows.

  4. Utilizzare il codice seguente per visualizzare la finestra.

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

    Al momento nella finestra non sono visualizzati molti elementi in quanto la funzione WndProc non è ancora stata implementata.

  5. Aggiungere un ciclo di messaggi per rimanere in attesa dei messaggi inviati dal sistema operativo. Quando l'applicazione riceve un messaggio, questo ciclo lo invia alla funzione WndProc affinché venga gestito. Il ciclo di messaggi è simile al codice seguente.

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

    Per ulteriori informazioni sulle strutture e le funzioni utilizzate nel ciclo di messaggi, vedere MSG, GetMessage, TranslateMessage e DispatchMessage.

    A questo punto, la funzione WinMain dovrebbe essere simile al codice seguente.

    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;
    }
    

Per aggiungere funzionalità alla funzione WndProc

  1. Per abilitare la funzione WndProc per la gestione dei messaggi ricevuti dall'applicazione, implementare un'istruzione switch.

    Il primo messaggio da gestire è WM_PAINT. L'applicazione riceve questo messaggio quando è necessario aggiornare parte della finestra visualizzata. (Quando la finestra viene visualizzata per la prima volta deve essere interamente aggiornata.

    Per gestire un messaggio WM_PAINT, chiamare innanzitutto BeginPaint, quindi gestire la logica per disporre il testo, i pulsanti e altri controlli nella finestra, quindi chiamare EndPaint. Per questa applicazione, la logica tra la chiamata iniziale e la chiamata finale consiste nella visualizzazione della stringa "Hello, World!" nella finestra. Nel codice seguente notare che la funzione TextOut viene utilizzata per visualizzare la stringa.

    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. Un'applicazione gestisce in genere molti altri messaggi, ad esempio WM_CREATE e WM_DESTROY. Nel codice seguente viene illustrata una funzione WndProc di base, ma completa.

    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;
    }
    

Esempio

Per compilare questo esempio

  1. Creare un progetto basato su Win-32 come illustrato in "Per creare un progetto basato su Win32" più indietro in questa procedura dettagliata.

  2. Copiare il codice che segue questi passaggi e incollarlo nel file di origine GT_HelloWorldWin32.cpp.

  3. Scegliere Compila soluzione dal menu Compila.

  4. Per eseguire l'applicazione, premere F5. Una finestra che contiene il testo "Hello World!" viene visualizzata nell'angolo superiore sinistro dello schermo.

Codice

// 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;
}

Passaggi successivi

Precedente: Creazione di applicazioni Windows (C++) | Successivo: Creazione di un'applicazione Windows Form con .NET Framework (C++)

Vedere anche

Attività

Creazione di applicazioni Windows (C++)

Cronologia delle modifiche

Data

Cronologia

Motivo

Dicembre 2010

Dichiarata l'omissione di alcune istruzioni di codice altrimenti necessarie in modo da poter spiegare più chiaramente altre parti del codice.

Commenti e suggerimenti dei clienti.