Condividi tramite


Creazione di applicazioni Win32 (C++)

Aggiornamento: novembre 2007

L'API Win32 (nota anche come API Windows) è un framework basato sul linguaggio C per la creazione di applicazioni Windows, disponibile a partire da Windows 1.0. La documentazione completa può essere consultata nella sezione API Windows.

In questa procedura viene creata una semplice applicazione Win32 in cui viene visualizzato in una finestra "Hello, World!". I passaggi sono identici per tutte le applicazioni Win32. Dopo aver completato la procedura, sarà possibile utilizzare il codice creato come scheletro per la creazione di qualsiasi altra applicazione Win32.

Prerequisiti

In questo argomento si presuppone la conoscenza delle nozioni di base del linguaggio C++. Chi sta iniziando ad apprendere le prime nozioni di C++ troverà particolarmente utile il testo "C++ Beginner's Guide" scritto da Herb Schildt, disponibile in linea all'indirizzo https://go.microsoft.com/fwlink/?LinkId=115303 (informazioni in lingua inglese).

Collegamento a video Per una dimostrazione video, vedere Procedura relativa a contenuti video: creazione di applicazioni Win32 (C++) (informazioni in lingua inglese).

Per creare un nuovo progetto Win32

  1. Scegliere Nuovo dal menu File e quindi Progetto....

  2. Nel riquadro Tipi progetto selezionare Win32 nel nodo Visual C++, quindi selezionare Progetto Win32 nel riquadro Modelli.

    Digitare un nome per il progetto, ad esempio win32app. È possibile accettare il percorso predefinito, digitarne uno o spostarsi in una directory in cui si desidera salvare il progetto.

  3. Nella Creazione guidata applicazione Win32 selezionare Avanti.

  4. Nella Creazione guidata applicazione Win32, in Tipo di applicazione, selezionare Applicazione Windows. In Opzioni aggiuntive selezionare Progetto vuoto. Non modificare le altre opzioni. Scegliere Fine per creare il progetto.

  5. Per aggiungere un file C++ al progetto, scegliere Aggiungi nuovo elemento... dal menu Progetto. Nella finestra di dialogo Aggiungi nuovo elemento scegliere File di C++ (.cpp). Digitare un nome per il file, ad esempio GT_HelloWorldWin32.cpp, e fare clic su Aggiungi.

Per avviare un'applicazione Win32

  1. Come descritto in precedenza, un'applicazione C e C++ deve avere una funzione main. Tale funzione rappresenta il punto di partenza. Analogamente, in un'applicazione Win32, ogni applicazione deve avere una funzione WinMain. La sintassi per WinMain è la seguente:

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

    Per una spiegazione dei parametri e del valore restituito della funzione, vedere Funzione WinMain.

  2. Oltre a WinMain, ogni applicazione Win32 deve avere anche una seconda funzione, chiamata generalmente WndProc, che significa ruotine della finestra. La sintassi per WndProc è la seguente:

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

    Lo scopo di questa funzione è di gestire qualsiasi messaggio che l'applicazione riceve dal del sistema operativo. L'applicazione riceve messaggi dal sistema operativo in qualsiasi momento. Si immagini ad esempio,di aver creato una finestra di dialogo che includa un pulsante OK. Quando l'utente fa clic sul pulsante, il sistema operativo invia un messaggio all'applicazione che indica l'esecuzione di questa operazione. La funzione WndProc è responsabile della risposta all'evento. Nell'esempio appena descritto la risposta appropriata può essere la chiusura della finestra di dialogo.

    Per ulteriori informazioni, vedere Routine della finestra.

Per aggiungere funzionalità a WinMain

  1. Innanzitutto, creare all'interno della funzione WinMain 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. Di seguito viene indicata 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 una spiegazione dei 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. Dopo aver registrato la classe, è necessario creare una finestra. Utilizzare la funzione CreateWindow nel modo seguente:

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

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

  4. Dopo aver creato la finestra, è possibile visualizzarla sullo schermo utilizzando il codice seguente:

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

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

  5. Il passaggio finale di WinMain è il ciclo di messaggi. Lo scopo del ciclo è di ascoltare i messaggi inviati dal sistema operativo. Quando l'applicazione riceve un messaggio, esso viene inviato alla funzione WndProc per la gestione. Il ciclo di messaggi è simile a quello riportato di seguito:

        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.

  6. I passaggi appena completati sono comuni alla maggior parte delle applicazioni Win32. A questo punto la funzione WinMain dovrebbe essere simile a quella riportata di seguito:

    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à a WndProc

  1. Lo scopo della funzione WndProc è di gestire i messaggi ricevuti dall'applicazione. L'implementazione in genere avviene utilizzando una funzione switch.

    Il primo messaggio da gestire è WM_PAINT. L'applicazione riceve questo messaggio quando è necessario aggiornare una parte della finestra dell'applicazione. Quando una finestra viene creata per la prima volta, è necessario aggiornarla interamente e il messaggio viene passato per indicare l'operazione.

    La prima operazione da eseguire quando si gestisce un messaggio WM_PAINT consiste nel chiamare BeginPaint, l'ultima consiste nel chiamare EndPaint. Tra le due chiamate di funzione viene gestita tutta la logica relativa al layout del testo, dei pulsanti e di altri controlli della finestra. Per questa applicazione, all'interno della finestra viene visualizza la stringa "Hello, World!". Per visualizzare il testo, utilizzare la funzione TextOut, come indicato di seguito:

    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. L'applicazione in genere gestirà molti altri messaggi, ad esempio WM_CREATE e WM_DESTROY. Di seguito viene indicata una funzione WndProc semplice 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

Descrizione

Dopo aver completato tutti i passaggi, il codice dovrebbe essere simile a quello riportato di seguito. Per compilare l'applicazione, scegliere Compila soluzione dal menu Compila. Se l'applicazione viene compilata senza alcun errore, è possibile eseguirla premendo F5. Accanto all'angolo superiore sinistro dello schermo verrà visualizzata una semplice finestra con il testo "Hello, World!".

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

//
//  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++)