diff --git a/src/Windows/Avalonia.Win32/ITaskBarList2VTable.cs b/src/Windows/Avalonia.Win32/ITaskBarList2VTable.cs deleted file mode 100644 index c187251ee3..0000000000 --- a/src/Windows/Avalonia.Win32/ITaskBarList2VTable.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using static Avalonia.Win32.Interop.UnmanagedMethods; - -namespace Avalonia.Win32 -{ - delegate void MarkFullscreenWindow(IntPtr This, IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fullscreen); - delegate HRESULT HrInit(IntPtr This); - - struct ITaskBarList2VTable - { - public IntPtr IUnknown1; - public IntPtr IUnknown2; - public IntPtr IUnknown3; - public IntPtr HrInit; - public IntPtr AddTab; - public IntPtr DeleteTab; - public IntPtr ActivateTab; - public IntPtr SetActiveAlt; - public IntPtr MarkFullscreenWindow; - } -} diff --git a/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs b/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs new file mode 100644 index 0000000000..1b01ebbe7f --- /dev/null +++ b/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs @@ -0,0 +1,55 @@ +using System; +using System.Runtime.InteropServices; +using static Avalonia.Win32.Interop.UnmanagedMethods; + +namespace Avalonia.Win32.Interop +{ + internal class TaskBarList + { + private static IntPtr s_taskBarList; + private static HrInit s_hrInitDelegate; + private static MarkFullscreenWindow s_markFullscreenWindowDelegate; + + /// + /// Ported from https://github.com/chromium/chromium/blob/master/ui/views/win/fullscreen_handler.cc + /// + /// Fullscreen state. + public static unsafe void MarkFullscreen(IntPtr hwnd, bool fullscreen) + { + if (s_taskBarList == IntPtr.Zero) + { + Guid clsid = ShellIds.TaskBarList; + Guid iid = ShellIds.ITaskBarList2; + + int result = CoCreateInstance(ref clsid, IntPtr.Zero, 1, ref iid, out s_taskBarList); + + if (s_taskBarList != IntPtr.Zero) + { + var ptr = (ITaskBarList2VTable**)s_taskBarList.ToPointer(); + + if (s_hrInitDelegate is null) + { + s_hrInitDelegate = Marshal.GetDelegateForFunctionPointer((*ptr)->HrInit); + } + + if (s_hrInitDelegate(s_taskBarList) != HRESULT.S_OK) + { + s_taskBarList = IntPtr.Zero; + } + } + } + + if (s_taskBarList != IntPtr.Zero) + { + var ptr = (ITaskBarList2VTable**)s_taskBarList.ToPointer(); + + if (s_markFullscreenWindowDelegate is null) + { + s_markFullscreenWindowDelegate = Marshal.GetDelegateForFunctionPointer((*ptr)->MarkFullscreenWindow); + } + + s_markFullscreenWindowDelegate(s_taskBarList, hwnd, fullscreen); + } + } + } +} diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index 43beb35e45..5601ccbafe 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -1880,6 +1880,22 @@ namespace Avalonia.Win32.Interop [MarshalAs(UnmanagedType.LPWStr)] public string pszSpec; } + + public delegate void MarkFullscreenWindow(IntPtr This, IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fullscreen); + public delegate HRESULT HrInit(IntPtr This); + + public struct ITaskBarList2VTable + { + public IntPtr IUnknown1; + public IntPtr IUnknown2; + public IntPtr IUnknown3; + public IntPtr HrInit; + public IntPtr AddTab; + public IntPtr DeleteTab; + public IntPtr ActivateTab; + public IntPtr SetActiveAlt; + public IntPtr MarkFullscreenWindow; + } } [Flags] diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 549a568fa2..51d60cc970 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -39,7 +39,6 @@ namespace Avalonia.Win32 private SavedWindowInfo _savedWindowInfo; private bool _isFullScreenActive; - private IntPtr _taskBarList; #if USE_MANAGED_DRAG private readonly ManagedWindowResizeDragHelper _managedDrag; @@ -545,40 +544,6 @@ namespace Avalonia.Win32 } } - /// - /// Ported from https://github.com/chromium/chromium/blob/master/ui/views/win/fullscreen_handler.cc - /// - /// Fullscreen state. - private unsafe void MarkFullscreen(bool fullscreen) - { - if (_taskBarList == IntPtr.Zero) - { - Guid clsid = ShellIds.TaskBarList; - Guid iid = ShellIds.ITaskBarList2; - - int result = CoCreateInstance(ref clsid, IntPtr.Zero, 1, ref iid, out _taskBarList); - - if (_taskBarList != IntPtr.Zero) - { - var ptr = (ITaskBarList2VTable**)_taskBarList.ToPointer(); - - var hrInit = Marshal.GetDelegateForFunctionPointer((*ptr)->HrInit); - - if (hrInit(_taskBarList) != HRESULT.S_OK) - { - _taskBarList = IntPtr.Zero; - } - } - } - - if (_taskBarList != IntPtr.Zero) - { - var ptr = (ITaskBarList2VTable**)_taskBarList.ToPointer(); - var markFullscreen = Marshal.GetDelegateForFunctionPointer((*ptr)->MarkFullscreenWindow); - markFullscreen(_taskBarList, _hwnd, fullscreen); - } - } - /// /// Ported from https://github.com/chromium/chromium/blob/master/ui/views/win/fullscreen_handler.cc /// Method must only be called from inside UpdateWindowProperties. @@ -634,7 +599,7 @@ namespace Avalonia.Win32 UpdateWindowProperties(_windowProperties, true); } - MarkFullscreen(fullscreen); + TaskBarList.MarkFullscreen(_hwnd, fullscreen); } private void ShowWindow(WindowState state)