Przewodnik: tworzenie tradycyjnej aplikacji klasycznej systemu Windows (C++)

W tym przewodniku wyjaśniono, jak utworzyć tradycyjną aplikację klasyczną systemu Windows w programie Visual Studio. Utworzona aplikacja używa interfejsu API systemu Windows do wyświetlania Hello, Windows desktop! w oknie. Możesz użyć kodu opracowywanego w tym przewodniku jako wzorca do tworzenia aplikacji klasycznych systemu Windows.

Interfejs API systemu Windows (znany również jako interfejs API Win32, interfejs API pulpitu systemu Windows i klasyczny interfejs API systemu Windows) to oparta na języku C platforma do tworzenia aplikacji systemu Windows. Został on użyty do tworzenia aplikacji systemu Windows od dziesięcioleci. Bardziej zaawansowane i łatwiejsze w programach struktury zostały utworzone na podstawie interfejsu API systemu Windows, na przykład platform MFC, ATL i .NET. Nawet najnowocześniejszy kod środowisko wykonawcze systemu Windows dla aplikacji UWP i aplikacji ze Sklepu, napisany z użyciem C++/WinRT, opiera się na interfejsie API systemu Windows. Aby uzyskać więcej informacji na temat interfejsu API systemu Windows, zobacz Indeks interfejsu API systemu Windows.

Ważne

Bloki kodu w sekcji Kod to fragmenty wyjaśniające, a nie instrukcje do wklejania na bieżąco. Pomijają kod pomocniczy, dzięki czemu każda koncepcja jest łatwiejsza do zobaczenia. Po utworzeniu pustego projektu użyj kompletnego, możliwego do utworzenia źródła w obszarze Kompilowanie kodu.

Wymagania wstępne

  • Microsoft Windows 7 lub nowsze wersje. Zalecamy korzystanie z systemu Windows 11 lub nowszego w celu uzyskania najlepszego środowiska programistycznego.

  • Visual Studio. Aby uzyskać informacje na temat pobierania i instalowania programu Visual Studio, zobacz Instalowanie programu Visual Studio. Po uruchomieniu instalatora upewnij się, że jest zaznaczone pole Programowanie aplikacji klasycznych z obciążeniem języka C++ . Nie martw się, jeśli nie zainstalowałeś tego obciążenia podczas instalacji programu Visual Studio. Instalator można uruchomić ponownie i zainstalować go teraz.

    Zrzut ekranu rozwoju aplikacji na pulpit z obciążeniem C plus plus w Instalatorze programu Visual Studio.

  • Podstawowa wiedza na temat używania środowiska IDE programu Visual Studio. Jeśli wcześniej używasz aplikacji klasycznych systemu Windows, prawdopodobnie możesz nadążyć. Aby zapoznać się z wprowadzeniem, zobacz Przewodnik po funkcji środowiska IDE programu Visual Studio.

  • Znajomość języka C++. Nie martw się, nie robimy nic zbyt skomplikowanego.

Utwórz projekt aplikacji klasycznej systemu Windows

Wykonaj następujące kroki, aby utworzyć pierwszy projekt aplikacji klasycznej dla systemu Windows. Nie wklejaj na bieżąco poszczególnych fragmentów kodu. Po utworzeniu projektu użyj kompletnego źródła w sekcji Kompilowanie kodu.

Aby wyświetlić kroki preferowanej wersji programu Visual Studio, użyj selektora wersji znajdującego się w górnej części spisu treści na tej stronie.

Aby utworzyć projekt pulpitu systemu Windows w programie Visual Studio

  1. W menu głównym wybierz pozycję Plik>nowy>projekt, aby otworzyć okno dialogowe Tworzenie nowego projektu.

  2. W górnej części okna dialogowego ustaw wartość Język na C++, ustaw wartość Platforma na Windows i ustaw wartość Typ projektu na Pulpit.

  3. Z filtrowanej listy typów projektów wybierz pozycję Kreator pulpitu systemu Windows, a następnie wybierz pozycję Dalej. Na następnej stronie wprowadź nazwę projektu, na przykład DesktopApp.

  4. Wybierz przycisk Utwórz, aby utworzyć projekt.

  5. Zostanie wyświetlone okno dialogowe Projekt aplikacji klasycznej systemu Windows. Na liście rozwijanej Typ aplikacji upewnij się, że wybrano pozycję Aplikacja klasyczna (.exe). Ponieważ tworzymy aplikację dla systemu Windows, wybranie opcji Aplikacja konsolowa powoduje utworzenie projektu, którego nie da się skompilować przy kodzie, którego będziemy używać. Następnie w obszarze Dodatkowe opcje wybierz pozycję Pusty projekt. Wybierz przycisk OK , aby utworzyć projekt.

  6. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt DesktopApp, wybierz pozycję Dodaj, a następnie wybierz pozycję Nowy element.

    Animacja przedstawiająca dodawanie nowego elementu do projektu DesktopApp w programie Visual Studio 2019.

    Animacja pokazuje kliknięcie prawym przyciskiem myszy nazwy projektu w Eksplorator rozwiązań, wybranie pozycji Dodaj w wyświetlonym menu, a następnie wybranie pozycji Nowy element.

  7. W oknie dialogowym Dodawanie nowego elementu wybierz pozycję Plik C++ (.cpp). W polu Nazwa wpisz nazwę pliku, na przykład HelloWindowsDesktop.cpp. Wybierz opcję Dodaj.

    Zrzut ekranu przedstawiający okno dialogowe Dodawanie nowego elementu w programie Visual Studio 2019. Wybrano opcję C plus File (.cpp). Pole nazwy jest ustawione na Hello Windows Desktop.cpp.

Projekt jest teraz tworzony i plik źródłowy jest otwierany w edytorze.

Aby utworzyć projekt aplikacji klasycznej systemu Windows w Visual Studio 2017

  1. W menu Plik wybierz pozycję Nowy, a następnie wybierz pozycję Projekt.

  2. W oknie dialogowym Nowy projekt, w lewym okienku rozwiń węzeł Zainstalowane>Visual C++, a następnie wybierz pozycję Pulpit systemu Windows. W środkowym panelu wybierz pozycję Kreator pulpitu systemu Windows.

    W polu Nazwa wpisz nazwę projektu, na przykład DesktopApp. Wybierz pozycję OK.

    Zrzut ekranu przedstawiający okno dialogowe Nowy projekt w programie Visual Studio 2017. Wybrano pozycję Kreator pulpitu systemu Windows. Pole tekstowe nazwy to DesktopApp.

  3. W oknie dialogowym Projekt klasyczny systemu Windows w obszarze Typ aplikacji wybierz pozycję Aplikacja systemu Windows (.exe). W obszarze Dodatkowe opcje wybierz pozycję Pusty projekt. Upewnij się, że nie wybrano prekompilowanego nagłówka . Wybierz przycisk OK , aby utworzyć projekt.

  4. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt DesktopApp, wybierz pozycję Dodaj, a następnie wybierz pozycję Nowy element.

    Animacja przedstawiająca dodawanie nowego elementu do programu DesktopApp Project w programie Visual Studio 2017.

    Animacja pokazuje kliknięcie prawym przyciskiem myszy nazwy projektu w Eksplorator rozwiązań, wybranie pozycji Dodaj w wyświetlonym menu, a następnie wybranie pozycji Nowy element.

  5. W oknie dialogowym Dodawanie nowego elementu wybierz pozycję Plik C++ (.cpp). W polu Nazwa wpisz nazwę pliku, na przykład HelloWindowsDesktop.cpp. Wybierz opcję Dodaj.

    Zrzut ekranu przedstawiający okno dialogowe Dodawanie nowego elementu w programie Visual Studio 2017. Po lewej stronie jest zaznaczona opcja Visual C plus plus plus Plik.

Projekt jest teraz tworzony i plik źródłowy jest otwierany w edytorze.

Aby utworzyć projekt klasyczny dla systemu Windows w programie Visual Studio 2015

  1. W menu Plik wybierz pozycję Nowy, a następnie wybierz pozycję Projekt.

  2. W oknie dialogowym Nowy projekt w okienku po lewej stronie rozwiń węzeł Zainstalowane>szablony>Visual C++, a następnie wybierz pozycję Win32. W środkowym okienku wybierz pozycję Projekt Win32.

    W polu Nazwa wpisz nazwę projektu, na przykład DesktopApp. Wybierz pozycję OK.

    Zrzut ekranu przedstawiający okno dialogowe Nowy projekt w programie Visual Studio 2015 z wyróżnioną opcją Projekt Win32 i wpisanym DesktopApp w polu tekstowym Nazwa.

  3. Na stronie „Przegląd” kreatora aplikacji Win32 wybierz pozycję Dalej.

    Zrzut ekranu przedstawiający okno dialogowe w Visual Studio 2015, które pokazuje stronę Przegląd Kreatora aplikacji Win32.

  4. Na stronie Ustawienia aplikacji w obszarze Typ aplikacji wybierz pozycję Aplikacja systemu Windows. W obszarze Dodatkowe opcje usuń zaznaczenie pozycji Prekompilowany nagłówek, a następnie wybierz pozycję Pusty projekt. Wybierz pozycję Zakończ , aby utworzyć projekt.

  5. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt DesktopApp, wybierz pozycję Dodaj, a następnie wybierz pozycję Nowy element.

    Animacja przedstawiająca dodawanie nowego elementu do projektu DesktopApp w programie Visual Studio 2015.

    Animacja pokazuje kliknięcie prawym przyciskiem myszy nazwy projektu w Eksplorator rozwiązań, wybranie pozycji Dodaj w wyświetlonym menu, a następnie wybranie pozycji Nowy element.

  6. W oknie dialogowym Dodawanie nowego elementu wybierz pozycję Plik C++ (.cpp). W polu Nazwa wpisz nazwę pliku, na przykład HelloWindowsDesktop.cpp. Wybierz opcję Dodaj.

    Zrzut ekranu przedstawiający okno dialogowe Dodawanie nowego elementu w programie Visual Studio 2015 z zaznaczoną opcją Visual C plus plus i wyróżnioną opcją C plus Plik.

Projekt jest teraz tworzony i plik źródłowy jest otwierany w edytorze.

Kod

Następnie dowiedz się, jak utworzyć kod dla aplikacji klasycznej systemu Windows w programie Visual Studio.

Jak program pasuje do siebie

Tradycyjna aplikacja klasyczna Windows używa kilku fragmentów kodu konfiguracji, zanim będzie mógł wyświetlić okno:

Część programu Purpose
Nagłówki i deklaracje udostępnione Podaj typy Windows i zadeklaruj wartości używane przez wiele funkcji.
WinMain Rejestruje klasę okna, tworzy i wyświetla okno oraz uruchamia pętlę komunikatów.
WndProc Przetwarza komunikaty z Windows, takie jak żądania malowania lub zamykania okna.

Poniższe fragmenty koncentrują się na jednej części programu naraz. Kompletne źródło łączy części w odpowiedniej kolejności.

Gdzie kod zaczyna działać w aplikacji klasycznej systemu Windows

  1. Tak jak każda aplikacja w języku C i każda aplikacja w języku C++ musi mieć funkcję main jako punkt wejścia, tak każda aplikacja klasyczna systemu Windows musi mieć funkcję WinMain. WinMain ma następującą składnię.

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

    Aby uzyskać informacje o parametrach i zwracanej wartości tej funkcji, zobacz Punkt wejścia WinMain.

    Uwaga

    Jakie są wszystkie dodatkowe wyrazy, takie jak WINAPI, lub CALLBACK, lub HINSTANCE_In_? Tradycyjny interfejs API systemu Windows w dużym stopniu wykorzystuje typedefy i makra preprocesora, aby ukryć niektóre szczegóły dotyczące typów i kodu zależnego od platformy, takie jak konwencje wywoływania, deklaracje __declspec i dyrektywy pragma kompilatora. W programie Visual Studio możesz użyć funkcji IntelliSense Szybkie informacje, aby sprawdzić, co definiują te aliasy typów i makra. Najedź kursorem myszy na wybrane słowo lub zaznacz je i naciśnij Ctrl+K, CtrlI, aby wyświetlić małe wyskakujące okno zawierające definicję. Aby uzyskać więcej informacji, zobacz Using IntelliSense (Używanie funkcji IntelliSense). Parametry i typy zwracane są często opisywane za pomocą adnotacji SAL, aby ułatwić wykrywanie błędów programistycznych. Aby uzyskać więcej informacji, zobacz Using SAL Annotations to Reduce C/C++ Code Defects (Używanie adnotacji SAL w celu zmniejszenia wad kodu C/C++).

  2. Programy klasyczne systemu Windows wymagają <windows.h>. Często jest również wyświetlany komunikat #include <tchar.h>. Ułatwia to pisanie aplikacji, która może pracować z elementem char lub wchar_t. Sposób jego działania polega na tym, że zamiast tego używasz makra TCHAR w kodzie. TCHAR przyjmuje wartość wchar_t, jeśli w projekcie zdefiniowano symbol UNICODE; w przeciwnym razie przyjmuje wartość char. Jeśli zawsze kompilujesz z włączoną obsługą UNICODE, nie potrzebujesz TCHAR i możesz po prostu bezpośrednio użyć wchar_t. Aby uzyskać więcej informacji, zobacz Using generic-text mappings (Używanie mapowań tekstu ogólnego). Poniższy kod przedstawia te dwie #include instrukcje na początku pliku.

    #include <windows.h>
    #include <tchar.h>
    
  3. Oprócz funkcji WinMain każda aplikacja klasyczna systemu Windows musi również mieć funkcję procedury obsługi okna. Ten przewodnik nazywa funkcję WndProc, ale możesz nadać jej dowolną nazwę w kodzie. WndProc ma następującą składnię.

    LRESULT CALLBACK WndProc(
       _In_ HWND   hWnd,
       _In_ UINT   message,
       _In_ WPARAM wParam,
       _In_ LPARAM lParam
    );
    

    W tej funkcji napiszesz kod do obsługi komunikatów odbieranych przez aplikację z systemu Windows w przypadku wystąpienia zdarzeń . Jeśli na przykład użytkownik wybierze przycisk OK w aplikacji, system Windows wyśle ci komunikat. Piszesz kod wewnątrz funkcji WndProc, która wykonuje odpowiednie zadania. Jest to nazywane obsługą zdarzenia. Obsługujesz tylko zdarzenia, które są istotne dla aplikacji.

    Aby uzyskać więcej informacji, zobacz Procedury okien.

Dodaj funkcjonalność do funkcji WinMain

Przed WinMain zadeklaruj wartości i procedurę obsługi okna używane przez inne części programu. Te deklaracje są wyświetlane przed WinMain w pełnym źródle:

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

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

// Stored instance handle for use in Win32 API calls such as FindResource.
HINSTANCE hInst;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  1. W funkcji WinMain należy zebrać podstawowe informacje na temat swojego okna głównego. Można to zrobić, wypełniając strukturę typu WNDCLASSEX. Struktura zawiera informacje o oknie, takie jak ikona aplikacji, kolor tła okna, nazwa wyświetlana na pasku tytułu, między innymi. Co ważne, zawiera wskaźnik funkcji do procedury okna, która obsługuje komunikaty wysyłane przez system Windows do aplikacji. W poniższym przykładzie przedstawiono typową 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(wcex.hInstance, 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, IDI_APPLICATION);
    

    Aby uzyskać informacje o polach tej struktury, zobacz WNDCLASSEX.

  2. Po wypełnieniu WNDCLASSEX struktury zarejestruj ją w Windows, aby wiedziała o oknie i sposobie wysyłania do niego komunikatów. RegisterClassEx Użyj funkcji i przekaż strukturę klasy okna jako argument. Makro _T sprawia, że literał łańcuchowy odpowiada typowi znaku wybranemu przez TCHAR, jak opisano w poprzednim omówieniu dotyczącym standardu Unicode. Poniższy kod pokazuje, jak zarejestrować klasę okna.

    if (!RegisterClassEx(&wcex))
    {
       MessageBox(NULL,
          _T("Call to RegisterClassEx failed!"),
          _T("Windows Desktop Guided Tour"),
          NULL);
    
       return 1;
    }
    
  3. Utwórz okno przy użyciu CreateWindowEx funkcji .

    // The parameters to CreateWindowEx explained:
    // WS_EX_OVERLAPPEDWINDOW : An optional extended window style.
    // 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, height)
    // NULL: the parent of this window
    // NULL: this application doesn't have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindowEx(
    WS_EX_OVERLAPPEDWINDOW,
       szWindowClass,
       szTitle,
       WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT, CW_USEDEFAULT,
       500, 100,
       NULL,
       NULL,
       hInstance,
       NULL
    );
    if (!hWnd)
    {
       MessageBox(NULL,
          _T("Call to CreateWindowEx failed!"),
          _T("Windows Desktop Guided Tour"),
          NULL);
    
       return 1;
    }
    

    Ta funkcja zwraca HWND, który jest uchwytem do okna. Uchwyt jest czymś w rodzaju wskaźnika. System Windows używa go do śledzenia tworzonych okien. Aby uzyskać więcej informacji, zobacz Typy danych systemu Windows.

  4. W tym momencie zostało utworzone okno, ale nadal musimy poinformować system Windows, aby był widoczny. To właśnie robi ten kod:

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

    Wyświetlone okno jest tylko pustym prostokątem, ponieważ nie zaimplementowano WndProc jeszcze funkcji. Aplikacja nie obsługuje jeszcze komunikatów wysyłanych przez system Windows.

  5. Aby obsłużyć komunikaty, najpierw dodajemy to, co jest nazywane pętlą komunikatów w celu nasłuchiwania komunikatów wysyłanych przez system Windows. Gdy aplikacja otrzyma komunikat, ta pętla przekazuje go do Twojej funkcji WndProc, aby został obsłużony. Pętla komunikatów przypomina następujący kod:

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

    Aby uzyskać więcej informacji na temat struktur i funkcji w pętli komunikatów, zobacz MSG, GetMessageTranslateMessage i DispatchMessage.

    Podstawowa WinMain funkcja, która tworzy główne okno aplikacji i nasłuchuje komunikatów wysyłanych przez system Windows do aplikacji, przypomina następujący kod:

    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(wcex.hInstance, 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, IDI_APPLICATION);
    
       if (!RegisterClassEx(&wcex))
       {
          MessageBox(NULL,
             _T("Call to RegisterClassEx failed!"),
             _T("Windows Desktop Guided Tour"),
             NULL);
    
          return 1;
       }
    
       // Store instance handle in our global variable
       hInst = hInstance;
    
       // The parameters to CreateWindowEx explained:
       // WS_EX_OVERLAPPEDWINDOW : An optional extended window style.
       // 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, height)
       // NULL: the parent of this window
       // NULL: this application doesn't have a menu bar
       // hInstance: the first parameter from WinMain
       // NULL: not used in this application
       HWND hWnd = CreateWindowEx(
          WS_EX_OVERLAPPEDWINDOW,
          szWindowClass,
          szTitle,
          WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, CW_USEDEFAULT,
          500, 100,
          NULL,
          NULL,
          hInstance,
          NULL
       );
    
       if (!hWnd)
       {
          MessageBox(NULL,
             _T("Call to CreateWindowEx failed!"),
             _T("Windows Desktop Guided Tour"),
             NULL);
    
          return 1;
       }
    
       // The parameters to ShowWindow explained:
       // hWnd: the value returned from CreateWindowEx
       // 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;
    }
    

Obsługuj komunikaty w funkcji WndProc

  1. Aby obsłużyć komunikaty odbierane przez aplikację, należy zaimplementować instrukcję switch w WndProc funkcji.

    Ważnym komunikatem, którym należy się zająć, jest WM_PAINT. Aplikacja otrzymuje komunikat, WM_PAINT gdy część wyświetlanego okna musi zostać zaktualizowana. Zdarzenie może wystąpić, gdy użytkownik przenosi okno przed oknem i przenosi go ponownie. Otrzymuje ten komunikat po pierwszym wyświetleniu okna, co daje szansę na wyświetlenie interfejsu użytkownika aplikacji. Aplikacja dowie się o tych zdarzeniach, gdy system Windows je wyśle. Po pierwszym wyświetleniu okna należy zaktualizować wszystko.

    Aby obsłużyć komunikat WM_PAINT, najpierw wywołaj BeginPaint, a następnie zaimplementuj całą logikę odpowiadającą za rozmieszczenie tekstu, przycisków i innych kontrolek w oknie. Następnie wywołaj EndPaint. W tej aplikacji kod między BeginPaint() a EndPaint() wyświetla Hello, Windows desktop! w oknie utworzonym w WinMain(). W poniższym kodzie TextOut funkcja wyświetla tekst w określonej lokalizacji w oknie.

    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR greeting[] = _T("Hello, Windows desktop!");
    
    switch (message)
    {
    case WM_PAINT:
       hdc = BeginPaint(hWnd, &ps);
    
       // Here your application is laid out.
       // For this introduction, we just print out "Hello, Windows desktop!"
       // in the top left corner.
       TextOut(hdc,
          5, 5,
          greeting, static_cast<int>(_tcslen(greeting))); // TextOut expects an int here but _tcslen returns a size_t. Thus the cast.
       // End application-specific layout section.
    
       EndPaint(hWnd, &ps);
       break;
    }
    

    W poprzednim kodzie HDC jest dojściem do kontekstu urządzenia skojarzonego z obszarem klienta okna. Podczas rysowania w oknie użyj tego uchwytu, aby odwołać się do obszaru klienta. Użyj funkcji BeginPaint i EndPaint, aby przygotować i wykonać rysunek w obszarze klienckim. BeginPaint Zwraca uchwyt do kontekstu urządzenia wyświetlania używanego do rysowania w obszarze klienta; EndPaint kończy żądanie malowania i zwalnia kontekst urządzenia.

  2. Aplikacja zazwyczaj obsługuje wiele innych komunikatów. Na przykład WM_CREATE jest wysyłany po pierwszym utworzeniu okna i WM_DESTROY zamknięciu okna. Poniższy kod przedstawia podstawową, ale kompletną WndProc funkcję:

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
       PAINTSTRUCT ps;
       HDC hdc;
       TCHAR greeting[] = _T("Hello, Windows desktop!");
    
       switch (message)
       {
       case WM_PAINT:
          hdc = BeginPaint(hWnd, &ps);
    
          // Here your application is laid out.
          // For this introduction, we just print out "Hello, Windows desktop!"
          // in the top left corner.
          TextOut(hdc,
             5, 5,
             greeting, static_cast<int>(_tcslen(greeting))); // TextOut expects an int here but _tcslen returns a size_t. Thus the cast.
          // 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;
    }
    

Skompiluj kod

Zgodnie z obietnicą następuje kompletny kod dla działającej aplikacji.

Aby skompilować ten przykład

  1. Usuń cały kod w HelloWindowsDesktop.cpp edytorze. Skopiuj ten przykładowy kod i wklej go do pliku HelloWindowsDesktop.cpp:

    // HelloWindowsDesktop.cpp
    // compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c
    
    #include <windows.h>
    #include <tchar.h>
    
    // Global variables
    
    // The main window class name.
    static TCHAR szWindowClass[] = _T("DesktopApp");
    
    // The string that appears in the application's title bar.
    static TCHAR szTitle[] = _T("Windows Desktop Guided Tour Application");
    
    // Stored instance handle for use in Win32 API calls such as FindResource.
    HINSTANCE hInst;
    
    // Forward declarations of functions included in this code module:
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(
       _In_ HINSTANCE hInstance,
       _In_opt_ HINSTANCE hPrevInstance,
       _In_ LPSTR     lpCmdLine,
       _In_ 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(wcex.hInstance, 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, IDI_APPLICATION);
    
       if (!RegisterClassEx(&wcex))
       {
          MessageBox(NULL,
             _T("Call to RegisterClassEx failed!"),
             _T("Windows Desktop Guided Tour"),
             NULL);
    
          return 1;
       }
    
       // Store instance handle in our global variable
       hInst = hInstance;
    
       // The parameters to CreateWindowEx explained:
       // WS_EX_OVERLAPPEDWINDOW : An optional extended window style.
       // 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, height)
       // NULL: the parent of this window
       // NULL: this application doesn't have a menu bar
       // hInstance: the first parameter from WinMain
       // NULL: not used in this application
       HWND hWnd = CreateWindowEx(
          WS_EX_OVERLAPPEDWINDOW,
          szWindowClass,
          szTitle,
          WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, CW_USEDEFAULT,
          500, 100,
          NULL,
          NULL,
          hInstance,
          NULL
       );
    
       if (!hWnd)
       {
          MessageBox(NULL,
             _T("Call to CreateWindowEx failed!"),
             _T("Windows Desktop Guided Tour"),
             NULL);
    
          return 1;
       }
    
       // The parameters to ShowWindow explained:
       // hWnd: the value returned from CreateWindowEx
       // 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, Windows desktop!");
    
       switch (message)
       {
       case WM_PAINT:
          hdc = BeginPaint(hWnd, &ps);
    
          // Here your application is laid out.
          // For this introduction, we just print out "Hello, Windows desktop!"
          // in the top left corner.
          TextOut(hdc,
             5, 5,
             greeting, static_cast<int>(_tcslen(greeting))); // TextOut expects an int here but _tcslen returns a size_t. Thus the cast.
          // 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;
    }
    
  2. W menu Kompilacja wybierz pozycję Kompiluj rozwiązanie. Wyniki kompilacji są wyświetlane w oknie Dane wyjściowe w programie Visual Studio.

    Animacja przedstawiająca kroki kompilowania projektu DesktopApp.

    Animacja pokazuje kliknięcie przycisku Zapisz wszystko, a następnie wybranie pozycji Kompiluj > Rozwiązanie kompilacji z menu głównego.

  3. Aby uruchomić aplikację, naciśnij F5. Powinno zostać wyświetlone okno z tekstem Hello, Windows desktop! .

    Zrzut ekranu przedstawiający okno z tytułem Aplikacja Przewodnika po Pulpicie Windows. Zawartość okna to Witaj, pulpicie Windows!.

Gratulacje! Utworzyłeś tradycyjną aplikację klasyczną dla systemu Windows.

Zobacz też