#include "pch.h" // Use the C++ standard templated min/max #define NOMINMAX #include #include #include #include #include #include #include #include #include "winrt/Windows.ApplicationModel.h" #include "winrt/Windows.ApplicationModel.Core.h" #include "winrt/Windows.ApplicationModel.Activation.h" #include "winrt/Windows.Foundation.h" #include "winrt/Windows.Graphics.Display.h" #include "winrt/Windows.System.h" #include "winrt/Windows.UI.Core.h" #include "winrt/Windows.UI.Input.h" #include "winrt/Windows.UI.ViewManagement.h" using namespace winrt::Windows::ApplicationModel; using namespace winrt::Windows::ApplicationModel::Core; using namespace winrt::Windows::ApplicationModel::Activation; using namespace winrt::Windows::UI::Core; using namespace winrt::Windows::UI::Input; using namespace winrt::Windows::UI::ViewManagement; using namespace winrt::Windows::System; using namespace winrt::Windows::Foundation; using namespace winrt::Windows::Graphics::Display; class ViewProvider : public winrt::implements { public: // IFrameworkView methods void Initialize(CoreApplicationView const & applicationView) { applicationView.Activated({ this, &ViewProvider::OnActivated }); CoreApplication::Suspending({ this, &ViewProvider::OnSuspending }); CoreApplication::Resuming({ this, &ViewProvider::OnResuming }); application.infoDisplay.active = true; application.infoDisplay.watermark = true; application.infoDisplay.resolution = true; application.infoDisplay.fpsinfo = true; } void Uninitialize() noexcept { } void SetWindow(CoreWindow const & window) { window.SizeChanged({ this, &ViewProvider::OnWindowSizeChanged }); window.VisibilityChanged({ this, &ViewProvider::OnVisibilityChanged }); window.Closed([this](auto&&, auto&&) { m_exit = true; }); auto dispatcher = CoreWindow::GetForCurrentThread().Dispatcher(); dispatcher.AcceleratorKeyActivated({ this, &ViewProvider::OnAcceleratorKeyActivated }); auto navigation = SystemNavigationManager::GetForCurrentView(); // UWP on Xbox One triggers a back request whenever the B button is pressed // which can result in the app being suspended if unhandled navigation.BackRequested([](const winrt::Windows::Foundation::IInspectable&, const BackRequestedEventArgs& args) { args.Handled(true); }); auto currentDisplayInformation = DisplayInformation::GetForCurrentView(); currentDisplayInformation.DpiChanged({ this, &ViewProvider::OnDpiChanged }); DisplayInformation::DisplayContentsInvalidated({ this, &ViewProvider::OnDisplayContentsInvalidated }); m_DPI = currentDisplayInformation.LogicalDpi(); m_logicalWidth = window.Bounds().Width; m_logicalHeight = window.Bounds().Height; application.SetWindow(&window); } void Load(winrt::hstring const &) noexcept { } void Run() { while (!m_exit) { if (m_visible) { application.Run(); CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); } else { CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); } } } protected: // Event handlers void OnActivated(CoreApplicationView const & /*applicationView*/, IActivatedEventArgs const & args) { CoreWindow::GetForCurrentThread().Activate(); } void OnSuspending(IInspectable const & /*sender*/, SuspendingEventArgs const & args) { auto deferral = args.SuspendingOperation().GetDeferral(); auto f = std::async(std::launch::async, [this, deferral]() { deferral.Complete(); }); } void OnResuming(IInspectable const & /*sender*/, IInspectable const & /*args*/) { } void OnWindowSizeChanged(CoreWindow const & sender, WindowSizeChangedEventArgs const & /*args*/) { application.SetWindow(&sender); } void OnVisibilityChanged(CoreWindow const & /*sender*/, VisibilityChangedEventArgs const & args) { m_visible = args.Visible(); } void OnAcceleratorKeyActivated(CoreDispatcher const &, AcceleratorKeyEventArgs const & args) { if (args.EventType() == CoreAcceleratorKeyEventType::SystemKeyDown && args.VirtualKey() == VirtualKey::Enter && args.KeyStatus().IsMenuKeyDown && !args.KeyStatus().WasKeyDown) { // Implements the classic ALT+ENTER fullscreen toggle auto view = ApplicationView::GetForCurrentView(); if (view.IsFullScreenMode()) view.ExitFullScreenMode(); else view.TryEnterFullScreenMode(); args.Handled(true); } if (args.EventType() == CoreAcceleratorKeyEventType::Character && args.VirtualKey() != VirtualKey::Enter) { wchar_t c = (wchar_t)args.VirtualKey(); if (c == '\b') { wi::gui::TextInputField::DeleteFromInput(); } else { wi::gui::TextInputField::AddInput(c); } } } void OnDpiChanged(DisplayInformation const & sender, IInspectable const & /*args*/) { application.SetWindow(&CoreWindow::GetForCurrentThread()); } void OnDisplayContentsInvalidated(DisplayInformation const & /*sender*/, IInspectable const & /*args*/) { } private: bool m_exit = false; bool m_visible = true; float m_DPI = 96; float m_logicalWidth = 800; float m_logicalHeight = 600; wi::Application application; inline int ConvertDipsToPixels(float dips) const noexcept { return int(dips * m_DPI / 96.f + 0.5f); } inline float ConvertPixelsToDips(int pixels) const noexcept { return (float(pixels) * 96.f / m_DPI); } }; class ViewProviderFactory : public winrt::implements { public: IFrameworkView CreateView() { return winrt::make(); } }; // Entry point int WINAPI wWinMain( _In_ HINSTANCE /*hInstance*/, _In_ HINSTANCE /*hPrevInstance*/, _In_ LPWSTR /*lpCmdLine*/, _In_ int /*nCmdShow*/ ) { auto viewProviderFactory = winrt::make(); CoreApplication::Run(viewProviderFactory); return 0; }