Sdílet prostřednictvím


Erstellen von Win32-Anwendungen (C++)

Aktualisiert: November 2007

Die Win32-API (auch als Windows-API bekannt) ist ein seit Windows 1.0 eingesetztes C-basiertes Framework zum Erstellen von Windows-Anwendungen. Eine ausführliche Dokumentation für diese API finden Sie unter Windows-API.

In diesem Verfahren erstellen Sie eine einfache Win32-Anwendung, die in einem Fenster "Hello, World!" anzeigt. Die Verfahrensschritte sind für alle Win32-Anwendungen identisch. Nach Abschluss dieses Verfahrens können Sie den darin erstellten Code als Skelett für die Erstellung weiterer Win32-Anwendungen verwenden.

Vorbereitungsmaßnahmen

In diesem Thema wird davon ausgegangen, dass Sie die Grundlagen der Programmiersprache C++ beherrschen. Wenn Sie gerade die ersten Schritte beim Erlernen von C++ machen, empfehlen wir "C++ Beginner's Guide" von Herb Schildt, online verfügbar unter https://go.microsoft.com/fwlink/?LinkId=115303.

Link zu Video Unter Video How to: Creating Win32 Applications (C++) finden Sie eine Videodemonstration.

So erstellen Sie ein neues Win32-Projekt

  1. Klicken Sie im Menü Datei zuerst auf Neu und dann auf Projekt....

  2. Wählen Sie im Bereich Projekttypen im Knoten Visual C++ die Option Win32 und anschließend im Bereich Vorlagen die Option Win32-Projekt aus.

    Geben Sie einen Namen für das Projekt ein, z. B. win32app. Sie können den Standardspeicherort akzeptieren, einen Speicherort eingeben oder einen Speicherort für das Projekt suchen.

  3. Wählen Sie im Win32-Anwendungs-Assistenten die Option Weiter aus.

  4. Wählen Sie im Win32-Anwendungs-Assistenten unter Anwendungstyp die Option Windows-Anwendung aus. Wählen Sie unter Zusätzliche Optionen die Option Leeres Projekt aus. Lassen Sie die übrigen Optionen unverändert. Klicken Sie auf Fertig stellen, um das Projekt zu erstellen.

  5. Fügen Sie dem Projekt eine C++-Datei hinzu, indem Sie im Menü Projekt die Option Neues Element hinzufügen auswählen Klicken Sie im Dialogfeld Neues Element hinzufügen auf C++-Datei (.cpp). Geben Sie einen Namen für die Datei ein, z. B. GT_HelloWorldWin32.cpp, und klicken Sie auf Hinzufügen.

So starten Sie eine Win32-Anwendung

  1. Wie Sie wissen, muss jede C- und C++-Anwendung über eine main-Funktion verfügen. Diese Funktion ist der Ausgangspunkt für die Anwendung. Auf ähnliche Weise muss in einer Win32-Anwendung jede Anwendung über eine WinMain-Funktion verfügen. Die Syntax für WinMain lautet wie folgt:

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

    Eine Erläuterung der Parameter und des Rückgabewerts dieser Funktion finden Sie unter WinMain Function.

  2. Neben WinMain muss jede Win32-Anwendung eine zweite Funktion haben, die normalerweise WndProc genannt wird (was für Fensterprozedur steht). Die Syntax für WndProc lautet wie folgt:

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

    Der Zweck dieser Funktion besteht darin, Meldungen zu behandeln, die die Anwendung vom Betriebssystem empfängt. Wann empfängt die Anwendung Meldungen vom Betriebssystem? Die ganze Zeit! Stellen Sie sich z. B. vor, dass Sie ein Dialogfeld mit der Schaltfläche OK erstellt haben. Wenn der Benutzer auf diese Schaltfläche klickt, sendet das Betriebssystem der Anwendung eine Meldung mit der Information, dass ein Benutzer auf diese Schaltfläche geklickt hat. Die WndProc-Funktion ist dafür zuständig, auf dieses Ereignis zu reagieren. Im Beispiel könnte die entsprechende Antwort sein, das Dialogfeld zu schließen.

    Weitere Informationen finden Sie unter Window Procedures.

So fügen Sie WinMain Funktionalität hinzu

  1. Erstellen Sie zunächst in der WinMain-Funktion eine Fensterklassenstruktur vom Typ WNDCLASSEX. Diese Struktur enthält Informationen über das Fenster, z. B. das Anwendungssymbol, die Hintergrundfarbe des Fensters, den Namen für die Anzeige in der Titelleiste, den Namen der Fensterprozedurfunktion usw. Nachfolgend eine typische WNDCLASSEX-Struktur:

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

    Eine Erläuterung der Felder dieser Struktur finden Sie unter WNDCLASSEX.

  2. Nachdem Sie nun die Fensterklasse erstellt haben, müssen Sie sie registrieren. Verwenden Sie die RegisterClassEx-Funktion, und übergeben Sie die Fensterklassenstruktur als Argument:

        if (!RegisterClassEx(&wcex))
        {
            MessageBox(NULL,
                _T("Call to RegisterClassEx failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
  3. Nachdem Sie die Klasse registriert haben, ist es an der Zeit, ein Fenster zu erstellen. Verwenden Sie die CreateWindow-Funktion wie folgt:

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

    Diese Funktion gibt einen HWND zurück, der ein Handle für ein Fenster ist. Weitere Informationen finden Sie unter Windows Data Types.

  4. Nachdem Sie das Fenster erstellt haben, können Sie es mit dem folgenden Code auf dem Bildschirm anzeigen:

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

    Bis jetzt zeigt dieses Fenster nicht viel an, da die WndProc-Funktion noch nicht implementiert wurde.

  5. Der letzte Schritt von WinMain ist die Nachrichtenschleife. Der Zweck dieser Schleife besteht in der Überwachung von Meldungen, die das Betriebssystem sendet. Wenn die Anwendung eine Meldung empfängt, wird die Meldung zur Behandlung an die WndProc-Funktion weitergeleitet. Die Nachrichtenschleife ähnelt diesem Code:

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

    Weitere Informationen über die in der Nachrichtenschleife verwendeten Strukturen und Funktionen finden Sie unter MSG, GetMessage, TranslateMessage und DispatchMessage.

  6. Die Schritte, die Sie gerade ausgeführt haben, sind den meisten Win32-Anwendungen gemeinsam. An diesem Punkt sollte die WinMain-Funktion dem folgenden Code ähneln:

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

So fügen Sie WndProc Funktionalität hinzu

  1. Der Zweck der WndProc-Funktion besteht darin, Meldungen zu behandeln, die die Anwendung empfängt. Dies wird normalerweise mit einer Schalterfunktion implementiert.

    Als erste Meldung wird die WM_PAINT-Meldung behandelt. Die Anwendung empfängt diese Meldung, wenn ein Teil des Fensters der Anwendung aktualisiert werden muss. Bei der ersten Erstellung eines Fensters muss das gesamte Fenster aktualisiert werden, was mit der Übergabe dieser Meldung angegeben wird.

    Wenn Sie eine WM_PAINT-Meldung behandeln, sollten Sie als Erstes BeginPaint und zum Abschluss EndPaint aufrufen. Innerhalb dieser beiden Funktionsaufrufe behandeln Sie die gesamte Logik für das Layout des Texts, der Schaltflächen und weiterer Steuerelemente für das Fenster. Für diese Anwendung wird die Zeichenfolge "Hello, World!" im Fenster angezeigt. Um Text anzuzeigen, verwenden Sie wie hier dargestellt die TextOut-Funktion:

    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. Die Anwendung behandelt normalerweise viele weitere Meldungen, z. B. WM_CREATE und WM_DESTROY. Nachfolgend eine einfache, aber vollständige WndProc-Funktion:

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

Beispiel

Beschreibung

Nachdem Sie alle Schritte ausgeführt hatten, sollte Ihr Code dem folgenden Code ähneln. Um die Anwendung zu erstellen, wählen Sie im Menü Erstellen die Option Projektmappe erstellen aus. Wenn die Anwendung fehlerfrei kompiliert wird, können Sie sie durch Drücken von F5 ausführen. In der linken oberen Ecke des Bildschirms wird ein einfaches Fenster mit dem Text "Hello, World!" angezeigt.

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

Nächste Schritte

Zurück:Erstellen von Windows-Anwendungen (C++) | Weiter:Erstellen einer Windows Forms-Anwendung mit .NET Framework (C++)

Siehe auch

Aufgaben

Erstellen von Windows-Anwendungen (C++)