Миграция пакета SDK для приложений для Windows примера приложения редактора фотографий UWP (C++/WinRT)
В этом разделе рассматриваются примеры приложения редактора фотографий C++/WinRT UWP и его перенос в пакет SDK для приложений Windows.
- Начните с клонирования репозитория примера приложения UWP и открытия решения в Visual Studio.
Внимание
Рекомендации и стратегии для подхода к процессу миграции и настройке среды разработки для миграции см. в статье "Общая стратегия миграции".
Установка инструментов для Windows App SDK
Чтобы настроить среду разработки на компьютере, выполните инструкции из статьи Установка средств для пакета SDK для приложений Windows.
Внимание
Среди разделов с заметками о выпуске вы найдете раздел Каналы выпуска Windows App SDK. В нем представлены заметки о выпуске для каждого канала. Не забудьте проверить все ограничения и известные проблемы в этих заметках о выпуске, так как они могут повлиять на результаты выполнения вместе с этим примером и /или запуском перенесенного приложения.
Создание нового проекта
- В Visual Studio создайте проект C++/WinRT из шаблона проекта "Пустое приложение" (WinUI 3 в классическом приложении). Назовите проект PhotoEditor, снимите флажок "Место" и "Проект" в одном каталоге. В качестве целевой версии вы можете выбрать последний выпуск (не предварительную версию) операционной системы клиента.
Примечание.
Мы будем ссылаться на версию примера проекта UWP (клонированную из репозитория) в качестве исходного решения или проекта. Мы будем называть версию пакета SDK для приложений Windows в качестве целевого решения или проекта.
Порядок переноса кода
MainPage — это важная и видная часть приложения. Но если бы мы начали переносить это, то вскоре мы поняли, что MainPage имеет зависимость от представления DetailPage, а затем, что DetailPage имеет зависимость от модели фото. Поэтому для этого пошагового руководства мы рассмотрим этот подход.
- Начнем с копирования файлов ресурсов.
- Затем мы переносим модель фото .
- Далее мы переносим класс App (так как для этого требуются некоторые члены, добавляемые в него, от этого будет зависеть DetailPage и MainPage).
- Затем сначала мы начнем перенос представлений, начиная с DetailPage .
- И мы завершим работу, переносив представление MainPage .
Мы будем копировать все файлы исходного кода
В этом пошаговом руководстве мы будем копировать файлы исходного кода с помощью проводник. Если вы предпочитаете копировать содержимое файла, см. приложение: копирование содержимого раздела файлов модели фото в конце этого раздела, например, как это можно сделать для фото (и вы можете применить аналогичную процедуру к другим типам в проекте). Этот вариант включает гораздо больше шагов, однако.
Копирование файлов ресурсов
В клоне исходного проекта в проводник найдите папку Windows-appsample-photo-editor>PhotoEditor>Assets. В этой папке находятся восемь файлов ресурсов. Выберите эти восемь файлов и скопируйте их в буфер обмена.
Кроме того, в проводник теперь найдите соответствующую папку в созданном целевом проекте. Путь к этой папке — PhotoEditor PhotoEditor>PhotoEditor>Assets. Вставьте в эту папку файлы ресурсов, скопированные только что, и примите запрос на замену семи файлов, которые уже существуют в назначении.
В целевом проекте в Visual Studio в Обозреватель решений разверните папку "Ресурсы". Добавьте в эту папку существующий
bg1.png
файл ресурса, который вы только что вставили. Указатель мыши можно наведите указатель мыши на файлы ресурсов. Предварительный просмотр эскизов будет отображаться для каждого, убедившись, что вы правильно заменили или добавили файлы активов.
Миграция модели фото
Фотография — это класс среды выполнения, представляющий фотографию. Это модель (в смысле моделей, представлений и моделей представления).
Копирование файлов исходного кода фотографии
В клоне исходного проекта в проводник найдите папку Windows-appsample-photo-editor>PhotoEditor. В этой папке вы найдете три файла исходного кода
Photo.idl
,Photo.h
аPhoto.cpp
также эти файлы вместе реализуют класс среды выполнения Photo. Выберите эти три файла и скопируйте их в буфер обмена.В Visual Studio щелкните правой кнопкой мыши узел целевого проекта и щелкните "Открыть папку" в проводник. Откроется целевая папка проекта в проводник. Вставьте в эту папку только что скопированные три файла.
Вернитесь в Обозреватель решений с выбранным целевым узлом проекта, убедитесь, что включен переключатель "Показать все файлы". Щелкните правой кнопкой мыши три файла, которые вы только что вставили, и нажмите кнопку "Включить в проект". Переключатель "Показать все файлы " отключен.
В исходном проекте в Обозреватель решений
Photo.h
и.cpp
вложеныPhoto.idl
в него, чтобы указать, что они создаются из (зависимо от него). Если вам нравится это расположение, то вы можете сделать то же самое в целевом проекте, вручную изменив\PhotoEditor\PhotoEditor\PhotoEditor\PhotoEditor.vcxproj
(сначала необходимо сохранить все в Visual Studio). Найдите следующее:<ClInclude Include="Photo.h" />
И замените его следующим образом:
<ClInclude Include="Photo.h"> <DependentUpon>Photo.idl</DependentUpon> </ClInclude>
Повторите это для
Photo.cpp
файла проекта и сохраните и закройте его. При настройке фокуса на Visual Studio нажмите кнопку "Перезагрузить".
Перенос исходного кода фотографии
- В
Photo.idl
поле поиска имениWindows.UI.Xaml
пространства имен (которое является пространством имен для XAML UWP) и измените егоMicrosoft.UI.Xaml
на (это пространство имен для XAML WinUI).
Примечание.
Api-интерфейсы UWP сопоставления с разделом пакета SDK для приложений Windows предоставляют сопоставление API UWP с эквивалентами пакета SDK для приложений Windows. Приведенное выше изменение является примером изменения имени пространства имен, необходимого во время процесса миграции.
Добавьте
Photo.cpp
#include "Photo.g.cpp"
в существующие директивы include сразу после#include "Photo.h"
. Это одно из различий имен папок и файлов (C++/WinRT), которые следует учитывать между проектами пакета SDK для приложений UWP и Windows.Сделайте следующее средство поиска и замены (регистр соответствия и целое слово) в содержимом всего исходного кода в файлах, которые вы только что скопировали и вставили.
Windows::UI::Xaml
=>Microsoft::UI::Xaml
Скопируйте
pch.h
в исходный проект приведенный ниже текст и вставьте ихpch.h
в целевой проект. Это подмножество файлов заголовков, включенных в исходный проект; Это только заголовки, которые мы должны поддерживать код, который мы переносили до сих пор.#include <winrt/Microsoft.UI.Xaml.Media.Imaging.h> #include <winrt/Windows.Storage.h> #include <winrt/Windows.Storage.FileProperties.h> #include <winrt/Windows.Storage.Streams.h>
Теперь убедитесь, что вы можете создать целевое решение (но еще не запущено).
Перенос класса App
Никаких изменений не требуется для целевого проекта App.idl
и App.xaml
. Но нам нужно изменить App.xaml.h
и добавить.xaml.cpp
некоторые новые члены в класс App . Мы сделаем это таким образом, чтобы мы строили после каждого раздела (за исключением последнего раздела, который относится к App::OnLaunched).
Предоставление доступа к объекту основного окна
На этом шаге мы внесите изменения, описанные в разделе "Изменение Windows.UI.Xaml.Window.Current на App.Window.
В целевом проекте Приложение сохраняет объект главного окна в окне члена частных данных. Далее в процессе миграции (при переносе исходного проекта использования Window.Current) этот элемент данных будет удобным, если этот элемент данных окна является статическим, а также предоставляется через функцию доступа. Таким образом, мы будем вносить эти изменения далее.
Так как мы делаем окно статическим, мы должны инициализировать его
App.xaml.cpp
вместо инициализатора элемента по умолчанию, который в настоящее время использует код. Ниже приведены те изменения, которые выглядят как вApp.xaml.h
иApp.xaml.cpp
.// App.xaml.h ... struct App : AppT<App> { ... static winrt::Microsoft::UI::Xaml::Window Window(){ return window; }; private: static winrt::Microsoft::UI::Xaml::Window window; }; ... // App.xaml.cpp ... winrt::Microsoft::UI::Xaml::Window App::window{ nullptr }; ...
App::OnNavigationFailed
Пример приложения "Редактор фотографий" использует логику навигации для перехода между MainPage и DetailPage. Дополнительные сведения о приложениях пакета SDK для приложений Для Приложений Windows, которым требуется навигация (и тех, которые нет), см. в статье "Необходимо ли реализовать навигацию по страницам?".
Таким образом, члены, которые будут перенесены в следующих нескольких разделах, существуют для поддержки навигации в приложении.
Начнем с миграции обработчика событий OnNavigationFailed . Скопируйте объявление и определение этой функции-члена из исходного проекта и вставьте его в целевой проект (в
App.xaml.h
иApp.xaml.cpp
).В коде, который вы вставили
App.xaml.h
, измените наWindows::UI::Xaml
Microsoft::UI::Xaml
.
App::CreateRootFrame
Исходный проект содержит вспомогательные функции с именем App::CreateRootFrame. Скопируйте объявление и определение этой вспомогательной функции из исходного проекта и вставьте ее в целевой проект (в
App.xaml.h
иApp.xaml.cpp
).В коде, который вы вставили
App.xaml.h
, измените наWindows::UI::Xaml
Microsoft::UI::Xaml
.В коде, вставляемом
App.xaml.cpp
вами, измените два вхожденияWindow::Current()
window
(это имя члена данных класса App , который мы видели ранее).
App::OnLaunched
Целевой проект уже содержит реализацию обработчика событий OnLaunched . Его параметр является постоянной ссылкой на Microsoft::UI::Xaml::LaunchActivatedEventArgs, что правильно для пакета SDK для приложений Windows (контрастирует с исходным проектом, использующим Windows::ApplicationModel::Activation::LaunchActivatedEventArgs, что правильно для UWP).
Нам просто нужно объединить два определения (источник и целевой объект) OnLaunched, чтобы Приложение::OnLaunched в
App.xaml.cpp
целевом проекте выглядело следующим образом. Обратите внимание, что он используетwindow
(вместоWindow::Current()
версии UWP).void App::OnLaunched(LaunchActivatedEventArgs const&) { window = make<MainWindow>(); Frame rootFrame = CreateRootFrame(); if (!rootFrame.Content()) { rootFrame.Navigate(xaml_typename<PhotoEditor::MainPage>()); } window.Activate(); }
Приведенный выше код дает приложению зависимость от MainPage, поэтому мы не сможем создать сборку с этой точки до тех пор, пока мы не перенесены DetailPage, а затем MainPage. Когда мы сможем снова построить, мы будем говорить так.
Перенос представления DetailPage
DetailPage — это класс, представляющий страницу редактора фотографий, где эффекты Win2D переключаются, задаются и объединяются. Перейдите на страницу редактора фотографий, выбрав эскиз фотографии в MainPage. DetailPage — это представление (в смысле моделей, представлений и представлений).
Ссылка на пакет NuGet Win2D
Для поддержки кода в DetailPage исходный проект имеет зависимость от Microsoft.Graphics.Win2D. Поэтому нам также потребуется зависимость от Win2D в целевом проекте.
- В целевом решении в Visual Studio щелкните Tools>NuGet диспетчер пакетов> Manage NuGet Packages for Solution...>Обзор. Убедитесь, что флажок "Включить предварительную версию " снят и введите или вставьте Microsoft.Graphics.Win2D в поле поиска. Выберите правильный элемент в результатах поиска, проверьте проект PhotoEditor и нажмите кнопку "Установить ", чтобы установить пакет.
Копирование файлов исходного кода DetailPage
В клоне исходного проекта в проводник найдите папку Windows-appsample-photo-editor>PhotoEditor. В этой папке вы найдете четыре файла исходного кода
DetailPage.idl
,DetailPage.xaml
DetailPage.h
иDetailPage.cpp
; эти файлы вместе реализуют представление DetailPage. Выберите эти четыре файла и скопируйте их в буфер обмена.В Visual Studio щелкните правой кнопкой мыши узел целевого проекта и щелкните "Открыть папку" в проводник. Откроется целевая папка проекта в проводник. Вставьте в эту папку только что скопированные четыре файла.
По-прежнему в проводник измените имена
DetailPage.h
иDetailPage.cpp
DetailPage.xaml.h
DetailPage.xaml.cpp
соответственно. Это одно из различий имен папок и файлов (C++/WinRT), которые следует учитывать между проектами пакета SDK для приложений UWP и Windows.Вернитесь в Обозреватель решений с выбранным целевым узлом проекта, убедитесь, что включен переключатель "Показать все файлы". Щелкните правой кнопкой мыши четыре файла, которые вы только что вставили (и переименовали), и нажмите кнопку "Включить в проект". Переключатель "Показать все файлы " отключен.
В исходном проекте в Обозреватель решений
DetailPage.idl
вложенныйDetailPage.xaml
элемент . Если вам нравится это расположение, то вы можете сделать то же самое в целевом проекте, вручную изменив\PhotoEditor\PhotoEditor\PhotoEditor\PhotoEditor.vcxproj
(сначала необходимо сохранить все в Visual Studio). Найдите следующее:<Midl Include="DetailPage.idl" />
И замените его следующим образом:
<Midl Include="DetailPage.idl"> <DependentUpon>DetailPage.xaml</DependentUpon> </Midl>
Сохраните и закройте файл проекта. При настройке фокуса на Visual Studio нажмите кнопку "Перезагрузить".
Перенос исходного кода DetailPage
В
DetailPage.idl
, найдитеWindows.UI.Xaml
и измените это наMicrosoft.UI.Xaml
.В
DetailPage.xaml.cpp
измените#include "DetailPage.h"
на#include "DetailPage.xaml.h"
.Сразу после этого добавьте
#include "DetailPage.g.cpp"
.Для вызова статического метода App::Window (который мы собираемся добавить) для компиляции, добавьте
DetailPage.xaml.cpp
#include "App.xaml.h"
непосредственно перед#include "Photo.h"
ним.Выполните указанные ниже действия поиска и замены (регистр соответствия и целое слово) в содержимом исходного кода в только что скопированных и вставленных файлах.
- В
DetailPage.xaml.h
и.xaml.cpp
,Windows::UI::Composition
=>Microsoft::UI::Composition
- В
DetailPage.xaml.h
и.xaml.cpp
,Windows::UI::Xaml
=>Microsoft::UI::Xaml
- In
DetailPage.xaml.cpp
,Window::Current()
=>App::Window()
- В
Скопируйте
pch.h
в исходный проект приведенный ниже текст и вставьте ихpch.h
в целевой проект.#include <winrt/Windows.Graphics.Effects.h> #include <winrt/Microsoft.Graphics.Canvas.Effects.h> #include <winrt/Microsoft.Graphics.Canvas.UI.Xaml.h> #include <winrt/Microsoft.UI.Composition.h> #include <winrt/Microsoft.UI.Xaml.Input.h> #include <winrt/Windows.Graphics.Imaging.h> #include <winrt/Windows.Storage.Pickers.h>
Кроме того, в верхней части
pch.h
, сразу после#pragma once
этого добавьте следующее:// This is required because we are using std::min and std::max, otherwise // we have a collision with min and max macros being defined elsewhere. #define NOMINMAX
Мы еще не можем построить, но мы сможем выполнить миграцию MainPage (которая будет следующей).
Перенос представления MainPage
Главная страница приложения представляет представление, которое вы увидите сначала при запуске приложения. Это страница, которая загружает фотографии из библиотеки рисунков и отображает представление эскизов на плитках.
Копирование файлов исходного кода MainPage
Аналогично тому, что вы сделали с DetailPage, теперь скопируйте ,
MainPage.xaml
MainPage.idl
иMainPage.h
MainPage.cpp
.Переименуйте и переименуйте
.h
.cpp
файлы.xaml.h
в и.xaml.cpp
соответственно.Включите все четыре файла в целевой проект, как и раньше.
В исходном проекте в Обозреватель решений
MainPage.idl
вложенныйMainPage.xaml
элемент . Если вам нравится это расположение, то вы можете сделать то же самое в целевом проекте, вручную изменив\PhotoEditor\PhotoEditor\PhotoEditor\PhotoEditor.vcxproj
его. Найдите следующее:<Midl Include="MainPage.idl" />
И замените ее на:
<Midl Include="MainPage.idl"> <DependentUpon>MainPage.xaml</DependentUpon> </Midl>
Перенос исходного кода MainPage
В
MainPage.idl
, выполните поискWindows.UI.Xaml
и измените оба вхожденияMicrosoft.UI.Xaml
на .В
MainPage.xaml.cpp
измените#include "MainPage.h"
на#include "MainPage.xaml.h"
.Сразу после этого добавьте
#include "MainPage.g.cpp"
.Для вызова статического метода App::Window (который мы собираемся добавить) для компиляции, добавьте
MainPage.xaml.cpp
#include "App.xaml.h"
непосредственно перед#include "Photo.h"
ним.
На следующем шаге мы добавим изменения, описанные в ContentDialog и всплывающем меню.
Таким образом, по-прежнему в
MainPage.xaml.cpp
методе MainPage::GetItemsAsync сразу после строкиContentDialog unsupportedFilesDialog{};
добавьте эту строку кода.unsupportedFilesDialog.XamlRoot(this->Content().XamlRoot());
Выполните указанные ниже действия поиска и замены (регистр соответствия и целое слово) в содержимом исходного кода в только что скопированных и вставленных файлах.
- В
MainPage.xaml.h
и.xaml.cpp
,Windows::UI::Composition
=>Microsoft::UI::Composition
- В
MainPage.xaml.h
и.xaml.cpp
,Windows::UI::Xaml
=>Microsoft::UI::Xaml
- In
MainPage.xaml.cpp
,Window::Current()
=>App::Window()
- В
Скопируйте
pch.h
в исходный проект приведенный ниже текст и вставьте ихpch.h
в целевой проект.#include <winrt/Microsoft.UI.Xaml.Hosting.h> #include <winrt/Microsoft.UI.Xaml.Media.Animation.h> #include <winrt/Windows.Storage.Search.h>
Убедитесь, что вы можете создать целевое решение (но еще не выполняется).
Обновление MainWindow
Удалите
MainWindow.xaml
StackPanel и его содержимое, так как нам не нужен пользовательский интерфейс в MainWindow. Это оставляет только пустой элемент Window .Удалите
MainWindow.idl
заполнительInt32 MyProperty;
, оставив только конструктор.MainWindow.xaml.cpp
ВMainWindow.xaml.h
и удалите объявления и определения заполнителя MyProperty и myButton_Click, оставив только конструктор.
Изменения миграции, необходимые для разницы в модели потоков
Эти два изменения в этом разделе необходимы из-за разницы в потоковой модели между UWP и пакетом SDK для приложений Windows, как описано в asTA для модели потоков STA. Ниже приведены краткие описания причин проблем, а затем способ устранения каждого из них.
MainPage
MainPage загружает файлы изображений из папки "Изображения", вызывает StorageItemContentProperties.GetImagePropertiesAsync для получения свойств файла изображения, создает объект модели фото для каждого файла изображения (сохраняя те же свойства в элементе данных) и добавляет этот объект Photo в коллекцию. Коллекция объектов Photo привязана к GridView в пользовательском интерфейсе. От имени этого GridView MainPage обрабатывает событие ContainerContentChanging и для этапа 1, который обработчик вызывает корутину, которая вызывает StorageFile.GetThumbnailAsync. Этот вызов GetThumbnailAsync приводит к перекачиваемым сообщениям (он не возвращается немедленно и выполняет все его асинхронное выполнение) и приводит к повторному входу. Результатом является то, что GridView имеет свою коллекцию "Элементы " во время выполнения макета и что приводит к сбою.
Если мы закомментируем вызов StorageItemContentProperties::GetImagePropertiesAsync, то мы не получаем сбой. Но реальное исправление заключается в том, чтобы вызов StorageFile.GetThumbnailAsync был явно асинхронным путем совместного ожидания wil::resume_foreground непосредственно перед вызовом GetThumbnailAsync. Это работает, так как в формате wil::resume_foreground планирует код, следующий за ним, задачей в диспетчереQueue.
Ниже приведен код для изменения:
// MainPage.xaml.cpp
IAsyncAction MainPage::OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
...
if (args.Phase() == 1)
{
...
try
{
co_await wil::resume_foreground(this->DispatcherQueue());
auto thumbnail = co_await impleType->GetImageThumbnailAsync(this->DispatcherQueue());
image.Source(thumbnail);
}
...
}
}
Фото
Свойство Photo::ImageTitle привязано к пользовательскому интерфейсу, поэтому пользовательский интерфейс вызывает функцию доступа для этого свойства при необходимости его значения. Но когда мы пытаемся получить доступ к ImageProperties.Title из этой функции доступа в потоке пользовательского интерфейса, мы получаем нарушение доступа.
Таким образом, мы можем просто получить доступ к названию один раз, из конструктора фото, и сохранить его в элементе данных m_imageName, если он не пуст. Затем в функции доступа Photo::ImageTitle нам потребуется только для доступа к элементу данных m_imageName .
Ниже приведен код для изменения:
// Photo.h
...
Photo(Photo(Windows::Storage::FileProperties::ImageProperties const& props,
...
) : ...
{
if (m_imageProperties.Title() != L"")
{
m_imageName = m_imageProperties.Title();
}
}
...
hstring ImageTitle() const
{
return m_imageName;
}
...
Это последние изменения, которые необходимо внести для переноса примера приложения "Редактор фотографий". В разделе "Тестирование перенесенного приложения" мы убедимся, что мы правильно выполнили действия.
Известные проблемы
Проблема с типом приложения (влияет только на предварительную версию 3)
Если вы последовали вместе с этим примером, используя шаблон проекта из VSIX для пакета SDK для приложений Windows версии 1.0 ( предварительная версия 3), вам потребуется внести небольшое исправление PhotoEditor.vcxproj
. Вот как это сделать.
В Visual Studio в Обозреватель решений щелкните правой кнопкой мыши узел проекта и щелкните "Выгрузить проект". Теперь PhotoEditor.vcxproj
открыт для редактирования. В качестве первого дочернего элемента Project добавьте элемент PropertyGroup следующим образом:
<Project ... >
<PropertyGroup>
<EnableWin32Codegen>true</EnableWin32Codegen>
</PropertyGroup>
<Import ... />
...
Сохраните и закройте PhotoEditor.vcxproj
. Щелкните правой кнопкой мыши узел проекта и щелкните " Перезагрузить проект". Теперь перестроите проект.
Тестирование перенесенного приложения
Теперь создайте проект и запустите приложение для его тестирования. Выберите изображение, задайте уровень масштабирования, выберите эффекты и настройте их.
Приложение. Копирование содержимого файлов модели фото
Как мы уже говорили ранее, вы можете скопировать файлы исходного кода самостоятельно или содержимое файлов исходного кода. Мы уже показали, как скопировать файлы исходного кода самостоятельно. Поэтому в этом разделе приведен пример копирования содержимого файла.
В исходном проекте в Visual Studio найдите папку PhotoEditor (универсальная модель Windows)>. В этой папке содержатся файлы Photo.idl
и Photo.h
Photo.cpp
, которые вместе реализуют класс среды выполнения Photo.
Добавление IDL и создание заглушки
В целевом проекте в Visual Studio добавьте в проект новый элемент Midl File (IDL ). Присвойте новому элементу имя Photo.idl
. Удалите содержимое Photo.idl
по умолчанию.
Скопируйте содержимое моделейPhoto.idl
> из исходного проекта в Visual Studio и вставьте их в Photo.idl
файл, который вы только что добавили в целевой проект. В вставленном коде выполните поиск Windows.UI.Xaml
и измените его Microsoft.UI.Xaml
на .
Сохраните файл.
Внимание
Мы собираемся выполнить сборку целевого решения. Сборка не будет выполняться до завершения на этом этапе, но она получит достаточно далеко, чтобы сделать необходимую работу для нас.
Теперь создайте целевое решение. Несмотря на то, что она не завершится, сборка необходима, так как она создаст файлы исходного кода (заглушки), которые необходимо приступить к реализации модели фото .
В Visual Studio щелкните правой кнопкой мыши узел целевого проекта и щелкните "Открыть папку" в проводник. Откроется целевая папка проекта в проводник. Перейдите в папку (поэтому вы будете в \PhotoEditor\PhotoEditor\PhotoEditor\Generated Files\sources
нейGenerated Files\sources
). Скопируйте заглушки Photo.h
и .cpp
вставьте их в \PhotoEditor\PhotoEditor\PhotoEditor
папку проекта, которая теперь находится на двух уровнях папок.
Вернитесь в Обозреватель решений с выбранным целевым узлом проекта, убедитесь, что включен переключатель "Показать все файлы". Щелкните правой кнопкой мыши заглушки, вставленные (Photo.h
и .cpp
) и нажмите кнопку "Включить в проект". Переключатель "Показать все файлы " отключен.
Вы увидите static_assert
в верхней части содержимого Photo.h
и .cpp
, что потребуется удалить.
Убедитесь, что вы можете создать еще раз (но еще не выполняйтесь).
Перенос кода в заглушки
Скопируйте содержимое Photo.h
и .cpp
из исходного проекта в целевой проект.
Далее остальные шаги по переносу скопированного кода совпадают с приведенными в разделе "Миграция фото исходного кода".
См. также
Windows developer