Программирование winapi windows 10

Содержание
  1. Пишем на WinAPI с «нуля»
  2. От редакции
  3. Предисловие
  4. First Blood
  5. You have a Message!
  6. CLASSные окна
  7. Our Windows
  8. План полета
  9. Итого
  10. Вызов API для среды выполнения Windows в классических приложениях Call Windows Runtime APIs in desktop apps
  11. Настройка проекта .NET для использования API среды выполнения Windows Modify a .NET project to use Windows Runtime APIs
  12. .NET 5: использование моникера целевой платформы .NET 5: Use the Target Framework Moniker option
  13. Предшествующие версии .NET: установка пакета NuGet Microsoft.Windows.SDK.Contracts Earlier versions of .NET: Install the Microsoft.Windows.SDK.Contracts NuGet package
  14. Настройка проектов, предназначенных для нескольких версий .NET Configure projects that multi-target different versions of .NET
  15. Настройка использования API среды выполнения Windows в проекте Win32 на C++ Modify a C++ Win32 project to use Windows Runtime APIs
  16. Добавление возможностей Windows 10 Add Windows 10 experiences
  17. Поддержка установочных баз Windows XP, Windows Vista, Windows 7 и Windows 8 Support Windows XP, Windows Vista, and Windows 7/8 install bases
  18. Условная компиляция Conditional compilation
  19. Проверки во время выполнения Runtime checks
  20. Связанные примеры Related Samples
  21. Получение ответов на вопросы Find answers to your questions

Пишем на WinAPI с «нуля»


Автор: Яковлев Игорь Сергеевич
Источник: RSDN Magazine #4-2005

Опубликовано: 30.12.2005
Исправлено: 16.03.2006
Версия текста: 1.0

От редакции

Данная статья является введением в программирование на WinAPI. Важно понимать, что она носит скорее информационный характер, чем служит примером кода для реальных приложений. Дело в том, что WinAPI создавался для языка С, и имеет целый ряд недостатков в применении, как-то: невысокая безопасность, большой объем ручного кодирования для решения простейших задач, С-стиль, плохо выглядящий в C++-приложениях. Практически любое средство разработки на языке C++ для Windows включает те или иные высокоуровневые C++-библиотеки (MFC, ATL/WTL для Visual C++, VCL для C++ Builder), значительно упрощающие разработку Windows-приложений, и делающие ее более безопасной.

Предисловие

Эта статья посвящена описанию программирования приложений на «чистом» Win32 API. Она написана в основном для начинающих программистов, пишущих программы на Visual C++ 6 с использованием библиотеки MFC, но я надеюсь, может пригодиться и более опытным людям.

First Blood

После создания нового проекта Win32 Application, в зависимости от выбранных опций, мастер генерирует стартовый код. Из этого кода программисту впоследствии, и придется писать программу. Создавая новый проект Win32 Application, выберите в окне мастера опцию An empty project и добавьте в раздел Source Files новый файл с расширением .cpp.

В этом файле добавьте функцию WinMain вида:

Вот и готова первая программа на WinAPI. Она выводит сообщение, после чего завершает свою работу. Обратите внимание на параметры функции WinMain :

  • HINSTANCE hInstance – дескриптор экземпляра приложения. Этот дескриптор содержит адрес начала кода программы в ее адресном пространстве. Дескриптор hInstance чаще всего требуется функциям, работающим с ресурсами программы.
  • HINSTANCE hPrevInstance – дескриптор предыдущего экземпляра приложения. Этот дескриптор остался от старых версий Windows — скорее всего, вам он никогда не пригодится.
  • LPSTR lpCmdLine – указатель на начало командной строки, введенной при запуске программы.
  • int nCmdShow – это значение содержит желаемый вид окна (например, свернутый или развернутый)

Значение, которое возвращается функцией WinMain (тип int ) – код завершения программы. Принято, что если программа завершила свое выполнение без ошибок, возвращается 0.

Функция WinMain – первая функция, которая выполнятся в программе (ее еще называют «точка входа» или «entry point»). С нее все начинается, и ею (желательно) все должно закончиться.

ПРИМЕЧАНИЕ

Функция WinMain – это первая функция, которую вы можете увидеть и заполнить кодом. На самом деле до этой функции выполняется достаточно много кода из библиотеки C++

You have a Message!

Программисты, незнакомые с программированием на WinAPI, спросят: «Что с этим делать?!», — или: «Где создавать CDialog?». В данном случае ответ прост – нигде! В нашем проекте нет класса CDialog или, предположим, CButton – ведь эта статья посвящена тому, как обойтись без них.

В Windows при каждом событии, произошедшем в системе, отсылается «сообщение Windows» («windows message»). Эти сообщения уведомляют программу о событиях в системе, а программа в свою очередь, может на них реагировать. Сообщения может отсылать не только Windows, но и сами приложения. Это является одним из способов организации связи между процессами в системе. Конечно, программа может отсылать сообщения и самой себе.

СОВЕТ

Сообщение можно отослать функцией SendMessage или ее асинхронным аналогом PostMessage.

Для приема сообщений в программе должен находиться «цикл сообщений» («message loop») который обычно выглядит так:

Функция GetMessage принимает следующие параметры:

  • LPMSG lpMsg – указатель на структуру сообщения, в которую GetMessage вернет результат.
  • HWND hWnd – описатель окна, от которого GetMessage примет сообщение ( NULL означает, что GetMessage принимает сообщения от всех окон, принадлежащих потоку).
  • UINT wMsgFilterMin – наименьший идентификатор сообщения, которое примет GetMessage.
  • UINT wMsgFilterMax – наибольший идентификатор сообщения, которое примет GetMessage (если в значениях параметров wMsgFilterMin и wMsgFilterMax передать 0, функция будет принимать ВСЕ сообщения).

Функция GetMessage не отдает управление программе, пока не придет какое-либо сообщение. Если пришедшее сообщение – WM_QUIT , функция GetMessage вернет 0 . Тогда цикл прервется, и программа завершит свою работу. При любом другом сообщении функция GetMessage возвращает значение больше нуля, и начинатся выполнение тела цикла. При ошибке GetMessage возвращает -1.

СОВЕТ

Сообщение WM_QUIT лучше посылать с помощью специальной функции PostQuitMessage(int iExitCode). Эта функция отошлет сообщение WM_QUIT, а в параметре wParam передаст код завершения программы, указанный в iExitCode.

Функция DispatchMessage должна вызвать «функцию обработки сообщений». В простейшем варианте она выглядит так:

При вызове этой функции ей передаются следующие параметры:

  • HWND hWnd – описатель окна, от которого пришло сообщение.
  • UINT message – идентификатор сообщения.
  • WPARAM wParam и LPARAM lParam – параметры сообщения.

Функция обработки сообщений не обязательно должна иметь имя WndProc . Таких функций в программе может быть несколько, но их прототипы обязательно должны выглядеть так:

При вызове этой функции DispatchMessage передает в параметре message идентификатор сообщения. По этому идентификатору производится выборка и выполняется какое-либо действие ( «реакция на сообщение» ).

В Windows существует очень много сообщений! Писать обработчики для всех сообщений – нереальная задача. Чтобы Windows сама обработала бесполезное для вас сообщение, необходимо вызвать функцию DefWindowProc :

Желательно передавать все необработанные сообщения этой функции, а результат ее выполнения возвращать при выходе из WndProc . Это очень важно, так как от обработки некоторых сообщений Windows ждет возврата конкретных результатов или действий.

Одной функцией обработки сообщений могут пользоваться несколько окон, но для одного окна может существовать только одна функция обработки сообщений! Как же система определяет, какой именно функцией обработки сообщения пользоваться для конкретного окна и где она находится?! За это отвечает «класс окна» («window class»).

CLASSные окна

При создании нового окна ему присваивается «Класс окна» (window class). Класс окна задает оконную функцию, используемую по умолчанию. Кроме этого, класс окна задает другие параметры окна, такие, как стиль, меню окна, цвет рабочей области и т.д. Разные классы окон могут указывать на одну и ту же функцию обработки сообщений. Для создания класса его необходимо зарегистрировать.

Итак, регистрация! За нее отвечает функция RegisterClass . В ее параметре необходимо передать указатель на структуру WNDCLASS . Обычно для заполнения структуры и вызова RegisterClass создают отдельную функцию. Но это — дело вкуса.

Вот простейший пример такой функции:

  • WNDPROC lpfnWndProc – адрес функции обработки сообщений.
  • HINSTANCE hInstance – уже знакомая переменная, описывающая экземпляр.
  • LPCTSTR lpszClassName – имя нового класса.
  • HICON hCursor – описатель курсора мыши.
  • HBRUSH hbrBackground – цвет рабочей области окна.

Функция RegisterClass возвращает уникальный «описатель класса окна» типа ATOM . Если при регистрации класса произошла ошибка, это значение будет равно нулю. Чтобы узнать, что произошло, можно вызвать функцию GetLastError() .

Существует также функция RegisterClassEx. Это аналог функции RegisterClass с возможностью присвоения окнам маленькой иконки. При работе с этой функцией необходимо пользоваться структурой WNDCLASSEX.

ПРИМЕЧАНИЕ

Если вы решились работать с GUI Windows вручную, то пользоваться нужно именно RegisterClassEx, поскольку приложение, не имеющее маленькой иконки, сегодня выглядит в Windows как минимум странно. – прим.ред.

СОВЕТ

Следите, чтобы имя вашего класса не совпадало с именами системных классов (например: button или edit).

ПРИМЕЧАНИЕ

Я описал не всю структуру. Все незаполненные поля, которых нет в примере, сейчас равны нулю. Об их значениях можно узнать из MSDN.

Сообщения от окон, созданных на базе класса, зарегистрированного описанной выше функцией RegMyWindowClass, будут обрабатываться функцией с именем WndProc. Чтобы функция WndProc поняла, от какого именно окна пришло сообщение, ей передается уникальный описатель окна HWND .

Our Windows

На вашем месте у меня возникло бы желание увидеть те самые пресловутые окна, из-за которых столько шума. Окно в Windows создается функцией CreateWindow . Вот ее прототип:

Как видите, у функции множество параметров:

  • LPCTSTR lpClassName – имя класса для создаваемого окна (это имя использовалось при регистрации класса).
  • LPCTSTR lpWindowName – имя окна.
  • DWORD dwStyle – стиль окна.
  • int x – позиция по горизонтали верхнего левого угла окна.
  • int y – позиция по вертикали.
  • int nWidth – ширина окна.
  • int nHeight – высота окна.
  • HWND hWndParent – используется для создания «дочернего окна» («child window»). Сюда передается описатель «родительского окна» («parent window»).
  • HMENU hMenu – описатель меню (если hMenu равно нулю, используется меню класса, указанного в lpClassName ).
  • HINSTANCE hInstance – экземпляр приложения.
  • LPVOID lpParam – указатель на пользовательский параметр окна. Этот указатель со всеми остальными параметрами функции CreateWindow будет занесен в структуру CREATESTRUCT . В сообщениях WM_CREATE или WM_NCCREATE параметр lParam будет содержать указатель на эту структуру.

Функция CreateWindow возвращает уникальный описатель окна HWND . Если функция вернула ноль, значит, во время создания окна произошла ошибка. Какая именно, можно узнать, вызвав функцию GetLastError .

ПРИМЕЧАНИЕ

Существует также функция CreateWindowEx, в которой дополнительно присутствует параметр dwExStyle. С его помощью можно создать окно с дополнительными стилями.

План полета

Итак, сейчас я упрощенно расскажу, что же произойдет, если щелкнуть по окну левой кнопкой мыши.

  1. Пользователь нажимает левую кнопку мыши в то время когда курсор мыши находится над рабочей областью окна.
  2. Windows помещает сообщение WM_LBUTTONDOWN в очередь потока.
  3. Цикл обработки сообщения должен вынуть сообщение с помощью функции GetMessage и передать его на обработку функции DispatchMessage .
  4. Функция DispatchMessage находит окно, которому предназначено сообщение и помещает сообщение в его очередь.
  5. Функция окна обрабатывает сообщение WM_LBUTTONDOWN и возвращает результат.
  6. Тело цикла заканчивается, и управление снова передается функции GetMessage для ожидания новых сообщений.

Итого

WinMain, регистрация класса, цикл сообщений, функция обработки сообщений, создание окна. Как все это связать?! Вот код, который объединяет все написанное выше в одну программу:

Вот, в принципе, и все! Это полноценное приложение на WinAPI.

Программа регистрирует класс, создает окно этого класса и обслуживает сообщение WM_LBUTTONUP (оно приходит по событию отпускания левой кнопки мыши), показывает окно, и после обработки сообщения снова возвращается в цикл сообщений, находящийся в WinMain .

Признаю, что данная статья и программа опускает очень много деталей! Многие вещи были не раскрыты (например, остальные переменные структуры WNDCLASS ). Все это сделано для того, чтобы максимально упростить статью и уменьшить код программы.

Вызов API для среды выполнения Windows в классических приложениях Call Windows Runtime APIs in desktop apps

С помощью API-интерфейсов универсальной платформы Windows (UWP) в классических приложениях вы можете добавить современные возможности, которые привлекут внимание пользователей Windows 10. You can use Universal Windows Platform (UWP) APIs to add modern experiences to your desktop apps that light up for Windows 10 users.

Прежде всего настройте в проекте необходимые ссылки. First, set up your project with the required references. Затем вызовите API среды выполнения Windows из кода приложения, чтобы добавить в него новые возможности Windows 10. Then, call Windows Runtime APIs from your code to add Windows 10 experiences to your desktop app. Вы можете создавать отдельные версии для пользователей Windows 10 либо распространять одинаковые двоичные файлы для всех пользователей независимо от того, с какой версией Windows они работают. You can build separately for Windows 10 users or distribute the same binaries to all users regardless of which version of Windows they run.

Некоторые API среды выполнения Windows поддерживаются только в классических приложениях с идентификатором пакета. Some Windows Runtime APIs are supported only in desktop apps that have package identity. Подробнее см. в разделе Доступные API среды выполнения Windows. For more information, see Available Windows Runtime APIs.

Настройка проекта .NET для использования API среды выполнения Windows Modify a .NET project to use Windows Runtime APIs

Для проектов .NET существует несколько вариантов. There are several options for .NET projects:

  • Начиная с выпуска .NET 5, вы можете добавить моникер целевой платформы (TFM) в файл проекта для получения доступа к API-интерфейсам WinRT. Starting in .NET 5, you can add a Target Framework Moniker (TFM) to your project file to access WinRT APIs. Этот вариант поддерживается в проектах, предназначенных для Windows 10 версии 1809 или более поздней. This option is supported in projects that target Windows 10, version 1809 or later.
  • Для более ранних версий .NET можно установить пакет NuGet Microsoft.Windows.SDK.Contracts , чтобы добавить все необходимые ссылки в проект. For earlier versions of .NET, you can install the Microsoft.Windows.SDK.Contracts NuGet package to add all necessary references to your project. Этот параметр поддерживается в проектах, предназначенных для Windows 10 версии 1803 или более поздней. This option is supported in projects that target Windows 10, version 1803 or later.
  • Если проект предназначен одновременно для .NET 5 (или более поздний выпуск) и более ранних версий, можно настроить файл проекта для использования обоих вариантов. If your project multi-targets .NET 5 (or later) and earlier versions of .NET, you can configure the project file to use both options.

.NET 5: использование моникера целевой платформы .NET 5: Use the Target Framework Moniker option

Этот вариант поддерживают только проекты, использующие .NET 5 или более позднего выпуска и предназначенные для Windows 10 версии 1809 или более позднего выпуска. This option is only supported in projects that use .NET 5 (or a later release) and target Windows 10, version 1809 or a later OS release. Дополнительные сведения об этом сценарии см. в этой записи блога. For more background info about this scenario, see this blog post.

В Visual Studio щелкните правой кнопкой мыши проект в Обозревателе решений и выберите Изменить файл проекта. With your project open in Visual Studio, right-click your project in Solution Explorer and choose Edit Project File. Файл проекта должен выглядеть примерно так. Your project file should look similar to this.

Замените значение элемента TargetFramework одной из следующих строк: Replace the value of the TargetFramework element with one of the following strings:

  • net5.0-windows10.0.17763.0: используйте это значение, если приложение предназначено для Windows 10 версии 1809; net5.0-windows10.0.17763.0: Use this value if your app targets Windows 10, version 1809.
  • net5.0-windows10.0.18362.0: используйте это значение, если приложение предназначено для Windows 10 версии 1903; net5.0-windows10.0.18362.0: Use this value if your app targets Windows 10, version 1903.
  • net5.0-windows10.0.19041.0: используйте это значение, если приложение предназначено для Windows 10 версии 2004. net5.0-windows10.0.19041.0: Use this value if your app targets Windows 10, version 2004.

Например, следующий элемент используется для проекта, предназначенного для Windows 10 версии 2004. For example, the following element is for a project that targets Windows 10, version 2004.

Сохраните изменения и закройте файл проекта. Save your changes and close the project file.

Предшествующие версии .NET: установка пакета NuGet Microsoft.Windows.SDK.Contracts Earlier versions of .NET: Install the Microsoft.Windows.SDK.Contracts NuGet package

Задайте этот параметр, если приложение использует .NET Core 3.x или .NET Framework. Use this option if your app uses .NET Core 3.x or .NET Framework. Этот вариант поддерживается в проектах, предназначенных для Windows 10 версии 1803 или ОС более позднего выпуска. This option is supported in projects that target Windows 10, version 1803 or a later OS release.

Убедитесь, что ссылки на пакеты активны: Make sure package references are enabled:

  1. В Visual Studio выберите элементы Сервис -> Диспетчер пакетов NuGet -> Параметры диспетчера пакетов. In Visual Studio, click Tools -> NuGet Package Manager -> Package Manager Settings.
  2. Убедитесь, что для формата управления пакетами по умолчанию установлено значение PackageReference. Make sure PackageReference is selected for Default package management format.

В Visual Studio щелкните правой кнопкой мыши проект в обозревателе решений и выберите элемент Управление пакетами NuGet. With your project open in Visual Studio, right-click your project in Solution Explorer and choose Manage NuGet Packages.

В окне диспетчера пакетов NuGet выберите вкладку Обзор и найдите Microsoft.Windows.SDK.Contracts . In the NuGet Package Manager window, select the Browse tab and search for Microsoft.Windows.SDK.Contracts .

Когда пакет Microsoft.Windows.SDK.Contracts будет найден, выберите на правой панели диспетчера пакетов NuGet нужную версию пакета в зависимости от версии Windows 10, на которую нужно ориентировать приложение: After the Microsoft.Windows.SDK.Contracts package is found, in the right pane of the NuGet Package Manager window select the Version of the package you want to install based on the version of Windows 10 you want to target:

  • 10.0.19041.xxxx — вариант для Windows 10 версии 2004; 10.0.19041.xxxx: Choose this for Windows 10, version 2004.
  • 10.0.18362.xxxx — вариант для Windows 10 версии 1903; 10.0.18362.xxxx: Choose this for Windows 10, version 1903.
  • 10.0.17763.xxxx — вариант для Windows 10 версии 1809; 10.0.17763.xxxx: Choose this for Windows 10, version 1809.
  • 10.0.17134.xxxx — вариант для Windows 10 версии 1803. 10.0.17134.xxxx: Choose this for Windows 10, version 1803.

Нажмите кнопку Установить. Click Install.

Настройка проектов, предназначенных для нескольких версий .NET Configure projects that multi-target different versions of .NET

Если проект предназначен одновременно для .NET 5 предварительной версии 3 (или более поздней версии) и более ранних версий (включая .NET Core 5.x и .NET Framework), можно настроить в файле проекта использование моникера целевой платформы для автоматического извлечения ссылок на API WinRT для .NET 5 и применять пакет NuGet Microsoft.Windows.SDK.Contracts для более ранних версий. If your project multi-targets .NET 5 (or later) and earlier versions (including .NET Core 3.x and .NET Framework), you can configure the project file to use the Target Framework Moniker to automatically pull in the WinRT API references for .NET 5 and use the Microsoft.Windows.SDK.Contracts NuGet package for earlier versions.

В Visual Studio щелкните правой кнопкой мыши проект в Обозревателе решений и выберите Изменить файл проекта. With your project open in Visual Studio, right-click your project in Solution Explorer and choose Edit Project File. В следующем примере показан файл проекта для приложения, использующего .NET Core 3.1. The following example demonstrates a project file for an app that uses .NET Core 3.1.

В файле замените элемент TargetFramework элементом TargetFrameworks (обратите внимание на множественное число). Replace the TargetFramework element in the file with a TargetFrameworks element (note the plural). В этом элементе укажите моникеры целевой платформы для всех версий .NET, которые вы хотите использовать, разделив их точкой с запятой. In this element, specify the Target Framework Monikers for all the versions of .NET you want to target, separated by semi-colons.

  • Для .NET 5 или более поздней версии используйте один из следующих моникеров целевой платформы: For .NET 5 or later, use one of the following Target Framework Monikers:
    • net5.0-windows10.0.17763.0: используйте это значение, если приложение предназначено для Windows 10 версии 1809; net5.0-windows10.0.17763.0: Use this value if your app targets Windows 10, version 1809.
    • net5.0-windows10.0.18362.0: используйте это значение, если приложение предназначено для Windows 10 версии 1903; net5.0-windows10.0.18362.0: Use this value if your app targets Windows 10, version 1903.
    • net5.0-windows10.0.19041.0: используйте это значение, если приложение предназначено для Windows 10 версии 2004. net5.0-windows10.0.19041.0: Use this value if your app targets Windows 10, version 2004.
  • Для .NET Core 3.x используйте netcoreapp3.0 или netcoreapp3.1. For .NET Core 3.x, use netcoreapp3.0 or netcoreapp3.1.
  • Для .NET Framework используйте net46. For .NET Framework, use net46.

В следующем примере показано, как настроить проект для использования одновременно .NET Core 3.1 и .NET 5 (для Windows 10 версии 2004). The following example demonstrates how to multi-target .NET Core 3.1 and .NET 5 (for Windows 10, version 2004).

После элемента PropertyGroup добавьте элемент PackageReference, включающий условный оператор, который отвечает за установку пакета NuGet Microsoft.Windows.SDK.Contracts для всех версий .NET Core 3.x или .NET Framework, для которых предназначено приложение. After the PropertyGroup element, add a PackageReference element that includes a conditional statement that installs the Microsoft.Windows.SDK.Contracts NuGet package for any versions of .NET Core 3.x or .NET Framework that your app targets. Элемент PackageReference должен быть дочерним по отношению к элементу ItemGroup. The PackageReference element must be a child of an ItemGroup element. В приведенном ниже примере показано, как это сделать для .NET Core 3.1. The following example demonstrates how to do this for .NET Core 3.1.

По завершении файл проекта должен выглядеть примерно так. When you’re done, your project file should look similar to this.

Сохраните изменения и закройте файл проекта. Save your changes and close the project file.

Настройка использования API среды выполнения Windows в проекте Win32 на C++ Modify a C++ Win32 project to use Windows Runtime APIs

Примените C++/WinRT для использования API среды выполнения Windows. Use C++/WinRT to consume Windows Runtime APIs. C++/WinRT — это полностью стандартная проекция языка C++17 для API среды выполнения Windows (WinRT), реализованная как библиотека на основе файлов заголовков и предназначенная для предоставления вам первоклассного доступа к современным интерфейсам API Windows. C++/WinRT is an entirely standard modern C++17 language projection for Windows Runtime (WinRT) APIs, implemented as a header-file-based library, and designed to provide you with first-class access to the modern Windows API.

Чтобы настроить C++/WinRT для проекта, сделайте следующее: To configure your project for C++/WinRT:

  • Для новых проектов можно установить расширение C++/WinRT Visual Studio (VSIX) и использовать один из шаблонов проектов C++/WinRT, входящих в это расширение. For new projects, you can install the C++/WinRT Visual Studio Extension (VSIX) and use one of the C++/WinRT project templates included in that extension.
  • Для существующих проектов можно установить в проект пакет NuGet Microsoft.Windows.CppWinRT. For existing projects, you can install the Microsoft.Windows.CppWinRT NuGet package in the project.

Дополнительные сведения об этом варианте см. в этой статье. For more details about these options, see this article.

Добавление возможностей Windows 10 Add Windows 10 experiences

Теперь все готово для добавления современных видов взаимодействия, которые активируются, когда пользователь запускает ваше приложение в Windows 10. Now you’re ready to add modern experiences that light up when users run your application on Windows 10. Используйте этот процесс разработки. Use this design flow.

Сначала определите, какие возможности нужно добавить First, decide what experiences you want to add

Выбор огромен. There’s lots to choose from. Например, можно упростить оформление покупки с помощью API монетизации либо привлечь внимание к приложению, когда вы можете предложить что-либо интересное, например новую фотографию, добавленную другим пользователем. For example, you can simplify your purchase order flow by using monetization APIs, or direct attention to your application when you have something interesting to share, such as a new picture that another user has posted.

Даже если пользователи не обращают внимания на ваше сообщение или закрывают его, они могут снова увидеть его в центре уведомлений, а затем щелкнуть сообщение, чтобы открыть приложение. Even if users ignore or dismiss your message, they can see it again in the action center, and then click on the message to open your app. Это позволяет увеличить объем взаимодействия с приложением и обеспечивает дополнительное преимущество в виде тесной интеграции вашего приложения с операционной системой. This increases engagement with your application and has the added bonus of making your application appear deeply integrated with the operating system. Мы предложим код для реализации этой возможности чуть позже в этой статье. We’ll show you the code for that experience a bit later in this article.

Дополнительные сведения см. в документации по UWP. Visit the UWP documentation for more ideas.

Выберите путь улучшения: дополнить или расширить Decide whether to enhance or extend

Вам часто будут встречаться термины дополнить и расширить, поэтому сейчас мы поясним, какой именно смысл вкладываем в них. You’ll often hear us use the terms enhance and extend, so we’ll take a moment to explain exactly what each of these terms mean.

Термин дополнить относится к API среды выполнения Windows, которые вы можете вызывать напрямую из классического приложения (независимо от того, применяете ли вы для приложения упаковку в пакет MSIX). We use the term enhance to describe Windows Runtime APIs that you can call directly from your desktop app (whether or not you have chosen to package your application in an MSIX package). При выборе новой возможности Windows 10 определите API-интерфейсы, которые вам необходимы для ее реализации, а затем проверьте, входит ли нужный API в этот список. When you’ve chosen a Windows 10 experience, identify the APIs that you need to create it, and then see if that API appears in this list. Это список API-интерфейсов, которые можно вызывать непосредственно из классического приложения. This is a list of APIs that you can call directly from your desktop app. Если выбранный API не входит в этот список, значит, связанные с этим API функции могут работать только в рамках процесса UWP. If your API does not appear in this list, that’s because the functionality associated with that API can run only within a UWP process. Сюда часто входят API-интерфейсы, которые отображают элементы XAML UWP, например элемент управления картой UWP или запрос безопасности Windows Hello. Often times, these include APIs that render UWP XAML such as a UWP map control or a Windows Hello security prompt.

API, которые отображают XAML UWP, обычно нельзя напрямую вызывать из классического приложений. Но иногда для них доступны альтернативные подходы. Although APIs that render UWP XAML typically cannot be called directly from your desktop, you might be able to use alternative approaches. Если вы хотите разместить элементы управления XAML UWP или другие пользовательские визуальные объекты, попробуйте применить XAML Islands (доступны в Windows 10 с версии 1903) и (или) визуальный уровень (доступен в Windows 10 с версии 1803). If you want to host UWP XAML controls or other custom visual experiences, you can use XAML Islands (starting in Windows 10, version 1903) and the Visual layer (starting in Windows 10, version 1803). Эти возможности можно использовать в упакованных и неупакованных классических приложениях. These features can be used in packaged or unpackaged desktop apps.

Если вы решили упаковать классическое приложение в пакет MSIX, у вас есть возможность расширить это приложение, добавив к нему проект UWP. If you have chosen to package your desktop app in an MSIX package, another option is to extend the application by adding a UWP project to your solution. Проект классического приложения по-прежнему остается точкой входа для вашего приложения. Но проект UWP предоставляет доступ ко всем API-интерфейсам, которые не входят в этот список. The desktop project is still the entry point of your application, but the UWP project gives you access to all of the APIs that do not appear in this list. Классические приложения могут взаимодействовать с процессами UWP с помощью службы приложений. У нас есть множество рекомендаций по настройке этой функции. The desktop app can communicate with the UWP process by using a an app service and we have lots of guidance on how to set that up. Если вы хотите добавить возможность, для которой требуется проект UWP, см. раздел Расширение возможностей с помощью компонентов UWP. If you want to add an experience that requires a UWP project, see Extend with UWP components.

Добавьте ссылки на контракты API Reference API contracts

Если вы можете вызывать API непосредственно из классического приложения, откройте браузер и найдите справочный раздел для этого API-интерфейса. If you can call the API directly from your desktop app, open a browser and search for the reference topic for that API. Под общей информацией об API там представлена таблица с описанием контракта для этого API. Beneath the summary of the API, you’ll find a table that describes the API contract for that API. Пример такой таблицы приведен ниже. Here’s an example of that table:

Если у вас есть классическое приложение на основе .NET, добавьте ссылку на этот контракт API и присвойте свойству Копировать локально этого файла значение False. If you have a .NET-based desktop app, add a reference to that API contract, and then set the Copy Local property of that file to False. Если у вас есть проект на основе C++, добавьте в раздел Дополнительные каталоги включаемых файлов путь к папке, содержащей этот контракт. If you have a C++-based project, add to your Additional Include Directories, a path to the folder that contains this contract.

Вызовите API-интерфейсы для добавления возможности Call the APIs to add your experience

Ниже приведен код для отображения окна уведомлений, которое мы уже видели ранее. Here’s the code that you’d use to show the notification window that we looked at earlier. Эти API-интерфейсы внесены в этот список, а значит, вы можете добавить этот код в классическое приложение и запустить его прямо сейчас. These APIs appear in this list so you can add this code to your desktop app and run it right now.

Поддержка установочных баз Windows XP, Windows Vista, Windows 7 и Windows 8 Support Windows XP, Windows Vista, and Windows 7/8 install bases

Вы можете модернизировать приложение для Windows 10, не создавая новую ветвь и не поддерживая раздельные базы кода. You can modernize your application for Windows 10 without having to create a new branch and maintain separate code bases.

Если вы хотите создать отдельные двоичные файлы для пользователей Windows 10, используйте условную компиляцию. If you want to build separate binaries for Windows 10 users, use conditional compilation. Если вы предпочитаете создать один набор двоичных файлов, которые развертываются для всех пользователей Windows, используйте проверки во время выполнения. If you’d prefer to build one set of binaries that you deploy to all Windows users, use runtime checks.

Давайте вкратце рассмотрим эти варианты. Let’s take a quick look at each option.

Условная компиляция Conditional compilation

Можно вести одну базу кода и компилировать набор двоичных файлов только для пользователей Windows 10. You can keep one code base and compile a set of binaries just for Windows 10 users.

Для этого добавьте новую конфигурацию сборки в проект. First, add a new build configuration to your project.

Создайте константу для этой конфигурации сборки, чтобы определить код, который будет вызывать API среды выполнения Windows. For that build configuration, create a constant that to identify code that calls Windows Runtime APIs.

Для проектов на основе .NET эта константа называется константой условной компиляции. For .NET-based projects, the constant is called a Conditional Compilation Constant.

Для проектов на основе C++ эта константа называется описанием препроцессора. For C++-based projects, the constant is called a Preprocessor Definition.

Добавьте эту константу до всех блоков кода UWP. Add that constant before any block of UWP code.

Компилятор выполнит сборку этого кода, только если соответствующая константа определена в активной конфигурации сборки. The compiler builds that code only if that constant is defined in your active build configuration.

Проверки во время выполнения Runtime checks

Можно скомпилировать один набор двоичных файлов для всех пользователей Windows независимо от того, какую версию Windows они используют. You can compile one set of binaries for all of your Windows users regardless of which version of Windows they run. В этом случае приложение будет обращаться к API среды выполнения Windows, только если пользователь выполняет его как упакованное приложение в среде Windows 10. Your application calls Windows Runtime APIs only if the user is runs your application as a packaged application on Windows 10.

Чтобы добавить в код проверки во время выполнения, проще всего установить пакет Nuget: использовать вспомогательные средства моста для классических приложений и применить метод IsRunningAsUWP() для отсечения всего кода, в котором вызываются API среды выполнения Windows. The easiest way to add runtime checks to your code is to install this Nuget package: Desktop Bridge Helpers and then use the IsRunningAsUWP() method to gate off all code that calls Windows Runtime APIs. Дополнительные сведения см. в записи блога Мост для классических приложений — определение контекста приложения. See this blog post for more details: Desktop Bridge — Identify the application’s context.

Получение ответов на вопросы Find answers to your questions

Есть вопросы? Have questions? Задайте их на Stack Overflow. Ask us on Stack Overflow. Наша команда следит за этими тегами. Our team monitors these tags. Вы также можете задать нам вопросы здесь. You can also ask us here.

Читайте также:  Common linux interview questions and answers
Оцените статью