Skip to content

Commit 515b6e6

Browse files
Working on HostBackdropBrush
#10
1 parent c98e011 commit 515b6e6

File tree

5 files changed

+90
-30
lines changed

5 files changed

+90
-30
lines changed

ShortDev.Uwp.FullTrust/ShortDev.Uwp.FullTrust/Xaml/XamlSynchronizationContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace ShortDev.Uwp.FullTrust.Xaml
55
{
6-
public sealed class XamlSynchronizationContext : SynchronizationContext
6+
internal sealed class XamlSynchronizationContext : SynchronizationContext
77
{
88
public CoreWindow CoreWindow { get; }
99
public XamlSynchronizationContext(CoreWindow coreWindow)

ShortDev.Uwp.FullTrust/ShortDev.Uwp.FullTrust/Xaml/XamlWindowActivator.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,21 @@ internal static (CoreApplicationView coreAppView, XamlWindow window) CreateNewIn
3535
Marshal.ThrowExceptionForHR(coreApplicationPrivate.CreateNonImmersiveView(out var coreView));
3636

3737
// Mount Xaml rendering
38-
XamlFrameworkView view = new();
39-
view.Initialize(coreView);
40-
view.SetWindow(coreWindow);
38+
XamlFrameworkView frameworkView = new();
39+
frameworkView.Initialize(coreView);
40+
frameworkView.SetWindow(coreWindow);
4141

4242
// Get xaml window & activate
4343
XamlWindow window = XamlWindow.Current;
4444

4545
// Enable async / await
4646
SynchronizationContext.SetSynchronizationContext(new XamlSynchronizationContext(coreWindow));
4747

48+
// Attach subclass to customize behavior of "CoreWindow"
4849
XamlWindowSubclass subclass = XamlWindowSubclass.Attach(window);
49-
subclass.CurrentFrameworkView = view;
50+
// Save instance of "FrameworkView"
51+
subclass.CurrentFrameworkView = frameworkView;
52+
5053
if (subclass.WindowPrivate != null)
5154
{
5255
// A XamlWindow inside a Win32 process is transparent by default
@@ -55,12 +58,15 @@ internal static (CoreApplicationView coreAppView, XamlWindow window) CreateNewIn
5558
subclass.WindowPrivate.TransparentBackground = config.HasTransparentBackground;
5659
}
5760

58-
// Show win32 frame if requested
59-
subclass.HasWin32Frame = config.HasWin32Frame;
61+
// Enable Acrylic "HostBackdropBrush"
62+
subclass.EnableHostBackdropBrush = true;
6063

64+
// Sync settings from "XamlWindowConfig"
65+
subclass.HasWin32Frame = config.HasWin32Frame;
6166
subclass.IsTopMost = config.IsTopMost;
6267
subclass.HasWin32TitleBar = config.HasWin32TitleBar;
6368

69+
// Dispose subclass on close
6470
coreWindow.Closed += (CoreWindow window, CoreWindowEventArgs args) =>
6571
{
6672
subclass.Dispose();

ShortDev.Uwp.FullTrust/ShortDev.Uwp.FullTrust/Xaml/XamlWindowSubclass.cs

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using ShortDev.Uwp.FullTrust.Internal;
33
using System;
44
using System.Collections.Generic;
5+
using System.ComponentModel;
56
using System.Diagnostics;
67
using System.Runtime.InteropServices;
78
using Windows.UI.Xaml;
@@ -40,13 +41,9 @@ public static XamlWindowSubclass Attach(XamlWindow window)
4041
public static XamlWindowSubclass ForWindow(XamlWindow window)
4142
=> _subclassRegistry[window];
4243

43-
/// <inheritdoc cref="ForWindow(XamlWindow)"/>
44-
public static XamlWindowSubclass ForCurrentWindow()
45-
=> ForWindow(XamlWindow.Current);
46-
4744
/// <inheritdoc cref="ForWindow(XamlWindow)"/>
4845
public static XamlWindowSubclass GetForCurrentView()
49-
=> ForCurrentWindow();
46+
=> ForWindow(XamlWindow.Current);
5047
#endregion
5148

5249
#region Instance
@@ -195,7 +192,7 @@ public bool MinimizeBox
195192
return;
196193

197194
_minimizeBox = value;
198-
UpdateFrameFLags();
195+
UpdateFrameFlags();
199196
}
200197
}
201198

@@ -209,7 +206,7 @@ public bool MaximizeBox
209206
return;
210207

211208
_maximizeBox = value;
212-
UpdateFrameFLags();
209+
UpdateFrameFlags();
213210
}
214211
}
215212

@@ -223,11 +220,11 @@ public bool HasWin32Frame
223220
return;
224221

225222
_hasWin32Frame = value;
226-
UpdateFrameFLags();
223+
UpdateFrameFlags();
227224
}
228225
}
229226

230-
void UpdateFrameFLags()
227+
void UpdateFrameFlags()
231228
{
232229
var flags = (long)GetWindowLong(Hwnd, GWL_STYLE);
233230
if (HasWin32Frame)
@@ -273,13 +270,17 @@ public bool IsTopMost
273270
get => _isTopMost;
274271
set
275272
{
273+
if (value == _isTopMost)
274+
return;
275+
276276
const int HWND_TOPMOST = -1;
277277
const int HWND_NOTOPMOST = -2;
278278
SetWindowPos(Hwnd,
279279
value ? (IntPtr)HWND_TOPMOST : (IntPtr)HWND_NOTOPMOST,
280280
0, 0, 0, 0,
281281
SetWindowPosFlags.IgnoreMove | SetWindowPosFlags.IgnoreResize
282282
);
283+
_isTopMost = value;
283284
}
284285
}
285286
#endregion
@@ -313,20 +314,51 @@ public bool UseDarkMode
313314
set
314315
{
315316
// https://github.com/qt/qtbase/blob/1808df9ce59a8c1d426f0361e25120a7852a6442/src/plugins/platforms/windows/qwindowswindow.cpp#L3168
316-
bool dwValue = true;
317-
int hRes = DwmSetWindowAttribute(Hwnd, 19, ref dwValue, Marshal.SizeOf<bool>());
317+
const int DWMWA_USE_IMMERSIVE_DARK_MODE = 20;
318+
int hRes = DwmSetWindowAttribute(Hwnd, 19, ref value, Marshal.SizeOf<bool>());
318319
if (hRes != 0)
319-
Marshal.ThrowExceptionForHR(DwmSetWindowAttribute(Hwnd, 20, ref dwValue, Marshal.SizeOf<bool>()));
320+
Marshal.ThrowExceptionForHR(DwmSetWindowAttribute(Hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, ref value, sizeof(bool)));
320321
NotifyFrameChanged(Hwnd);
321322
_useDarkMode = value;
322323
}
323324
}
324325

325326
[DllImport("dwmapi.dll", PreserveSig = true)]
326-
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
327+
static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
327328

328329
[DllImport("dwmapi.dll", PreserveSig = true)]
329-
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref bool attrValue, int attrSize);
330+
static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref bool attrValue, int attrSize);
331+
332+
[DllImport("dwmapi.dll", PreserveSig = true, SetLastError = true)]
333+
static extern int DwmSetWindowAttribute(IntPtr hwnd, TestStruct attr, IntPtr a, IntPtr b);
334+
335+
[StructLayout(LayoutKind.Sequential)]
336+
unsafe struct TestStruct
337+
{
338+
public int attr;
339+
public int* v8;
340+
public int v9;
341+
}
342+
#endregion
343+
344+
#region EnableHostBackdropBrush
345+
bool _enableHostBackdropBrush = false;
346+
public bool EnableHostBackdropBrush
347+
{
348+
get => _enableHostBackdropBrush;
349+
set
350+
{
351+
// Windows.UI.Xaml.dll!DirectUI::Window::EnableHostBackdropBrush
352+
const int DWMWA_USE_HOSTBACKDROPBRUSH = 16;
353+
unsafe
354+
{
355+
int dwvalue = 16;
356+
DwmSetWindowAttribute(Hwnd, 19, ref dwvalue, 5);
357+
// throw new Win32Exception(Marshal.GetLastWin32Error());
358+
}
359+
_useDarkMode = value;
360+
}
361+
}
330362
#endregion
331363

332364
#region CloseRequested

ShortDev.Uwp.FullTrust/Windows/UI/Xaml/FullTrustApplication.cs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ public static void Start([In] ApplicationInitializationCallback callback, [In] X
6363
static void InvokeOnLaunched()
6464
{
6565
var app = Current;
66-
app.GetType().GetMethod("OnLaunched", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(app, new[] { new Win32LaunchActivatedEventArgs() as object as LaunchActivatedEventArgs });
66+
67+
Win32LaunchActivatedEventArgs args_0 = new();
68+
LaunchActivatedEventArgs args = args_0 as object as LaunchActivatedEventArgs;
69+
app.GetType().GetMethod("OnLaunched", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(app, new[] { args });
6770

6871
return;
6972
IApplicationOverrides applicationOverrides = (IApplicationOverrides)app;
@@ -72,7 +75,7 @@ static void InvokeOnLaunched()
7275

7376
sealed class Win32LaunchActivatedEventArgs : ILaunchActivatedEventArgs, IActivatedEventArgs, IApplicationViewActivatedEventArgs, IPrelaunchActivatedEventArgs, IViewSwitcherProvider, ILaunchActivatedEventArgs2, IActivatedEventArgsWithUser
7477
{
75-
User _currentUser;
78+
User? _currentUser;
7679
public Win32LaunchActivatedEventArgs()
7780
{
7881
var result = User.FindAllAsync().GetAwaiter().GetResult();
@@ -102,13 +105,13 @@ public int CurrentlyShownApplicationViewId
102105
public bool PrelaunchActivated
103106
=> false;
104107

105-
public ActivationViewSwitcher ViewSwitcher
108+
public ActivationViewSwitcher? ViewSwitcher
106109
=> null;
107110

108-
public TileActivatedInfo TileActivatedInfo
111+
public TileActivatedInfo? TileActivatedInfo
109112
=> null;
110113

111-
public User User
114+
public User? User
112115
=> _currentUser;
113116
}
114117

@@ -129,11 +132,25 @@ public static Thread CreateNewUIThread(Action callback)
129132
public static CoreApplicationView CreateNewView()
130133
=> CreateNewView(XamlWindowConfig.Default);
131134

132-
/// ´<inheritdoc cref="CreateNewView" />
135+
/// <inheritdoc cref="CreateNewView" />
133136
public static CoreApplicationView CreateNewView(XamlWindowConfig windowConfig)
134137
{
135-
var result = XamlWindowActivator.CreateNewInternal(windowConfig);
136-
return result.coreAppView;
138+
CoreApplicationView? coreAppView = null;
139+
140+
AutoResetEvent @event = new(false);
141+
CreateNewUIThread(() =>
142+
{
143+
var result = XamlWindowActivator.CreateNewInternal(windowConfig);
144+
coreAppView = result.coreAppView;
145+
146+
@event.Set();
147+
148+
// Run message loop
149+
XamlWindowSubclass.ForWindow(result.window).CurrentFrameworkView!.Run();
150+
});
151+
@event.WaitOne();
152+
153+
return coreAppView!;
137154
}
138155
}
139156
}

Test/UwpUI/MainPage.xaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
<Page.Resources>
1111
<media:AcrylicBrush x:Key="AcrylicBackgroundBrush" BackgroundSource="Backdrop"
1212
TintOpacity="0.8" TintColor="#232323" FallbackColor="#232323" />
13+
<media:AcrylicBrush x:Key="AcrylicBackgroundBrush2" BackgroundSource="HostBackdrop"
14+
TintOpacity="0.8" TintColor="#232323" FallbackColor="#232323" />
1315
</Page.Resources>
1416

1517
<Grid>
@@ -24,6 +26,9 @@
2426
<Button Content="Open" x:Name="OpenButton" Click="OpenButton_Click" MinWidth="200" />
2527
</StackPanel>
2628
</Border>
27-
<Border Background="{StaticResource AcrylicBackgroundBrush}" CornerRadius="10" Grid.Column="2" />
29+
<Grid Grid.Column="2">
30+
<Grid Background="Red" Width="100" Height="100" />
31+
<Border Background="{StaticResource AcrylicBackgroundBrush2}" CornerRadius="10" />
32+
</Grid>
2833
</Grid>
2934
</Page>

0 commit comments

Comments
 (0)