Skip to content

Commit

Permalink
修复窗口透明效果的异常问题
Browse files Browse the repository at this point in the history
修复win32 window边框样式BUG
支持将动态壁纸设置为程序背景
  • Loading branch information
rmbadmin committed Nov 2, 2021
1 parent 4f425cd commit 951ec09
Show file tree
Hide file tree
Showing 32 changed files with 346 additions and 217 deletions.
1 change: 1 addition & 0 deletions SteamToolsV2+.sln
Original file line number Diff line number Diff line change
Expand Up @@ -1391,6 +1391,7 @@ Global
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6} = {8E38AAF2-8C7D-4B0D-AB25-AB37EECB4029}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
RESX_NeutralResourcesLanguage = zh-Hans
SolutionGuid = {9313F2B4-10DA-43AA-A481-CAA7571C740C}
EndGlobalSection
EndGlobal
12 changes: 12 additions & 0 deletions src/ST.Client.Desktop.Avalonia.App/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
using FluentAvalonia.Styling;
using Avalonia.Media;
using System.Reactive.Disposables;
using System.Application.UI.Views.Controls;
#if WINDOWS
//using WpfApplication = System.Windows.Application;
#endif
Expand Down Expand Up @@ -491,6 +492,17 @@ public void SetAllWindowransparencyMateria(int level)
foreach (var window in desktop.Windows)
{
window.TransparencyLevelHint = (WindowTransparencyLevel)level;

if (window.TransparencyLevelHint == WindowTransparencyLevel.Transparent ||
window.TransparencyLevelHint == WindowTransparencyLevel.None ||
window.TransparencyLevelHint == WindowTransparencyLevel.Blur)
{
((IPseudoClasses)window.Classes).Set(":transparent", true);
}
else
{
((IPseudoClasses)window.Classes).Set(":transparent", false);
}
}
}
}
Expand Down
13 changes: 2 additions & 11 deletions src/ST.Client.Desktop.Avalonia.App/Views/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,9 @@
Topmost="{Binding Topmost}"
x:DataType="vm:MainWindowViewModel"
x:CompileBindings="True">
<Window.Styles>
<Style Selector="TitleBar:fullscreen">
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}" />
</Style>
</Window.Styles>
<Panel Margin="{Binding #MainWindow.OffScreenMargin}">
<!--<Panel ZIndex="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<controls:EmptyControl x:Name="DesktopBackground"
IsVisible="{ReflectionBinding Source={x:Static ms:UISettings.EnableDesktopBackground},Path=Value,Mode=TwoWay}"/>
</Panel>-->
<controls:EmptyControl x:Name="DesktopBackground"
IsVisible="{ReflectionBinding Source={x:Static ms:UISettings.EnableDesktopBackground},Path=Value,Mode=TwoWay}"/>
<local:MainView DataContext="{Binding}"/>
<!--<controls:WebView3 IsVisible="False" InitialUrl="chrome://version"></controls:WebView3>-->
</Panel>
Expand Down
13 changes: 5 additions & 8 deletions src/ST.Client.Desktop.Avalonia.App/Views/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,23 @@ public MainWindow() : base()
{
InitializeComponent();

//var background = this.FindControl<EmptyControl>("DesktopBackground");
//_backHandle = background.Handle;
var background = this.FindControl<EmptyControl>("DesktopBackground");
_backHandle = background.Handle;

//if (OperatingSystem2.IsWindows && !OperatingSystem2.IsWindows11AtLeast)
//{
// TransparencyLevelHint = WindowTransparencyLevel.Transparent;
//}
#if DEBUG
this.AttachDevTools();
#endif
#if StartupTrace
StartupTrace.Restart("MainWindow.ctor");
#endif
}

protected override void OnClosing(CancelEventArgs e)
{
#if !UI_DEMO
if (StartupOptions.Value.HasNotifyIcon)
{
_isOpenWindow = false;
IsHideWindow = true;
e.Cancel = true;
Hide();

Expand All @@ -49,7 +46,7 @@ protected override void OnClosing(CancelEventArgs e)
tab.Deactivation();
}
#endif
base.OnClosed(e);
base.OnClosing(e);
}

protected override void FluentWindow_Opened(object? sender, EventArgs e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ protected override IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr l
// I retain the SystemBorder & ability resize the window in the transparent
// area over the drop shadows, meaning resize handles don't overlap the window

if (wParam != IntPtr.Zero && _owner?.Window.CanResize == true)
if (wParam != IntPtr.Zero &&
_owner?.Window.CanResize == true &&
_owner?.IsHideWindow == false)
{
var ncParams = Marshal.PtrToStructure<NCCALCSIZE_PARAMS>(lParam);

Expand All @@ -115,6 +117,8 @@ protected override IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr l
WindowState == WindowState.FullScreen)
{
//newSize.top += GetResizeHandleHeight();

_owner.IsNewSizeWindow = false;
}
else
{
Expand Down Expand Up @@ -217,8 +221,9 @@ private void EnsureExtended()
var marg = new Win32Interop.MARGINS();

// WS_OVERLAPPEDWINDOW
// 0x00C00000L 会导致标题栏有奇怪的白边
var style = 0x00000000L | 0x00080000L | 0x00040000L | 0x00020000L | 0x00010000L;
// 0x00C00000L 0x00080000L 不需要标题栏
// 0x00040000L 创建一个具有粗框的窗口可以用来调整窗口的大小
var style = 0x00000000L | 0X00800000L | 0x00020000L | 0x00010000L;

// This is causing the window to appear solid but is completely transparent. Weird...
//Win32Interop.GetWindowLongPtr(Hwnd, -16).ToInt32();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@
M7 7.5C7 4.42386 9.42386 2 12.5 2C15.5761 2 18 4.42386 18 7.5C18 10.5761 15.5761 13 12.5 13C12.0069 13 11.4935 12.9536 11 12.8199V13C11 13.5523 10.5523 14 10 14H9V15C9 15.5523 8.55228 16 8 16H7V16.5C7 17.3284 6.32843 18 5.5 18H3.5C2.67157 18 2 17.3284 2 16.5V14.9142C2 14.5164 2.15804 14.1349 2.43934 13.8536L6.98018 9.31271C7.11378 9.17912 7.17968 8.94454 7.12154 8.67456C7.04001 8.29598 7 7.89668 7 7.5ZM15 6C15 5.44772 14.5523 5 14 5C13.4477 5 13 5.44772 13 6C13 6.55228 13.4477 7 14 7C14.5523 7 15 6.55228 15 6Z
</StreamGeometry>

<StreamGeometry x:Key="BlockDrawing">
M10 2C14.4183 2 18 5.58172 18 10C18 14.4183 14.4183 18 10 18C5.58172 18 2 14.4183 2 10C2 5.58172 5.58172 2 10 2ZM10 3C6.13401 3 3 6.13401 3 10C3 13.866 6.13401 17 10 17C13.866 17 17 13.866 17 10C17 6.13401 13.866 3 10 3ZM6.5 9.5H13.5C13.7761 9.5 14 9.72386 14 10C14 10.2455 13.8231 10.4496 13.5899 10.4919L13.5 10.5H6.5C6.22386 10.5 6 10.2761 6 10C6 9.75454 6.17688 9.55039 6.41012 9.50806L6.5 9.5H13.5H6.5Z
<StreamGeometry x:Key="ShutdownDrawing">
M704 107.136a448 448 0 1 1-384 0v72.256a384 384 0 1 0 384 0z
M480 96V512a32 32 0 0 0 64 0V96a32 32 0 0 0-64 0z
</StreamGeometry>

<StreamGeometry x:Key="GridDrawing">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,14 @@
<Setter Property="(DockPanel.Dock)" Value="Right" />
</Style>

<Style Selector="StackPanel.Settings DockPanel > WrapPanel">
<Style Selector="StackPanel.Settings DockPanel > StackPanel">
<Setter Property="Margin" Value="0 0 100 0" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="(DockPanel.Dock)" Value="Left" />
</Style>

<Style Selector="StackPanel.Settings DockPanel :is(Control).right">
<Setter Property="Margin" Value="0" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="(DockPanel.Dock)" Value="Right" />
Expand Down
16 changes: 14 additions & 2 deletions src/ST.Client.Desktop.Avalonia/Application/UI/Styles/Window.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,21 @@
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="WindowStartupLocation" Value="CenterScreen"/>
<Setter Property="ExtendClientAreaTitleBarHeightHint" Value="{StaticResource TitleBarHeight}"/>
<Setter Property="TransparencyBackgroundFallback" Value="{DynamicResource BackgroundColorKey}" />
<Setter Property="Icon" Value="avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Assets/Icon.ico"/>
</Style>

<Style Selector="ExperimentalAcrylicBorder">
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="IsVisible" Value="True"/>
</Style>

<Style Selector=":is(Window):transparent ExperimentalAcrylicBorder">
<Setter Property="IsVisible" Value="False"/>
<Setter Property="Opacity" Value="{ReflectionBinding Value,Source={x:Static ms:UISettings.AcrylicOpacity},Mode=OneWay}"/>
</Style>


<!--<Style Selector="Button.SystemCaption">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="{x:Null}" />
Expand Down Expand Up @@ -133,10 +145,10 @@
<Setter Property="BorderThickness" Value="0 0 0 0" />
</Style>
<Style Selector=":is(wnd|ICoreWindow):is(wnd|Window):windows:extended /template/ TextBlock#TitleText">
<Style Selector=":is(wnd|Window):windows:extended /template/ TextBlock#TitleText">
<Setter Property="IsVisible" Value="False" />
</Style>
<Style Selector=":is(wnd|ICoreWindow):is(wnd|Window):windows:extended:customtitlebar /template/ Panel#DefaultTitleBar">
<Style Selector=":is(wnd|Window):windows:extended:customtitlebar /template/ Panel#DefaultTitleBar">
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Width" Value="10" />
</Style>-->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,79 +13,116 @@ public class EmptyControl : TemplatedControl
readonly INativeWindowApiService windowApiService = INativeWindowApiService.Instance;

Window window;
Window Parent;
Window ParentWindow;
IntPtr _Handle;
IntPtr _DwmHandle;
public EmptyControl()
{
//this.InitializeComponent();

this.GetObservable(IsVisibleProperty)
.Subscribe(x =>
{
if (x)
if (OperatingSystem2.IsWindows)
{
this.GetObservable(IsVisibleProperty)
.Subscribe(x =>
{
if (window == null)
if (x)
{
this.LayoutUpdated += EmptyControl_LayoutUpdated;
this.AttachedToVisualTree += EmptyControl_AttachedToVisualTree;
this.DetachedFromVisualTree += EmptyControl_DetachedFromVisualTree;
window = new Window
if (window == null)
{
Width = this.Bounds.Width,
Height = this.Bounds.Height,
Background = Avalonia.Media.Brushes.Transparent,
WindowStartupLocation = WindowStartupLocation.Manual,
WindowState = WindowState.Normal,
ExtendClientAreaToDecorationsHint = true,
ExtendClientAreaChromeHints = Avalonia.Platform.ExtendClientAreaChromeHints.PreferSystemChrome,
SystemDecorations = SystemDecorations.Full,
CanResize = false,
TransparencyLevelHint = WindowTransparencyLevel.Transparent,
ShowInTaskbar = false,
Focusable = false
};
if (Parent != null && VisualRoot != null)
EmptyControl_AttachedToVisualTree(null, new VisualTreeAttachmentEventArgs(Parent, VisualRoot));
this.LayoutUpdated += EmptyControl_LayoutUpdated;
this.AttachedToVisualTree += EmptyControl_AttachedToVisualTree;
this.DetachedFromVisualTree += EmptyControl_DetachedFromVisualTree;
window = new Window
{
Width = this.Bounds.Width,
Height = this.Bounds.Height,
Background = null,
WindowStartupLocation = WindowStartupLocation.Manual,
WindowState = WindowState.Normal,
ExtendClientAreaToDecorationsHint = true,
ExtendClientAreaTitleBarHeightHint = -1,
ExtendClientAreaChromeHints = Avalonia.Platform.ExtendClientAreaChromeHints.NoChrome,
SystemDecorations = SystemDecorations.Full,
CanResize = false,
TransparencyLevelHint = WindowTransparencyLevel.Transparent,
ShowInTaskbar = false,
Topmost = false,
Focusable = false,
IsEnabled = false,
ShowActivated = false,
IsTabStop = false,
IsHitTestVisible = false,
};
window.GotFocus += Window_GotFocus;
if (Parent != null && VisualRoot != null)
EmptyControl_AttachedToVisualTree(null, new VisualTreeAttachmentEventArgs(Parent, VisualRoot));
}
}
}
else
{
if (window != null)
else
{
if (Parent != null && VisualRoot != null)
EmptyControl_DetachedFromVisualTree(null, new VisualTreeAttachmentEventArgs(Parent, VisualRoot));
this.LayoutUpdated -= EmptyControl_LayoutUpdated;
this.AttachedToVisualTree -= EmptyControl_AttachedToVisualTree;
this.DetachedFromVisualTree -= EmptyControl_DetachedFromVisualTree;
window = null;
if (window != null)
{
if (Parent != null && VisualRoot != null)
EmptyControl_DetachedFromVisualTree(null, new VisualTreeAttachmentEventArgs(Parent, VisualRoot));
this.LayoutUpdated -= EmptyControl_LayoutUpdated;
this.AttachedToVisualTree -= EmptyControl_AttachedToVisualTree;
this.DetachedFromVisualTree -= EmptyControl_DetachedFromVisualTree;
window = null;
}
}
}
});
});
}
}

private void Window_GotFocus(object? sender, Avalonia.Input.GotFocusEventArgs e)
{
ParentWindow.Focus();
}

private void EmptyControl_DetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
if (OperatingSystem2.IsWindows && UISettings.EnableDesktopBackground.Value)
{
windowApiService.ReleaseBackground(_Handle);
Parent.PositionChanged -= Parent_PositionChanged;
Close();
}
windowApiService.ReleaseBackground(_DwmHandle);
ParentWindow.PositionChanged -= Parent_PositionChanged;
ParentWindow.Closing -= ParentWindow_Closing;
ParentWindow.GotFocus -= ParentWindow_GotFocus;
Close();
}

private void EmptyControl_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
if (OperatingSystem2.IsWindows && UISettings.EnableDesktopBackground.Value)
{
ParentWindow = (Window)e.Root;
ParentWindow.Topmost = true;
Show();
ParentWindow.Topmost = false;
ParentWindow.PositionChanged += Parent_PositionChanged;
ParentWindow.Closing += ParentWindow_Closing;
ParentWindow.GotFocus += ParentWindow_GotFocus;
ParentWindow.Opened += ParentWindow_Opened;
_Handle = window.PlatformImpl.Handle.Handle;
windowApiService.SetWindowPenetrate(_Handle);
//windowApiService.SetParentWindow(_Handle, ParentWindow.PlatformImpl.Handle.Handle);
_DwmHandle = windowApiService.SetDesktopBackgroundToWindow(
_Handle, (int)window.Width, (int)window.Height);
}

private void ParentWindow_Opened(object? sender, EventArgs e)
{
if (window != null)
Show();
Parent = (Window)e.Root;
Parent.PositionChanged += Parent_PositionChanged;
_Handle = Handle;
_Handle = windowApiService.SetDesktopBackgroundToWindow(
_Handle, (int)window.Width, (int)window.Height);
}

windowApiService.SetWindowPenetrate(Handle);
}
private void ParentWindow_GotFocus(object? sender, Avalonia.Input.GotFocusEventArgs e)
{
window.Topmost = true;
window.Topmost = false;
ParentWindow.Topmost = true;
ParentWindow.Topmost = false;
}

private void ParentWindow_Closing(object? sender, ComponentModel.CancelEventArgs e)
{
if (window != null)
window.Hide();
}

private void Parent_PositionChanged(object? sender, PixelPointEventArgs e)
Expand All @@ -95,13 +132,10 @@ private void Parent_PositionChanged(object? sender, PixelPointEventArgs e)

private void EmptyControl_LayoutUpdated(object? sender, System.EventArgs e)
{
if (OperatingSystem2.IsWindows && UISettings.EnableDesktopBackground.Value)
{
window.Position = this.PointToScreen(this.Bounds.Position);
window.Width = this.Bounds.Width;
window.Height = this.Bounds.Height;
windowApiService.BackgroundUpdate(_Handle, (int)window.Width, (int)window.Height);
}
window.Position = this.PointToScreen(this.Bounds.Position);
window.Width = this.Bounds.Width;
window.Height = this.Bounds.Height;
windowApiService.BackgroundUpdate(_DwmHandle, (int)window.Width, (int)window.Height);
//NativeMethods.SetWindowPos(HWND, NativeMethods.HWND_TOPMOST, window.Position.X, window.Position.Y, (int)window.Width, (int)window.Height, 0);
}

Expand All @@ -118,7 +152,7 @@ public void Show()

public IntPtr Handle
{
get { return window.PlatformImpl.Handle.Handle; }
get { return _Handle; }
}

public void Close()
Expand Down
Loading

0 comments on commit 951ec09

Please sign in to comment.