-
Notifications
You must be signed in to change notification settings - Fork 0
/
win32-xaml-island-base.hpp
97 lines (77 loc) · 2.85 KB
/
win32-xaml-island-base.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#pragma once
#include "pch.h"
using namespace winrt;
using namespace Windows::UI;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Hosting;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Text;
using namespace Windows::Foundation;
struct InitXamlEngine // a singleton which needs created once before using XAML
{
InitXamlEngine() : winxamlmanager{(
init_apartment(apartment_type::single_threaded),
WindowsXamlManager::InitializeForCurrentThread() )}
{
// After destroying the WindowsXamlManager for a given thread, creating a new
// WindowsXamlManager on the same thread is not supported and will result in
// unpredictable behavior. - Microsoft
static auto call_count{ 0 };
assert(call_count == 0);
++call_count;
}
~InitXamlEngine() { winxamlmanager.Close(); }
InitXamlEngine(const InitXamlEngine&) = delete;
InitXamlEngine(InitXamlEngine&&) = delete;
InitXamlEngine& operator=(const InitXamlEngine&) = delete;
InitXamlEngine& operator=(InitXamlEngine&&) = delete;
const WindowsXamlManager winxamlmanager;
};
class Win32Host // a classic Win32 window to host a XAML island
{
friend class Win32XamlIsland;
public:
auto HwndHost() const { return hWndHost; }
private:
HWND hWndHost{ NULL };
};
class Win32XamlIsland : public Win32Host // the base class for a Win32 XAML island
{
public:
Win32XamlIsland() = default;
virtual ~Win32XamlIsland() { desktopSource.Close(); }
Win32XamlIsland(const Win32XamlIsland&) = delete;
Win32XamlIsland(Win32XamlIsland&&) = delete;
Win32XamlIsland& operator=(const Win32XamlIsland&) = delete;
Win32XamlIsland& operator=(Win32XamlIsland&&) = delete;
auto AttachTo(HWND);
auto HwndXamlIsland() const { return hWndXamlIsland; }
private:
virtual void DoInitXamlContent() = 0; // XAML controls initialization
virtual UIElement DoTopXamlContainer() const = 0; // the control to be passed to desktopSource.Content
DesktopWindowXamlSource desktopSource{};
HWND hWndXamlIsland{ NULL };
// Declare XAML controls here (or under protected)
};
inline auto Win32XamlIsland::AttachTo(HWND hwnd) // Template Method
{
// Make sure that your code calls the AttachToWindow method only once
// per DesktopWindowXamlSource object. Calling this method more than once
// for a DesktopWindowXamlSource object could result in a memory leak.
// - Microsoft
assert(hWndXamlIsland == NULL);
assert(hwnd != NULL);
hWndHost = hwnd;
auto interop = desktopSource.as<IDesktopWindowXamlSourceNative>();
check_hresult(interop->AttachToWindow(hwnd));
interop->get_WindowHandle(&hWndXamlIsland);
desktopSource.Content(DoTopXamlContainer());
DoInitXamlContent();
DoTopXamlContainer().UpdateLayout();
}
inline double RasterizationScale()
{
return double(GetDpiForSystem()) * 25.0 / 24.0 / 100.0;
}