3#include <winrt/Windows.UI.Xaml.h>
4#include <winrt/Windows.UI.Xaml.Hosting.h>
5#include <Windows.UI.Xaml.Hosting.DesktopWindowXamlSource.h>
28 LRESULT(*WndProc)(HWND, INT, WPARAM, LPARAM,
XamlWindow*) {
nullptr };
35 AppController(HINSTANCE hInst, winrt::Windows::UI::Xaml::Application xapp) {
38 m_winxamlmanager = winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread();
41 HINSTANCE HInstance()
const {
46 winrt::Windows::UI::Xaml::Application m_xapp{
nullptr };
47 HINSTANCE m_hInstance{
nullptr };
48 winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager m_winxamlmanager{
nullptr };
57 winrt::Windows::UI::Xaml::UIElement(*m_getUI) (
const XamlWindow& xw) {
nullptr };
61 winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource m_desktopXamlSource{
nullptr };
62 HWND m_hWnd{
nullptr };
63 HACCEL m_hAccelTable{
nullptr };
67 std::wstring m_markup;
68 winrt::Windows::UI::Xaml::UIElement m_ui{
nullptr };
70 static inline std::unordered_map<std::wstring, XamlWindow> s_windows{};
74 m_Id(std::move(other.m_Id)),
75 m_getUI(std::move(other.m_getUI)),
76 m_markup(std::move(other.m_markup)),
77 m_desktopXamlSource(std::move(other.m_desktopXamlSource)),
78 m_hWnd(std::move(other.m_hWnd)),
79 m_hAccelTable(std::move(m_hAccelTable)),
80 m_controller(std::move(other.m_controller))
96 template<
typename T = winrt::Windows::UI::Xaml::UIElement>
113 template<
typename TUIElement>
116 xw.m_controller = controller;
117 xw.m_getUI = [](
const XamlWindow&) {
return TUIElement().as<winrt::Windows::UI::Xaml::UIElement>(); };
118 const auto& entry = s_windows.emplace(
id, std::move(xw));
119 return entry.first->second;
140 xw.m_markup = markup;
142 return winrt::Windows::UI::Xaml::Markup::XamlReader::Load(xw.m_markup)
143 .as<winrt::Windows::UI::Xaml::UIElement>();
145 const auto& entry = s_windows.emplace(
id, std::move(xw));
146 return entry.first->second;
165 const auto& entry = s_windows.emplace(
id, std::move(xw));
166 return entry.first->second;
173 std::wstring_view
Id()
const {
183 return s_windows.at(std::wstring(
id));
185 static constexpr wchar_t const*
const WindowClass() {
186 return L
"XamlWindow";
199 HWND
Create(
wchar_t const* szTitle, DWORD style, HWND parent =
nullptr,
int width = CW_USEDEFAULT,
int height = CW_USEDEFAULT,
int nCmdShow = SW_NORMAL) {
200 static std::once_flag once;
202 std::call_once(once, [ctl = this->m_controller]() {
204 wcex.cbSize =
sizeof(wcex);
206 wcex.style = CS_HREDRAW | CS_VREDRAW;
207 wcex.lpfnWndProc = [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -> LRESULT
210 auto xw =
reinterpret_cast<XamlWindow*
>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
211 if (xw ==
nullptr && message == WM_CREATE) {
212 auto createStruct =
reinterpret_cast<LPCREATESTRUCT
>(lParam);
214 xw =
reinterpret_cast<XamlWindow*
>(createStruct->lpCreateParams);
215 SetWindowLongPtr(hWnd, GWLP_USERDATA,
reinterpret_cast<LONG_PTR
>(xw));
219 return xw ? xw->WndProc(hWnd, message, wParam, lParam) : DefWindowProc(hWnd, message, wParam, lParam);
223 wcex.hInstance = ctl->HInstance();
224 wcex.hCursor = LoadCursor(
nullptr, IDC_ARROW);
225 wcex.lpszClassName = WindowClass();
226 winrt::check_bool(RegisterClassExW(&wcex) != 0);
229 m_desktopXamlSource = winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource();
230 auto hWnd = CreateWindowW(WindowClass(), szTitle, style,
231 CW_USEDEFAULT, CW_USEDEFAULT, width, height, parent,
nullptr, m_controller->HInstance(),
this);
233 ShowWindow(hWnd, nCmdShow);
263 while (GetMessage(&msg,
nullptr, 0, 0))
265 if (
auto xamlSourceNative2 = m_desktopXamlSource.as<IDesktopWindowXamlSourceNative2>()) {
266 BOOL xamlSourceProcessedMessage = FALSE;
267 winrt::check_hresult(xamlSourceNative2->PreTranslateMessage(&msg, &xamlSourceProcessedMessage));
268 if (xamlSourceProcessedMessage) {
273 if (!TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg))
275 TranslateMessage(&msg);
276 DispatchMessage(&msg);
279 return (
int)msg.wParam;
282 HWND GetBridgeWindow()
const {
283 static HWND hWndXamlIsland =
nullptr;
284 if (!hWndXamlIsland) {
285 auto interop = m_desktopXamlSource.as<IDesktopWindowXamlSourceNative>();
286 winrt::check_hresult(interop->get_WindowHandle(&hWndXamlIsland));
288 return hWndXamlIsland;
291 LRESULT WndProc(HWND
hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
292 auto interop = m_desktopXamlSource.as<IDesktopWindowXamlSourceNative>();
298 auto createStruct =
reinterpret_cast<LPCREATESTRUCT
>(lParam);
301 winrt::check_hresult(interop->AttachToWindow(m_hWnd));
303 this->m_ui = this->m_getUI(*
this);
307 m_desktopXamlSource.Content(m_ui);
312 HWND hWndXamlIsland =
nullptr;
313 winrt::check_hresult(interop->get_WindowHandle(&hWndXamlIsland));
315 SetWindowPos(hWndXamlIsland,
nullptr, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_SHOWWINDOW);
321 SetWindowLongPtr(
hwnd, GWLP_USERDATA, (LONG_PTR)
nullptr);
325 if (m_controller && m_controller->WndProc) {
326 return m_controller->WndProc(
hwnd, message, wParam, lParam,
this);
328 else return DefWindowProc(
hwnd, message, wParam, lParam);
The main CppXAML namespace.
AppController is responsible for coordinating XamlWindow instances, can extend their wndproc,...
Definition: XamlWindow.h:22
AppController(HINSTANCE hInst, winrt::Windows::UI::Xaml::Application xapp)
Definition: XamlWindow.h:35
void(* OnUICreated)(winrt::Windows::UI::Xaml::UIElement content, XamlWindow *xw)
App-provided callback to be called when any of this controller's windows create their UI (usually Pag...
Definition: XamlWindow.h:27
Implements an HWND based host for XAML Islands. You can create a XamlWindow from one of three overloa...
Definition: XamlWindow.h:54
static XamlWindow & Make(std::wstring_view id, AppController *controller=nullptr)
Creates a window that hosts a XAML UI element.
Definition: XamlWindow.h:114
static XamlWindow & Get(std::wstring_view id)
returns the XamlWindow corresponding to the id.
Definition: XamlWindow.h:182
AppController * Controller() const
Definition: XamlWindow.h:251
static XamlWindow & Make(std::wstring_view id, std::wstring_view markup, AppController *c=nullptr)
Creates a window that hosts XAML UI, based on some markup provided as an input parameter.
Definition: XamlWindow.h:137
HWND hwnd() const
returns the HWND backing the XamlWindow.
Definition: XamlWindow.h:87
T GetUIElement() const
returns the XAML UI that the XamlWindow was created with.
Definition: XamlWindow.h:97
int RunLoop()
Definition: XamlWindow.h:259
HWND Create(wchar_t const *szTitle, DWORD style, HWND parent=nullptr, int width=CW_USEDEFAULT, int height=CW_USEDEFAULT, int nCmdShow=SW_NORMAL)
Call this function to create the actual window. Afterwards, you will call XamlWindow::RunLoop to proc...
Definition: XamlWindow.h:199
void SetAcceleratorTable(HACCEL acc)
Definition: XamlWindow.h:243
std::wstring_view Id() const
returns the window's id
Definition: XamlWindow.h:173
static XamlWindow & Make(std::wstring_view id, winrt::Windows::UI::Xaml::UIElement(*getUI)(const XamlWindow &), AppController *c=nullptr)
Creates a window that hosts XAML UI. The UI will be provided by the app.
Definition: XamlWindow.h:161