Пошаговое руководство. Создание традиционного классического приложения Windows (C++)

В этом пошаговом руководстве показано, как создать традиционное классическое приложение Windows в Visual Studio. Приложение, которое вы создаете, использует API Windows для отображения "Hello, Windows desktop!" в окне. Код, который вы разрабатываете в этом пошаговом руководстве, можно использовать в качестве шаблона для создания классических приложений Windows.

API Windows (также известный как API Win32, КЛАССИЧЕСКИЙ API Windows и Классический API Windows) — это платформа на основе языка C для создания приложений Windows. Он использовался для создания приложений Windows на протяжении десятилетий. Более сложные и простые платформы программ были созданы на основе API Windows. Например, MFC, ATL, платформы .NET. Даже самый современный код среда выполнения Windows для приложений UWP и Store, написанных в C++/WinRT, использует API Windows в нижней части. Дополнительные сведения об API Windows см. в разделе "Индекс API Windows".

Внимание

В разделе "Сборка кода " в конце этого документа показан полный код. В этом пошаговом руководстве рассматриваются различные фрагменты кода, которые входят в приложение Windows, но вы не будете кодировать по мере использования, так как некоторые сведения опущены в фрагментах кода, чтобы сосредоточиться на наиболее важных частях. Вы можете скопировать полный код и вставить его в проект в конце.

Необходимые компоненты

  • Компьютер под управлением Microsoft Windows 7 или более поздних версий. Мы рекомендуем Windows 11 или более поздней версии для оптимальной разработки.

  • копия Visual Studio. Сведения о скачивании и установке Visual Studio см. в этой статье. Когда вы запускаете установщик, убедитесь, что установлена рабочая нагрузка Разработка классических приложений на C++. Не беспокойтесь, если вы не установили эту рабочую нагрузку при установке Visual Studio. Вы можете снова запустить установщик и установить ее сейчас.

    Снимок экрана: разработка классических приложений с помощью рабочей нагрузки C++ в Установщике Visual Studio, которая говорит: создание классических приложений на основе Windows с помощью набора инструментов Visual C++

  • Базовое понимание использования интегрированной среды разработки Visual Studio. Если вы уже использовали классические приложения для Windows, вы, вероятно, справитесь. Общие сведения см. в обзоре возможностей интегрированной среды разработки Visual Studio.

  • Основные навыки владения языком C++. Не волнуйтесь, мы не будем делать ничего сложного.

Создание классического проекта Windows

Выполните следующие действия, чтобы создать первый классический проект Windows. Запишите в начале этого пошагового руководства полный код доступен в разделе "Сборка кода" в конце пошагового руководства. Следуйте инструкциям по созданию проекта, но удерживайте вставку следующих разделов кода до конца, когда будет представлен полный код приложения. Некоторые сведения опущены в фрагментах кода, чтобы сосредоточиться на наиболее важных частях. Вы можете скопировать полный код и вставить его в проект в конце.

Чтобы упростить объяснение. Чтобы ознакомиться с документацией по предпочтительной версии Visual Studio, используйте селектор Версия. Он расположен в верхней части оглавление на этой странице.

Создание классического проекта Windows в Visual Studio

  1. В главном меню выберите Файл >Создать >Проект, чтобы открыть диалоговое окно Создание проекта.

  2. В верхней части диалогового окна задайте для языка C++, установите для платформы значение "Платформа" в Windows и задайте для типа Project значениеDesktop.

  3. Из отфильтрованного списка типов проектов выберите мастер рабочего стола Windows и нажмите кнопку "Далее". На следующей странице введите имя проекта, например DesktopApp.

  4. Нажмите кнопку Создать, чтобы создать проект.

  5. Откроется диалоговое окно "Проект рабочего стола Windows". В раскрывающемся списке "Тип приложения" выберите классическое приложение (.exe). Так как мы делаем приложение Windows, выбор консольного приложения приводит к созданию проекта, который не будет строиться с учетом кода, который мы будем использовать. Затем в разделе "Дополнительные параметры" выберите "Пустой проект". Нажмите кнопку ОК, чтобы создать проект.

  6. В Обозреватель решений щелкните правой кнопкой мыши проект DesktopApp, выберите "Добавить" и выберите "Создать элемент".

    Анимация, показывающая добавление нового элемента в Project DesktopApp в Visual Studio 2019.

    Анимация показывает правой кнопкой мыши имя проекта в Обозреватель решений, выбрав "Добавить" в появившемся меню и выбрав "Создать элемент".

  7. В диалоговом окне Добавление нового элемента выберите Файл C++ (.cpp). В поле "Имя" введите имя файла, например HelloWindowsDesktop.cpp. Нажмите кнопку Добавить.

    Снимок экрана: диалоговое окно

Теперь проект создается, и исходный файл открывается в редакторе.

Создание классического проекта Windows в Visual Studio 2017

  1. В меню Файл выберите команду Создать, а затем пункт Проект.

  2. В диалоговом окне "Создать проект" в левой области разверните узел "Установленный>Visual C++", а затем выберите "Рабочий стол Windows". В средней области выберите мастер рабочего стола Windows.

    В поле "Имя" введите имя проекта, например DesktopApp. Выберите OK.

    Снимок экрана: диалоговое окно

  3. В диалоговом окне "Классический проект Windows" в разделе "Тип приложения" выберите приложение Windows (.exe). В поле Дополнительные параметрывыберите Пустой проект. Убедитесь, что предварительно скомпилированные заголовки не выбраны. Нажмите кнопку ОК, чтобы создать проект.

  4. В Обозреватель решений щелкните правой кнопкой мыши проект DesktopApp, выберите "Добавить" и выберите "Создать элемент".

    Анимация, показывающая добавление нового элемента в Project DesktopApp в Visual Studio 2017.

    Анимация показывает правой кнопкой мыши имя проекта в Обозреватель решений, выбрав "Добавить" в появившемся меню, а затем выберите новый элемент.

  5. В диалоговом окне Добавление нового элемента выберите Файл C++ (.cpp). В поле "Имя" введите имя файла, например HelloWindowsDesktop.cpp. Нажмите кнопку Добавить.

    Снимок экрана: диалоговое окно

Теперь проект создается, и исходный файл открывается в редакторе.

Создание классического проекта Windows в Visual Studio 2015

  1. В меню Файл выберите команду Создать, а затем пункт Проект.

  2. В диалоговом окне "Создать проект" в левой области разверните узел "Установленные>шаблоны>Visual C++", а затем выберите Win32. В средней области выберите шаблон Проект Win32.

    В поле "Имя" введите имя проекта, например DesktopApp. Выберите OK.

    Снимок экрана: диалоговое окно

  3. На странице "Обзор" мастера приложений Win32 нажмите кнопку "Далее".

    Страница обзора мастера создания DesktopApp в Win32 Application Wizard.

  4. На странице "Приложение Параметры" в разделе "Тип приложения" выберите приложение Windows. В разделе "Дополнительные параметры" не проверка заголовок предварительной компиляции, а затем выберите "Пустой проект". Чтобы создать проект, нажмите кнопку Готово.

  5. В Обозреватель решений щелкните правой кнопкой мыши проект DesktopApp, выберите "Добавить" и выберите "Создать элемент".

    Анимация, показывающая добавление нового элемента в Project DesktopApp в Visual Studio 2015.

    Анимация показывает правой кнопкой мыши имя проекта в Обозреватель решений, выбрав "Добавить" в появившемся меню и выбрав "Создать элемент".

  6. В диалоговом окне Добавление нового элемента выберите Файл C++ (.cpp). В поле "Имя" введите имя файла, например HelloWindowsDesktop.cpp. Нажмите кнопку Добавить.

    Снимок экрана: диалоговое окно

Теперь проект создается, и исходный файл открывается в редакторе.

Код

Далее вы узнаете, как создать код для классического приложения Windows в Visual Studio.

Где код запускается в классическом приложении Windows

  1. Так же, как каждое приложение C и приложение C++ должны иметь main функцию в качестве отправной точки, каждое классическое приложение Windows должно иметь WinMain функцию. WinMain имеет следующий синтаксис:

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

    Сведения о параметрах и возвращаемых значениях этой функции см. в статье "Точка входа WinMain".

    Примечание.

    Что такое все эти дополнительные слова, например WINAPI, или , или CALLBACK, или HINSTANCE_In_? Традиционный API Windows использует макросы typedefs и препроцессоров для абстрагирования некоторых сведений о типах и коде для конкретной платформы, таких как соглашения о вызовах, __declspec объявлениях и pragmas компилятора. В Visual Studio вы можете использовать функцию быстрого сведений IntelliSense, чтобы узнать, что определяют эти типдефы и макросы. Наведите указатель мыши на слово, интересующее вас, или выберите его и нажмите клавиши CTRL K, CTRL++I для небольшого всплывающего окна, содержащего определение. Дополнительные сведения см. в разделе Using IntelliSense. Параметры и типы возвращаемых значений часто используют заметки SAL для перехвата ошибок программирования. Дополнительные сведения см. в статье "Использование заметок SAL для уменьшения дефектов кода C/C++".

  2. Требуются <windows.h>классические программы Windows. Вы также часто увидите #include <tchar.h>. Это упрощает запись приложения, с которыми можно работать charwchar_tлибо. Таким образом, вы вместо этого используете TCHAR макрос в коде, который в конечном счете разрешает, wchar_t если UNICODE символ определен в проекте, в противном случае он разрешается char. Если вы всегда создаете с поддержкой ЮНИКОДа, вам не нужно TCHAR использовать его wchar_t напрямую. Дополнительные сведения см. в разделе "Использование универсальных текстовых сопоставлений". В следующем коде показаны две #include инструкции в верхней части файла.

    #include <windows.h>
    #include <tchar.h>
    
  3. Наряду с функцией, каждое классическое WinMain приложение Windows также должно иметь функцию window-procedure. Эта функция вызывается, WndProcно вы можете присвоить ему любое имя, которое вы хотите в коде. WndProc имеет следующий синтаксис:

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

    В этой функции вы пишете код для обработки сообщений , получаемых приложением из Windows при возникновении событий . Например, если пользователь нажимает кнопку "ОК" в приложении, Windows отправляет вам сообщение. Код записывается в WndProc функцию, которая выполняет все необходимые действия. Он называется обработкой события. Вы обрабатываете только события, относящиеся к приложению.

    Дополнительные сведения см. в разделе Процедуры окна.

Добавление функций в функцию WinMain

  1. WinMain В функции необходимо записать некоторые основные сведения о главном окне. Это можно сделать, заполнив структуру типа WNDCLASSEX. Структура содержит сведения о окне, таком как значок приложения, цвет фона окна, имя, отображаемое в строке заголовка, помимо прочего. Важно отметить, что он содержит указатель функции на процедуру окна, которая обрабатывает сообщения, которые Windows отправляет в приложение. В следующем примере показана типичная WNDCLASSEX структура:

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

    Сведения о полях приведенной выше структуры см. в разделе WNDCLASSEX.

  2. WNDCLASSEX После заполнения структуры зарегистрируйте ее в Windows, чтобы она знала о окне и о том, как отправлять сообщения в него. RegisterClassEx Используйте функцию и передайте структуру класса окна в качестве аргумента. Макрос _T используется, так как мы используем TCHAR тип для обсуждения в Юникоде выше. В следующем коде показано, как зарегистрировать класс окна.

    if (!RegisterClassEx(&wcex))
    {
       MessageBox(NULL,
          _T("Call to RegisterClassEx failed!"),
          _T("Windows Desktop Guided Tour"),
          NULL);
    
       return 1;
    }
    
  3. Затем вы создадите CreateWindowEx окно с помощью функции.

    static TCHAR szWindowClass[] = _T("DesktopApp");
    static TCHAR szTitle[] = _T("Windows Desktop Guided Tour Application");
    
    // 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, 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 = 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;
    }
    

    Эта функция возвращает дескриптор HWNDв окно. Дескриптор несколько похож на указатель. Windows использует его для отслеживания создаваемых окон. Дополнительные сведения см. в разделе Типы данных Windows.

  4. На этом этапе окно было создано, но нам по-прежнему нужно сообщить Windows, чтобы сделать его видимым. Вот что делает этот код:

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

    Отображаемое окно является просто пустым прямоугольником, так как вы еще не реализовали функцию WndProc . Приложение пока не обрабатывает сообщения, которые Windows отправляет в него.

  5. Чтобы обрабатывать сообщения, сначала мы добавим цикл сообщений для прослушивания сообщений, отправляемых Windows. Когда приложение получает сообщение, этот цикл отправляет его в WndProc функцию для обработки. Цикл сообщений похож на следующий код:

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

    Дополнительные сведения о структурах и функциях в цикле сообщений см. в разделе MSG, GetMessageTranslateMessage и DispatchMessage.

    Базовая WinMain функция, которая создает главное окно приложения и прослушивает сообщения, которые Windows отправляет приложение, будут выглядеть следующим образом:

    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, 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 = 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 CreateWindow failed!"),
             _T("Windows Desktop 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;
    }
    

Обработка сообщений в WndProc функции

  1. Для обработки сообщений, получаемых приложением, вы реализуете инструкцию switch в WndProc функции.

    Важное сообщение для обработки .WM_PAINT Приложение получает WM_PAINT сообщение, когда необходимо обновить часть отображаемого окна. Событие может возникать, когда пользователь перемещает окно перед окном и снова перемещает его. Оно получает это сообщение при первом отображении окна, что дает возможность отображать пользовательский интерфейс приложения. Приложение узнает об этих событиях, когда Windows отправляет их. При первом отображении окна все его необходимо обновить.

    Чтобы обработать сообщение, сначала вызовите, а затем обработайте WM_PAINTBeginPaintвсю логику для размещения текста, кнопок и других элементов управления в окне. Затем вызовите EndPaint. Для этого приложения код между BeginPaint() и отображается Hello, Windows desktop! в окне, созданном в WinMain()EndPaint() . В следующем коде TextOut функция отображает текст в указанном расположении в окне.

    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, _tcslen(greeting));
       // End application-specific layout section.
    
       EndPaint(hWnd, &ps);
       break;
    }
    

    В приведенном выше коде используется дескриптор контекста устройства, HDC связанного с клиентской областью окна. Он используется при рисовании в окне для ссылки на ее клиентную область. BeginPaintEndPaint Используйте функции для подготовки и завершения рисования в клиентской области. BeginPaint возвращает дескриптор контекста устройства отображения, используемого для рисования в клиентской области; EndPaint завершает запрос на краску и освобождает контекст устройства.

  2. Приложение обычно обрабатывает множество других сообщений. Например, WM_CREATE отправляется при первом создании окна и WM_DESTROY при закрытии окна. В следующем коде показана базовая, но полная WndProc функция:

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

Сборка кода

Как обещало, полный код рабочего приложения следует.

Сборка примера

  1. Удалите весь код в HelloWindowsDesktop.cpp редактора. Скопируйте этот пример кода и вставьте его в HelloWindowsDesktop.cpp:

    // HelloWindowsDesktop.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("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, 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 = 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 CreateWindow failed!"),
             _T("Windows Desktop 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, 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, _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;
    }
    
  2. В меню Построение выберите Построить решение. Результаты компиляции отображаются в окне вывода в Visual Studio.

    Анимация, показывающая шаги по созданию проекта DesktopApp.

    Анимация показывает нажатие кнопки "Сохранить все", а затем выберите "Сборка > Сборка решения" в главном меню.

  3. Чтобы запустить приложение, нажмите клавишу F5. Должно появиться окно с текстом "Hello, Windows desktop!".

    Снимок экрана: запущенный проект. В нем отображается окно с заголовком классического приложения Windows Desktop. Содержимое окна hello, windows desktop!.

Поздравляем! Вы создали традиционное классическое приложение Windows.

См. также

Типы классических приложений Windows C++