diff --git a/change/react-native-windows-2020-05-19-03-08-41-reactApplication.json b/change/react-native-windows-2020-05-19-03-08-41-reactApplication.json new file mode 100644 index 00000000000..24c3ade0de9 --- /dev/null +++ b/change/react-native-windows-2020-05-19-03-08-41-reactApplication.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "set up react application to use an app's reactrootview", + "packageName": "react-native-windows", + "email": "asklar@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-19T10:08:41.333Z" +} diff --git a/packages/E2ETest/run_wdio.js b/packages/E2ETest/run_wdio.js index d44e57e1957..1a0bcd1ad1a 100644 --- a/packages/E2ETest/run_wdio.js +++ b/packages/E2ETest/run_wdio.js @@ -117,6 +117,7 @@ function parseLogs() { } function printFailedTests(ft) { + console.log('Failed test cases: '); for (const key in ft) { console.log(chalk.redBright(key)); console.log( @@ -133,8 +134,9 @@ function printFailedTests(ft) { function doProcess(code) { const failedTests = parseLogs(); for (const failedTest of failedTests) { - console.log('Failed tests: '); - printFailedTests(failedTest); + if (Object.keys(failedTest).length > 0) { + printFailedTests(failedTest); + } } process.exit(code); } diff --git a/packages/E2ETest/windows/ReactUWPTestApp/App.xaml.cs b/packages/E2ETest/windows/ReactUWPTestApp/App.xaml.cs index 9befe037a84..b8561511bb1 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/App.xaml.cs +++ b/packages/E2ETest/windows/ReactUWPTestApp/App.xaml.cs @@ -9,6 +9,8 @@ using Windows.UI.Core; using Windows.UI.ViewManagement; using Microsoft.ReactNative.Managed; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; namespace ReactUWPTestApp { @@ -23,8 +25,6 @@ sealed partial class App : ReactApplication /// public App() { - MainComponentName = "ReactUWPTestApp"; - #if BUNDLE JavaScriptBundleFile = "index.windows"; InstanceSettings.UseWebDebugger = false; @@ -56,12 +56,17 @@ public App() protected override void OnLaunched(LaunchActivatedEventArgs e) { base.OnLaunched(e); - SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed; - ApplicationView.GetForCurrentView().TryResizeView(new Size(800, 600)); - if (DisplayInformation.GetForCurrentView().ResolutionScale != ResolutionScale.Scale100Percent) + var frame = Window.Current.Content as Frame; + if (frame == null) { - throw new Exception("A bug requires this app to run at 100% for accurate results - See https://github.com/microsoft/react-native-windows/issues/4619"); + frame = new Frame(); + Window.Current.Content = frame; } + frame.Navigate(typeof(MainPage)); + Window.Current.Activate(); + + SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed; + ApplicationView.GetForCurrentView().TryResizeView(new Size(800, 600)); } } } diff --git a/packages/E2ETest/windows/ReactUWPTestApp/MainPage.xaml b/packages/E2ETest/windows/ReactUWPTestApp/MainPage.xaml new file mode 100644 index 00000000000..c857e3dfc95 --- /dev/null +++ b/packages/E2ETest/windows/ReactUWPTestApp/MainPage.xaml @@ -0,0 +1,13 @@ + + + diff --git a/packages/E2ETest/windows/ReactUWPTestApp/MainPage.xaml.cs b/packages/E2ETest/windows/ReactUWPTestApp/MainPage.xaml.cs new file mode 100644 index 00000000000..d4b0381eefc --- /dev/null +++ b/packages/E2ETest/windows/ReactUWPTestApp/MainPage.xaml.cs @@ -0,0 +1,20 @@ +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 + +namespace ReactUWPTestApp +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class MainPage : Page + { + public MainPage() + { + this.InitializeComponent(); + var app = Application.Current as App; + myRootView.ReactNativeHost = app.Host; + } + } +} diff --git a/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj b/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj index 9dc144ee76c..71294f03bc1 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj +++ b/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj @@ -124,6 +124,9 @@ App.xaml + + MainPage.xaml + @@ -175,6 +178,12 @@ Microsoft.ReactNative.Managed + + + Designer + MSBuild:Compile + + 16.0 diff --git a/packages/E2ETest/windows/ReactUWPTestApp/TreeDumpControlViewManager.cs b/packages/E2ETest/windows/ReactUWPTestApp/TreeDumpControlViewManager.cs index fff0cb61c74..0d0bc55b359 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/TreeDumpControlViewManager.cs +++ b/packages/E2ETest/windows/ReactUWPTestApp/TreeDumpControlViewManager.cs @@ -32,11 +32,12 @@ public FrameworkElement CreateView() m_textBlock.IsTextSelectionEnabled = false; m_textBlock.LayoutUpdated += (source, e) => { + ApplicationView.GetForCurrentView().TryResizeView(new Size(800, 600)); var bounds = ApplicationView.GetForCurrentView().VisibleBounds; if (bounds.Width != 800 || bounds.Height != 600) { // Dump disabled when window size is not 800x600! - UpdateResult(false /*matchDump*/ , "Window has been resized, dump comparison is only valid at default launch size: 800x600!, current size:" + bounds.ToString()); + UpdateResult(false /*matchDump*/ , $"Window has been resized, dump comparison is only valid at default launch size: 800x600!, current size: {bounds.Width}x{bounds.Height}"); } else { diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/App.cpp b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/App.cpp index 24ef3d664fb..e5fcadb6a10 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/App.cpp +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/App.cpp @@ -17,8 +17,6 @@ namespace winrt::SampleAppCpp::implementation { /// WinMain(). /// App::App() noexcept { - MainComponentName(L"SampleApp"); - #if BUNDLE JavaScriptBundleFile(L"index.windows"); InstanceSettings().UseWebDebugger(false); diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.cpp b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.cpp new file mode 100644 index 00000000000..9db5da89bc7 --- /dev/null +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.cpp @@ -0,0 +1,19 @@ +#include "pch.h" +#include "MainPage.h" +#if __has_include("MainPage.g.cpp") +#include "MainPage.g.cpp" +#endif + +#include +#include + +using namespace winrt; +using namespace Windows::UI::Xaml; + +namespace winrt::SampleAppCpp::implementation { +MainPage::MainPage() { + InitializeComponent(); + ReactRootView().ReactNativeHost(Application::Current().as()->Host()); +} + +} // namespace winrt::SampleAppCpp::implementation diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.h b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.h new file mode 100644 index 00000000000..908066b496d --- /dev/null +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.h @@ -0,0 +1,13 @@ +#pragma once + +#include "MainPage.g.h" + +namespace winrt::SampleAppCpp::implementation { +struct MainPage : MainPageT { + MainPage(); +}; +} // namespace winrt::SampleAppCpp::implementation + +namespace winrt::SampleAppCpp::factory_implementation { +struct MainPage : MainPageT {}; +} // namespace winrt::SampleAppCpp::factory_implementation diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.idl b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.idl new file mode 100644 index 00000000000..632100b9738 --- /dev/null +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.idl @@ -0,0 +1,8 @@ +namespace SampleAppCpp +{ + [default_interface] + runtimeclass MainPage : Windows.UI.Xaml.Controls.Page + { + MainPage(); + } +} diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.xaml b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.xaml new file mode 100644 index 00000000000..3e068afdc89 --- /dev/null +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/MainPage.xaml @@ -0,0 +1,12 @@ + + + + diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj index addc3cc801d..f6ed47b6650 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj @@ -130,6 +130,10 @@ + + MainPage.xaml + Code + @@ -157,6 +161,10 @@ + + MainPage.xaml + Code + Create @@ -170,6 +178,10 @@ App.xaml + + MainPage.xaml + Code + @@ -191,6 +203,11 @@ {c0a6bd9c-3ee5-4b12-8ce4-cee95178539c} + + + Designer + + diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj.filters b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj.filters index 872971f9b86..de9839ae11c 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj.filters +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj.filters @@ -59,4 +59,7 @@ + + + \ No newline at end of file diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/packages.config b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/packages.config index 24369e62645..f0b88f9827f 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/packages.config +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/packages.config @@ -2,4 +2,4 @@ - + \ No newline at end of file diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/App.xaml.cs b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/App.xaml.cs index 7c5bbd5dc94..25b8d68e74f 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/App.xaml.cs +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/App.xaml.cs @@ -3,6 +3,9 @@ using Microsoft.ReactNative; using Microsoft.ReactNative.Managed; +using Windows.ApplicationModel.Activation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; namespace SampleAppCS { @@ -19,7 +22,6 @@ sealed partial class App : ReactApplication /// public App() { - MainComponentName = "SampleApp"; #if BUNDLE JavaScriptBundleFile = "index.windows"; @@ -47,5 +49,13 @@ public App() InitializeComponent(); } + + protected override void OnLaunched(LaunchActivatedEventArgs e) + { + base.OnLaunched(e); + var frame = Window.Current.Content as Frame; + frame.Navigate(typeof(MainPage)); + Window.Current.Activate(); + } } } diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/MainPage.xaml b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/MainPage.xaml new file mode 100644 index 00000000000..e16eb3f5c1e --- /dev/null +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/MainPage.xaml @@ -0,0 +1,13 @@ + + + + diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/MainPage.xaml.cs b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/MainPage.xaml.cs new file mode 100644 index 00000000000..bc11e1953fc --- /dev/null +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/MainPage.xaml.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 + +namespace SampleAppCS +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class MainPage : Page + { + public MainPage() + { + this.InitializeComponent(); + ReactRootView.ReactNativeHost = (Application.Current as App).Host; + } + } +} diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/SampleAppCS.csproj b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/SampleAppCS.csproj index 881abebe7d4..bcbba5a61b3 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/SampleAppCS.csproj +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCS/SampleAppCS.csproj @@ -1,6 +1,5 @@  - + Debug @@ -126,6 +125,9 @@ App.xaml + + MainPage.xaml + @@ -172,6 +174,12 @@ SampleLibraryCS + + + Designer + MSBuild:Compile + + 16.0 diff --git a/packages/playground/windows/playground-win32/Playground-Win32.cpp b/packages/playground/windows/playground-win32/Playground-Win32.cpp index fa1dfc6f319..240dbdc4504 100644 --- a/packages/playground/windows/playground-win32/Playground-Win32.cpp +++ b/packages/playground/windows/playground-win32/Playground-Win32.cpp @@ -129,7 +129,7 @@ struct WindowData { auto host = Host(); host.InstanceSettings().JavaScriptBundleFile(m_bundleFile); - host.InstanceSettings().MainComponentName(appName); + host.InstanceSettings().UseWebDebugger(m_useWebDebugger); host.InstanceSettings().UseDirectDebugger(m_useDirectDebugger); host.InstanceSettings().BundleRootPath( @@ -146,7 +146,7 @@ struct WindowData { host.ReloadInstance(); m_reactRootView = winrt::Microsoft::ReactNative::ReactRootView(); - m_reactRootView.ComponentName(host.InstanceSettings().MainComponentName()); + m_reactRootView.ComponentName(appName); m_reactRootView.ReactNativeHost(host); // Retrieve ABI pointer from C++/CX pointer diff --git a/packages/playground/windows/playground/App.cpp b/packages/playground/windows/playground/App.cpp index b06cf5068f7..cd348c0908c 100644 --- a/packages/playground/windows/playground/App.cpp +++ b/packages/playground/windows/playground/App.cpp @@ -37,50 +37,10 @@ App::App() { /// /// Details about the launch request and process. void App::OnLaunched(LaunchActivatedEventArgs const &e) { - Frame rootFrame{nullptr}; - auto content = Window::Current().Content(); - if (content) { - rootFrame = content.try_as(); - } - - // Do not repeat app initialization when the Window already has content, - // just ensure that the window is active - if (rootFrame == nullptr) { - // Create a Frame to act as the navigation context and associate it with - // a SuspensionManager key - rootFrame = Frame(); - - rootFrame.NavigationFailed({this, &App::OnNavigationFailed}); - - if (e.PreviousExecutionState() == ApplicationExecutionState::Terminated) { - // Restore the saved session state only when appropriate, scheduling the - // final launch steps after the restore is complete - } - - if (e.PrelaunchActivated() == false) { - if (rootFrame.Content() == nullptr) { - // When the navigation stack isn't restored navigate to the first page, - // configuring the new page by passing required information as a navigation - // parameter - rootFrame.Navigate(xaml_typename(), box_value(e.Arguments())); - } - // Place the frame in the current Window - Window::Current().Content(rootFrame); - // Ensure the current window is active - Window::Current().Activate(); - } - } else { - if (e.PrelaunchActivated() == false) { - if (rootFrame.Content() == nullptr) { - // When the navigation stack isn't restored navigate to the first page, - // configuring the new page by passing required information as a navigation - // parameter - rootFrame.Navigate(xaml_typename(), box_value(e.Arguments())); - } - // Ensure the current window is active - Window::Current().Activate(); - } - } + Frame frame{}; + Window::Current().Content(frame); + Window::Current().Activate(); + frame.Navigate(xaml_typename(), box_value(e.Arguments())); } /// diff --git a/packages/playground/windows/playground/App.xaml b/packages/playground/windows/playground/App.xaml index 31d31170016..a74c81723b0 100644 --- a/packages/playground/windows/playground/App.xaml +++ b/packages/playground/windows/playground/App.xaml @@ -1,7 +1,8 @@ - + xmlns:local="using:playground" + xmlns:react="using:Microsoft.ReactNative"> - + diff --git a/packages/playground/windows/playground/MainPage.cpp b/packages/playground/windows/playground/MainPage.cpp index aaade330325..d641caeaf7c 100644 --- a/packages/playground/windows/playground/MainPage.cpp +++ b/packages/playground/windows/playground/MainPage.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "MainPage.h" #include "MainPage.g.cpp" +#include using namespace winrt; using namespace Windows::ApplicationModel::Activation; @@ -35,8 +36,11 @@ void MainPage::OnLoadClick( auto host = Host(); auto bundleFile = unbox_value(x_entryPointCombo().SelectedItem().as().Content()); host.InstanceSettings().JavaScriptBundleFile(bundleFile); + auto mainComponentName = unbox_value(x_rootComponentNameCombo().SelectedItem().as().Content()); - host.InstanceSettings().MainComponentName(mainComponentName); + ReactRootView().ComponentName(mainComponentName); + ReactRootView().ReactNativeHost(host); + host.InstanceSettings().UseWebDebugger(x_UseWebDebuggerCheckBox().IsChecked().GetBoolean()); host.InstanceSettings().UseDirectDebugger(x_UseDirectDebuggerCheckBox().IsChecked().GetBoolean()); host.InstanceSettings().DebuggerBreakOnNextLine(x_BreakOnFirstLineCheckBox().IsChecked().GetBoolean()); @@ -48,13 +52,6 @@ void MainPage::OnLoadClick( // Nudge the ReactNativeHost to create the instance and wrapping context host.ReloadInstance(); - - m_reactRootView = Microsoft::ReactNative::ReactRootView(); - m_reactRootView.ComponentName(host.InstanceSettings().MainComponentName()); - m_reactRootView.ReactNativeHost(host); - - x_rootElement().Children().Clear(); - x_rootElement().Children().Append(m_reactRootView); } void winrt::playground::implementation::MainPage::x_entryPointCombo_SelectionChanged( @@ -71,13 +68,7 @@ void winrt::playground::implementation::MainPage::x_entryPointCombo_SelectionCha } Microsoft::ReactNative::ReactNativeHost MainPage::Host() noexcept { - if (!m_host) { - m_host = Microsoft::ReactNative::ReactNativeHost(); - m_host.InstanceSettings(InstanceSettings()); - m_host.PackageProviders(PackageProviders()); - } - - return m_host; + return Application::Current().as()->Host(); } Microsoft::ReactNative::ReactInstanceSettings MainPage::InstanceSettings() noexcept { diff --git a/packages/playground/windows/playground/MainPage.h b/packages/playground/windows/playground/MainPage.h index cc2d8777abc..32d30dc0b09 100644 --- a/packages/playground/windows/playground/MainPage.h +++ b/packages/playground/windows/playground/MainPage.h @@ -13,8 +13,6 @@ struct MainPage : MainPageT { Microsoft::ReactNative::ReactInstanceSettings InstanceSettings() noexcept; Windows::Foundation::Collections::IVector PackageProviders() noexcept; - Microsoft::ReactNative::ReactRootView m_reactRootView; - Microsoft::ReactNative::ReactNativeHost m_host; Microsoft::ReactNative::ReactInstanceSettings m_instanceSettings; Windows::Foundation::Collections::IVector m_packageProviders; diff --git a/packages/playground/windows/playground/MainPage.xaml b/packages/playground/windows/playground/MainPage.xaml index a4824be9fba..8cb9ede4f50 100644 --- a/packages/playground/windows/playground/MainPage.xaml +++ b/packages/playground/windows/playground/MainPage.xaml @@ -4,6 +4,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:react="using:Microsoft.ReactNative" mc:Ignorable="d"> @@ -134,8 +135,7 @@ InputScope="Number" MaxLength="5" /> - - ReactApplication.idl - - ReactApplicationDelegate.idl - Code - IReactContext.idl Code @@ -497,10 +493,6 @@ ReactApplication.idl - - ReactApplicationDelegate.idl - Code - IReactContext.idl Code @@ -572,9 +564,6 @@ - - Designer - Designer diff --git a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters index 4824e58dc1d..e74ae69e9eb 100644 --- a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +++ b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters @@ -704,7 +704,6 @@ - diff --git a/vnext/Microsoft.ReactNative/ReactApplication.cpp b/vnext/Microsoft.ReactNative/ReactApplication.cpp index 17fe4ade491..fb64898bac6 100644 --- a/vnext/Microsoft.ReactNative/ReactApplication.cpp +++ b/vnext/Microsoft.ReactNative/ReactApplication.cpp @@ -4,6 +4,7 @@ #include "pch.h" #include "ReactApplication.h" #include "ReactApplication.g.cpp" +#include "winrt/Microsoft.ReactNative.h" #include "IReactDispatcher.h" #include "Modules/LinkingManagerModule.h" @@ -85,14 +86,6 @@ ReactNative::ReactNativeHost ReactApplication::Host() noexcept { return m_host; } -hstring ReactApplication::MainComponentName() noexcept { - return InstanceSettings().MainComponentName(); -} - -void ReactApplication::MainComponentName(hstring const &value) noexcept { - InstanceSettings().MainComponentName(value); -} - bool ReactApplication::UseDeveloperSupport() noexcept { return InstanceSettings().UseDeveloperSupport(); } @@ -127,10 +120,36 @@ void ReactApplication::OnActivated(IActivatedEventArgs const &e) { void ReactApplication::OnLaunched(LaunchActivatedEventArgs const &e) { base_type::OnLaunched(e); - // auto args = std::wstring(e.Arguments().c_str()); this->OnCreate(e); } +void ApplyArguments(ReactNative::ReactNativeHost const &host, std::wstring const &arguments) noexcept { + Microsoft::ReactNative::implementation::ReactNativeHost *hostImpl{ + get_self(host)}; + if (!arguments.empty() /*&& host.HasInstance()*/) { + constexpr wchar_t delimiter = L' '; + std::wistringstream argumentStream(arguments); + std::wstring token; + while (std::getline(argumentStream, token, delimiter)) { + if (token == L"-?") { + std::cout << "Options:" << std::endl + << " --direct-debugging Enable direct debugging on specified port." << std::endl; + } else if (token == L"--direct-debugging") { + if (std::getline(argumentStream, token, delimiter)) { + const uint16_t port = static_cast(std::wcstoul(token.c_str(), nullptr, 10)); + hostImpl->InstanceSettings().UseWebDebugger(false); + hostImpl->InstanceSettings().UseDirectDebugger(true); + hostImpl->InstanceSettings().DebuggerBreakOnNextLine(true); + hostImpl->InstanceSettings().DebuggerPort(port); + } + } + } + // TODO: check for 'remoteDebugging'. Return if not found. Otherwise, + // validate a value is provided and then parse it to set the + // ReactInstanceManager.DevSupportManager.IsRemoteDebuggingEnabled flag + } +} + /// /// Invoked when the application is launched normally by the end user. Other /// entry points will be used such as when the application is launched to open a @@ -138,10 +157,6 @@ void ReactApplication::OnLaunched(LaunchActivatedEventArgs const &e) { /// /// Details about the launch request and process. void ReactApplication::OnCreate(IActivatedEventArgs const &e) { - if (!m_delegate) { - m_delegate = CreateReactApplicationDelegate(); - } - #if defined _DEBUG if (IsDebuggerPresent()) { this->DebugSettings().EnableFrameRateCounter(TRUE); @@ -179,34 +194,15 @@ void ReactApplication::OnCreate(IActivatedEventArgs const &e) { // Restore the saved session state only when appropriate, scheduling the // final launch steps after the restore is complete } + Window::Current().Content(rootFrame); + } - if (!isPrelaunchActivated) { - if (rootFrame.Content() == nullptr) { - // When the navigation stack isn't restored navigate to the first page, - // configuring the new page by passing required information as a - // navigation parameter - content = m_delegate.OnCreate(args); - rootFrame.Content(content); - } + ApplyArguments(Host(), args.c_str()); - // Place the frame in the current Window - Window::Current().Content(rootFrame); - // Ensure the current window is active - Window::Current().Activate(); - } - } else { - if (!isPrelaunchActivated) { - if (rootFrame.Content() == nullptr) { - // When the navigation stack isn't restored navigate to the first page, - // configuring the new page by passing required information as a - // navigation parameter - content = m_delegate.OnCreate(args); - rootFrame.Content(content); - } - // Ensure the current window is active - Window::Current().Activate(); - } - } + // Nudge the ReactNativeHost to create the instance and wrapping context + Host().ReloadInstance(); + + Window::Current().Activate(); } /// @@ -231,8 +227,4 @@ void ReactApplication::OnNavigationFailed(IInspectable const &, NavigationFailed throw hresult_error(E_FAIL, hstring(L"Failed to load Page ") + e.SourcePageType().Name); } -ReactApplicationDelegate __stdcall ReactApplication::CreateReactApplicationDelegate() { - return ReactApplicationDelegate(*this); -} - } // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/Microsoft.ReactNative/ReactApplication.h b/vnext/Microsoft.ReactNative/ReactApplication.h index b17d031257b..6ebcf0c63df 100644 --- a/vnext/Microsoft.ReactNative/ReactApplication.h +++ b/vnext/Microsoft.ReactNative/ReactApplication.h @@ -62,9 +62,6 @@ struct ReactApplication : NoDefaultCtorReactApplication_base { ReactNative::ReactNativeHost Host() noexcept; - hstring MainComponentName() noexcept; - void MainComponentName(hstring const &value) noexcept; - bool UseDeveloperSupport() noexcept; void UseDeveloperSupport(bool value) noexcept; @@ -81,15 +78,11 @@ struct ReactApplication : NoDefaultCtorReactApplication_base { void OnNavigationFailed(IInspectable const &, xaml::Navigation::NavigationFailedEventArgs const &); protected: - virtual ReactApplicationDelegate __stdcall CreateReactApplicationDelegate(); - private: ReactNative::ReactInstanceSettings m_instanceSettings{nullptr}; Windows::Foundation::Collections::IVector m_packageProviders{nullptr}; ReactNative::ReactNativeHost m_host{nullptr}; - ReactApplicationDelegate m_delegate{nullptr}; - void OnCreate(Windows::ApplicationModel::Activation::IActivatedEventArgs const &e); }; diff --git a/vnext/Microsoft.ReactNative/ReactApplication.idl b/vnext/Microsoft.ReactNative/ReactApplication.idl index 1b62f75856a..e6dcb54d5ca 100644 --- a/vnext/Microsoft.ReactNative/ReactApplication.idl +++ b/vnext/Microsoft.ReactNative/ReactApplication.idl @@ -15,7 +15,6 @@ namespace Microsoft.ReactNative { IVector PackageProviders { get; set; }; ReactNativeHost Host { get; }; - String MainComponentName { get; set; }; Boolean UseDeveloperSupport { get; set; }; String JavaScriptMainModuleName { get; set; }; String JavaScriptBundleFile { get; set; }; diff --git a/vnext/Microsoft.ReactNative/ReactApplicationDelegate.cpp b/vnext/Microsoft.ReactNative/ReactApplicationDelegate.cpp deleted file mode 100644 index fc16f11cd2b..00000000000 --- a/vnext/Microsoft.ReactNative/ReactApplicationDelegate.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" - -#include - -// ReactApplicationDelegate.h must be included before ReactApplicationDelegate.g.cpp -#include "ReactApplicationDelegate.h" - -#include "ReactApplicationDelegate.g.cpp" -#include "ReactNativeHost.h" -#include "ReactSupport.h" - -using namespace winrt; -using namespace Windows::Foundation; -using namespace xaml; -using namespace Windows::ApplicationModel; -using namespace Windows::ApplicationModel::Activation; - -namespace winrt::Microsoft::ReactNative::implementation { - -static void ApplyArguments(ReactNative::ReactNativeHost const &host, std::wstring const &arguments) noexcept { - Microsoft::ReactNative::implementation::ReactNativeHost *hostImpl{ - get_self(host)}; - if (!arguments.empty() /*&& host.HasInstance()*/) { - constexpr wchar_t delimiter = L' '; - std::wistringstream argumentStream(arguments); - std::wstring token; - while (std::getline(argumentStream, token, delimiter)) { - if (token == L"-?") { - std::cout << "Options:" << std::endl - << " --direct-debugging Enable direct debugging on specified port." << std::endl; - } else if (token == L"--direct-debugging") { - if (std::getline(argumentStream, token, delimiter)) { - const uint16_t port = static_cast(std::wcstoul(token.c_str(), nullptr, 10)); - hostImpl->InstanceSettings().UseWebDebugger(false); - hostImpl->InstanceSettings().UseDirectDebugger(true); - hostImpl->InstanceSettings().DebuggerBreakOnNextLine(true); - hostImpl->InstanceSettings().DebuggerPort(port); - } - } - } - // TODO: check for 'remoteDebugging'. Return if not found. Otherwise, - // validate a value is provided and then parse it to set the - // ReactInstanceManager.DevSupportManager.IsRemoteDebuggingEnabled flag - } -} - -ReactApplicationDelegate::ReactApplicationDelegate(Application const &application) noexcept - : m_application(application) { - VerifyElseCrash(application); - - m_reactApplication = application.as(); - VerifyElseCrashSz(m_reactApplication, "Expected argument to implement 'IReactApplication' interface"); - - m_application.Resuming({this, &ReactApplicationDelegate::OnResuming}); - m_application.Suspending({this, &ReactApplicationDelegate::OnSuspending}); - m_application.LeavingBackground({this, &ReactApplicationDelegate::OnLeavingBackground}); - m_application.EnteredBackground({this, &ReactApplicationDelegate::OnEnteredBackground}); -} - -void ReactApplicationDelegate::OnActivated(IActivatedEventArgs const &args) noexcept { - switch (args.Kind()) { - case ActivationKind::Protocol: - auto protocolArgs = args.as(); - // auto uri = protocolArgs.Uri; - - // TODO: Need to support deep linking by integrating with the Linking module - if (args.PreviousExecutionState() != ApplicationExecutionState::Running) { - // TODO... Figure out the right activation path for PreviousExecutionState - VerifyElseCrashSz( - false, "ReactApplicationDelegate.OnActivated doesn't handle PreviousExecutionState other than Running"); - } else { - // TODO... Figure out the right activation path - OutputDebugStringW( - L"ReactApplicationDelegate.OnActivated doesn't handle PreviousExecutionState when its Running"); - } - break; - } -} - -// Create the root view for the ReactNative app -UIElement ReactApplicationDelegate::OnCreate(hstring const &arguments) noexcept { - auto host = m_reactApplication.Host(); - - ApplyArguments(host, arguments.c_str()); - - if (m_reactRootView != nullptr) { - return *m_reactRootView; - } - - // Nudge the ReactNativeHost to create the instance and wrapping context - host.ReloadInstance(); - - m_reactRootView = winrt::make_self(); - m_reactRootView->ComponentName(host.InstanceSettings().MainComponentName()); - m_reactRootView->ReactNativeHost(host); - - auto resources = Application::Current().Resources(); - auto brush = resources.Lookup(box_value(L"ApplicationPageBackgroundThemeBrush")).as(); - m_reactRootView->Background(brush); - - return *m_reactRootView; -} - -void ReactApplicationDelegate::OnResuming(IInspectable const & /*sender*/, IInspectable const & /*args*/) noexcept { - OutputDebugStringW(L"ReactApplicationDelegate::OnResuming"); -} - -void ReactApplicationDelegate::OnSuspending(IInspectable const & /*sender*/, IInspectable const & /*args*/) noexcept { - OutputDebugStringW(L"ReactApplicationDelegate::OnSuspending"); -} - -void ReactApplicationDelegate::OnLeavingBackground( - IInspectable const & /*sender*/, - LeavingBackgroundEventArgs const & /*args*/) noexcept { - OutputDebugStringW(L"ReactApplicationDelegate::OnLeavingBackground"); -} - -void ReactApplicationDelegate::OnEnteredBackground( - IInspectable const & /*sender*/, - EnteredBackgroundEventArgs const & /*args*/) noexcept { - OutputDebugStringW(L"ReactApplicationDelegate::OnEnteredBackground"); -} - -} // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/Microsoft.ReactNative/ReactApplicationDelegate.h b/vnext/Microsoft.ReactNative/ReactApplicationDelegate.h deleted file mode 100644 index 4aadc8b89c2..00000000000 --- a/vnext/Microsoft.ReactNative/ReactApplicationDelegate.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "ReactApplicationDelegate.g.h" -#include "ReactRootView.h" - -namespace winrt::Microsoft::ReactNative::implementation { - -struct ReactApplicationDelegate : ReactApplicationDelegateT { - ReactApplicationDelegate() = default; - ReactApplicationDelegate(xaml::Application const &application) noexcept; - - void OnActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs const &args) noexcept; - xaml::UIElement OnCreate(hstring const &args) noexcept; - - private: - void OnResuming(IInspectable const &sender, IInspectable const &args) noexcept; - void OnSuspending(IInspectable const &sender, IInspectable const &args) noexcept; - void OnLeavingBackground( - IInspectable const &sender, - Windows::ApplicationModel::LeavingBackgroundEventArgs const &args) noexcept; - void OnEnteredBackground( - IInspectable const &sender, - Windows::ApplicationModel::EnteredBackgroundEventArgs const &args) noexcept; - - private: - xaml::Application m_application{nullptr}; - IReactApplication m_reactApplication{nullptr}; - winrt::com_ptr m_reactRootView{nullptr}; -}; - -} // namespace winrt::Microsoft::ReactNative::implementation - -namespace winrt::Microsoft::ReactNative::factory_implementation { -struct ReactApplicationDelegate - : ReactApplicationDelegateT {}; -} // namespace winrt::Microsoft::ReactNative::factory_implementation diff --git a/vnext/Microsoft.ReactNative/ReactApplicationDelegate.idl b/vnext/Microsoft.ReactNative/ReactApplicationDelegate.idl deleted file mode 100644 index ca596c9f4d6..00000000000 --- a/vnext/Microsoft.ReactNative/ReactApplicationDelegate.idl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -import "ReactApplication.idl"; -#include "NamespaceRedirect.h" - -namespace Microsoft.ReactNative { - - [webhosthidden] - unsealed runtimeclass ReactApplicationDelegate { - ReactApplicationDelegate(); - ReactApplicationDelegate(XAML_NAMESPACE.Application application); - void OnActivated(Windows.ApplicationModel.Activation.IActivatedEventArgs args); - XAML_NAMESPACE.UIElement OnCreate(String args); - } -} diff --git a/vnext/Microsoft.ReactNative/ReactInstanceSettings.h b/vnext/Microsoft.ReactNative/ReactInstanceSettings.h index fcdc1ef1a1b..e3f9b12a849 100644 --- a/vnext/Microsoft.ReactNative/ReactInstanceSettings.h +++ b/vnext/Microsoft.ReactNative/ReactInstanceSettings.h @@ -28,9 +28,6 @@ struct ReactInstanceSettings : ReactInstanceSettingsT { IReactNotificationService Notifications() noexcept; - hstring MainComponentName() noexcept; - void MainComponentName(hstring const &value) noexcept; - bool UseDeveloperSupport() noexcept; void UseDeveloperSupport(bool value) noexcept; @@ -88,7 +85,6 @@ struct ReactInstanceSettings : ReactInstanceSettingsT { private: IReactPropertyBag m_properties{ReactPropertyBagHelper::CreatePropertyBag()}; IReactNotificationService m_notifications{ReactNotificationServiceHelper::CreateNotificationService()}; - hstring m_mainComponentName{}; bool m_useDeveloperSupport{REACT_DEFAULT_USE_DEVELOPER_SUPPORT}; hstring m_javaScriptMainModuleName{}; hstring m_javaScriptBundleFile{}; @@ -131,14 +127,6 @@ inline IReactNotificationService ReactInstanceSettings::Notifications() noexcept return m_notifications; } -inline hstring ReactInstanceSettings::MainComponentName() noexcept { - return m_mainComponentName; -} - -inline void ReactInstanceSettings::MainComponentName(hstring const &value) noexcept { - m_mainComponentName = value; -} - inline bool ReactInstanceSettings::UseDeveloperSupport() noexcept { return m_useDeveloperSupport; } diff --git a/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl b/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl index ade42eaf090..b050f273e0d 100644 --- a/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl +++ b/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl @@ -14,7 +14,6 @@ namespace Microsoft.ReactNative { IReactPropertyBag Properties { get; }; IReactNotificationService Notifications { get; }; - String MainComponentName { get; set; }; Boolean UseDeveloperSupport { get; set; }; String JavaScriptMainModuleName { get; set; }; String JavaScriptBundleFile { get; set; }; diff --git a/vnext/local-cli/generator-windows/index.js b/vnext/local-cli/generator-windows/index.js index f34881758f9..115255b498a 100644 --- a/vnext/local-cli/generator-windows/index.js +++ b/vnext/local-cli/generator-windows/index.js @@ -101,6 +101,7 @@ function copyProjectTemplateAndReplace( const xamlTargets = ``; const xamlNugetErrors = ``; const xamlNamespace = options.useWinUI3 ? 'Microsoft.UI.Xaml' : 'Windows.UI.Xaml'; + const xamlNamespaceCpp = xamlNamespace.replace(/\./g, '::',); const templateVars = { '// clang-format off': '', @@ -119,6 +120,7 @@ function copyProjectTemplateAndReplace( '<%=XamlNugetPkgName%>': xamlNugetPkgName, '<%=XamlNugetPkgVersion%>': xamlNugetPkgVersion, '<%=XamlNamespace%>': xamlNamespace, + '<%=XamlNamespaceCpp%>': xamlNamespaceCpp, }; [ diff --git a/vnext/local-cli/generator-windows/templates/cpp/proj-experimental/MyApp.vcxproj b/vnext/local-cli/generator-windows/templates/cpp/proj-experimental/MyApp.vcxproj index 215038b6e54..5ecf444ad69 100644 --- a/vnext/local-cli/generator-windows/templates/cpp/proj-experimental/MyApp.vcxproj +++ b/vnext/local-cli/generator-windows/templates/cpp/proj-experimental/MyApp.vcxproj @@ -6,7 +6,7 @@ true true {<%=projectGuid%>} - <%=ns%> + <%=name%> <%=ns%> en-US 16.0 @@ -67,6 +67,7 @@ true false + <%=XamlProps%> @@ -98,6 +99,10 @@ + + MainPage.xaml + Code + @@ -124,6 +129,10 @@ + + MainPage.xaml + Code + Create @@ -137,6 +146,10 @@ App.xaml + + MainPage.xaml + Code + @@ -145,6 +158,11 @@ false + + + Designer + + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\ @@ -164,7 +182,7 @@ - + <%=XamlTargets%> @@ -172,7 +190,7 @@ - + <%=XamlNugetErrors%> \ No newline at end of file diff --git a/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj b/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj index e1ce6a27d50..78c57198545 100644 --- a/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj +++ b/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj @@ -6,7 +6,7 @@ true true {<%=projectGuid%>} - <%=ns%> + <%=name%> <%=ns%> en-US 16.0 @@ -99,6 +99,10 @@ + + MainPage.xaml + Code + @@ -125,6 +129,10 @@ + + MainPage.xaml + Code + Create @@ -138,6 +146,10 @@ App.xaml + + MainPage.xaml + Code + @@ -146,6 +158,11 @@ false + + + Designer + + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\ diff --git a/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj.filters b/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj.filters index 13a1efb1a61..1fa33b7299b 100644 --- a/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj.filters +++ b/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj.filters @@ -55,4 +55,7 @@ + + + \ No newline at end of file diff --git a/vnext/local-cli/generator-windows/templates/cpp/src/App.cpp b/vnext/local-cli/generator-windows/templates/cpp/src/App.cpp index f7afd63819d..876e5c6f324 100644 --- a/vnext/local-cli/generator-windows/templates/cpp/src/App.cpp +++ b/vnext/local-cli/generator-windows/templates/cpp/src/App.cpp @@ -6,6 +6,12 @@ // clang-format off using namespace winrt::<%=ns%>; using namespace winrt::<%=ns%>::implementation; +using namespace winrt; +using namespace <%=XamlNamespaceCpp%>; +using namespace <%=XamlNamespaceCpp%>::Controls; +using namespace <%=XamlNamespaceCpp%>::Navigation; +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Activation; /// /// Initializes the singleton application object. This is the first line of @@ -14,8 +20,6 @@ using namespace winrt::<%=ns%>::implementation; /// App::App() noexcept { - MainComponentName(L"<%=name%>"); - #if BUNDLE JavaScriptBundleFile(L"index.windows"); InstanceSettings().UseWebDebugger(false); @@ -38,3 +42,38 @@ App::App() noexcept InitializeComponent(); } + +/// +/// Invoked when the application is launched normally by the end user. Other entry points +/// will be used such as when the application is launched to open a specific file. +/// +/// Details about the launch request and process. +void App::OnLaunched(LaunchActivatedEventArgs const& e) +{ + super::OnLaunched(e); + + Frame rootFrame = Window::Current().Content().as(); + rootFrame.Navigate(xaml_typename<<%=name%>::MainPage>(), box_value(e.Arguments())); +} + +/// +/// Invoked when application execution is being suspended. Application state is saved +/// without knowing whether the application will be terminated or resumed with the contents +/// of memory still intact. +/// +/// The source of the suspend request. +/// Details about the suspend request. +void App::OnSuspending([[maybe_unused]] IInspectable const& sender, [[maybe_unused]] SuspendingEventArgs const& e) +{ + // Save application state and stop any background activity +} + +/// +/// Invoked when Navigation to a certain page fails +/// +/// The Frame which failed navigation +/// Details about the navigation failure +void App::OnNavigationFailed(IInspectable const&, NavigationFailedEventArgs const& e) +{ + throw hresult_error(E_FAIL, hstring(L"Failed to load Page ") + e.SourcePageType().Name); +} diff --git a/vnext/local-cli/generator-windows/templates/cpp/src/App.h b/vnext/local-cli/generator-windows/templates/cpp/src/App.h index 229832d4b79..9cf53085880 100644 --- a/vnext/local-cli/generator-windows/templates/cpp/src/App.h +++ b/vnext/local-cli/generator-windows/templates/cpp/src/App.h @@ -1,12 +1,18 @@ #pragma once #include "App.xaml.g.h" + // clang-format off namespace winrt::<%=ns%>::implementation { struct App : AppT { App() noexcept; + void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const&); + void OnSuspending(IInspectable const&, Windows::ApplicationModel::SuspendingEventArgs const&); + void OnNavigationFailed(IInspectable const&, <%=XamlNamespaceCpp%>::Navigation::NavigationFailedEventArgs const&); + private: + using super = AppT; }; } // namespace winrt::<%=ns%>::implementation diff --git a/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.cpp b/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.cpp new file mode 100644 index 00000000000..9bd90d589d4 --- /dev/null +++ b/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.cpp @@ -0,0 +1,24 @@ +#include "pch.h" +#include "MainPage.h" +#if __has_include("MainPage.g.cpp") +#include "MainPage.g.cpp" +#endif + +#include "App.h" + +// clang-format off + +using namespace winrt; +using namespace <%=XamlNamespaceCpp%>; + +namespace winrt::<%=ns%>::implementation +{ + MainPage::MainPage() + { + InitializeComponent(); + auto app = Application::Current().as(); + ReactRootView().ReactNativeHost(app->Host()); + } +} + +// clang-format on diff --git a/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.h b/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.h new file mode 100644 index 00000000000..a8fb2cb62e4 --- /dev/null +++ b/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.h @@ -0,0 +1,21 @@ +#pragma once +#include "MainPage.g.h" +#include + +// clang-format off +namespace winrt::<%=ns%>::implementation +{ + struct MainPage : MainPageT + { + MainPage(); + }; +} + +namespace winrt::<%=ns%>::factory_implementation +{ + struct MainPage : MainPageT + { + }; +} + +// clang-format on diff --git a/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.idl b/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.idl new file mode 100644 index 00000000000..4836346b4aa --- /dev/null +++ b/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.idl @@ -0,0 +1,8 @@ +namespace <%=ns%> +{ + [default_interface] + runtimeclass MainPage : <%=XamlNamespace%>.Controls.Page + { + MainPage(); + } +} diff --git a/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.xaml b/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.xaml new file mode 100644 index 00000000000..f330dce624d --- /dev/null +++ b/vnext/local-cli/generator-windows/templates/cpp/src/MainPage.xaml @@ -0,0 +1,13 @@ + + + diff --git a/vnext/local-cli/generator-windows/templates/cs/proj/MyApp.csproj b/vnext/local-cli/generator-windows/templates/cs/proj/MyApp.csproj index 6e9f200af72..f54fbf520ff 100644 --- a/vnext/local-cli/generator-windows/templates/cs/proj/MyApp.csproj +++ b/vnext/local-cli/generator-windows/templates/cs/proj/MyApp.csproj @@ -122,6 +122,9 @@ App.xaml + + MainPage.xaml + @@ -146,6 +149,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + diff --git a/vnext/local-cli/generator-windows/templates/cs/src/App.xaml.cs b/vnext/local-cli/generator-windows/templates/cs/src/App.xaml.cs index 8ee40b5403b..9e62f3d5021 100644 --- a/vnext/local-cli/generator-windows/templates/cs/src/App.xaml.cs +++ b/vnext/local-cli/generator-windows/templates/cs/src/App.xaml.cs @@ -1,4 +1,7 @@ using Microsoft.ReactNative; +using Windows.ApplicationModel.Activation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; namespace <%=ns%> { @@ -6,8 +9,6 @@ sealed partial class App : ReactApplication { public App() { - MainComponentName = "<%=name%>"; - #if BUNDLE JavaScriptBundleFile = "index.windows"; InstanceSettings.UseWebDebugger = false; @@ -31,5 +32,18 @@ public App() InitializeComponent(); } + + /// + /// Invoked when the application is launched normally by the end user. Other entry points + /// will be used such as when the application is launched to open a specific file. + /// + /// Details about the launch request and process. + protected override void OnLaunched(LaunchActivatedEventArgs e) + { + base.OnLaunched(e); + var frame = Window.Current.Content as Frame; + frame.Navigate(typeof(MainPage)); + Window.Current.Activate(); + } } } diff --git a/vnext/local-cli/generator-windows/templates/cs/src/MainPage.xaml b/vnext/local-cli/generator-windows/templates/cs/src/MainPage.xaml new file mode 100644 index 00000000000..9563608bd87 --- /dev/null +++ b/vnext/local-cli/generator-windows/templates/cs/src/MainPage.xaml @@ -0,0 +1,13 @@ + + + diff --git a/vnext/local-cli/generator-windows/templates/cs/src/MainPage.xaml.cs b/vnext/local-cli/generator-windows/templates/cs/src/MainPage.xaml.cs new file mode 100644 index 00000000000..e746893dac6 --- /dev/null +++ b/vnext/local-cli/generator-windows/templates/cs/src/MainPage.xaml.cs @@ -0,0 +1,33 @@ +using Microsoft.ReactNative; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 + +namespace <%=ns%> +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class MainPage : Page + { + public MainPage() + { + this.InitializeComponent(); + var app = Application.Current as App; + reactRootView.ReactNativeHost = app.Host; + } + } +}