XamlBridge2.cpp
 1  #include "pch.h"
 2  #include "XamlBridge2.h"
 3  #include <CoreWindow.h> // ICoreWindowInterop
 4  
 5  #include <winrt/Microsoft.Toolkit.Win32.UI.XamlHost.h>
 6  #include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
 7  
 8  namespace wac = Windows::ApplicationModel::Core;
 9  
10  // Stubbed implementation for frameworkView.Initialize()
11  struct XamlBridgeCoreAppViewImpl : implements<XamlBridgeCoreAppViewImpl, wac::ICoreApplicationView>
12  {
13      auto CoreWindow() { return Core::CoreWindow::GetForCurrentThread(); }
14      auto Activated(Windows::Foundation::TypedEventHandler<wac::CoreApplicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs> const&) { return event_token(); }
15      auto Activated(event_token const&) {}
16      auto IsMain() { return true; }
17      auto IsHosted() { return false; }
18  };
19  
20  // Function to run the message loop for the xaml window
21  void XamlBridge2::MessageLoop()
22  {
23      Logger::trace("XamlBridge2::MessageLoop()");
24      frameworkView.Run();
25      Logger::trace("XamlBridge2::MessageLoop() stopped");
26  }
27  
28  // Function to initialize the xaml bridge
29  HWND XamlBridge2::InitBridge()
30  {
31      Logger::trace("XamlBridge2::InitBridge()");
32      HRESULT hr = S_OK;
33      winrt::init_apartment(apartment_type::single_threaded);
34  
35      auto windowsUIHandle = LoadLibrary(TEXT("Windows.UI.dll"));
36      auto pfnPrivateCreateCoreWindow = reinterpret_cast<fnPrivateCreateCoreWindow>(GetProcAddress(windowsUIHandle, MAKEINTRESOURCEA(1500)));
37  
38      // Create the core window to host the XAML content
39      void* pCoreWindow;
40      hr = pfnPrivateCreateCoreWindow(IMMERSIVE_HOSTED, L"", 0, 0, 0, 0, 0, parentWindow, winrt::guid_of<Core::ICoreWindow>(), &pCoreWindow);
41      winrt::check_hresult(hr);
42      coreWindow = Core::CoreWindow(pCoreWindow, winrt::take_ownership_from_abi);
43  
44      // Prep for the WinUI resources
45      auto app = Microsoft::Toolkit::Win32::UI::XamlHost::XamlApplication({ Microsoft::UI::Xaml::XamlTypeInfo::XamlControlsXamlMetaDataProvider() });
46  
47      // Initialize the XAML framework
48      frameworkView.Initialize(*reinterpret_cast<wac::CoreApplicationView*>(&make<XamlBridgeCoreAppViewImpl>()));
49      frameworkView.SetWindow(coreWindow);
50  
51      // Add the WinUI resources
52      app.Resources().MergedDictionaries().Append(muxc::XamlControlsResources());
53  
54      auto coreWindowInterop = coreWindow.as<ICoreWindowInterop>();
55      hr = coreWindowInterop->get_WindowHandle(&coreWindowHwnd);
56      winrt::check_hresult(hr);
57  
58      SetParent(coreWindowHwnd, parentWindow);
59      SetWindowLong(coreWindowHwnd, GWL_STYLE, WS_CHILD | WS_VISIBLE);
60  
61      return coreWindowHwnd;
62  }
63  
64  // Message Handler function for Xaml windows
65  LRESULT XamlBridge2::MessageHandler(UINT const message, WPARAM const wParam, LPARAM const lParam) noexcept
66  {
67      switch (message)
68      {
69      case WM_ACTIVATE:
70      case WM_MOVE:
71          SendMessage(coreWindowHwnd, message, wParam, lParam);
72          break;
73      }
74  
75      return DefWindowProc(parentWindow, message, wParam, lParam);
76  }