Browse Source

move TaskbarList interop into UnmanagedMethods and a wrapper class.

pull/3849/head
Dan Walmsley 6 years ago
parent
commit
0e12f98419
  1. 22
      src/Windows/Avalonia.Win32/ITaskBarList2VTable.cs
  2. 55
      src/Windows/Avalonia.Win32/Interop/TaskBarList.cs
  3. 16
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  4. 37
      src/Windows/Avalonia.Win32/WindowImpl.cs

22
src/Windows/Avalonia.Win32/ITaskBarList2VTable.cs

@ -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;
}
}

55
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;
/// <summary>
/// Ported from https://github.com/chromium/chromium/blob/master/ui/views/win/fullscreen_handler.cc
/// </summary>
/// <param name="fullscreen">Fullscreen state.</param>
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<HrInit>((*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<MarkFullscreenWindow>((*ptr)->MarkFullscreenWindow);
}
s_markFullscreenWindowDelegate(s_taskBarList, hwnd, fullscreen);
}
}
}
}

16
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]

37
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
}
}
/// <summary>
/// Ported from https://github.com/chromium/chromium/blob/master/ui/views/win/fullscreen_handler.cc
/// </summary>
/// <param name="fullscreen">Fullscreen state.</param>
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<HrInit>((*ptr)->HrInit);
if (hrInit(_taskBarList) != HRESULT.S_OK)
{
_taskBarList = IntPtr.Zero;
}
}
}
if (_taskBarList != IntPtr.Zero)
{
var ptr = (ITaskBarList2VTable**)_taskBarList.ToPointer();
var markFullscreen = Marshal.GetDelegateForFunctionPointer<MarkFullscreenWindow>((*ptr)->MarkFullscreenWindow);
markFullscreen(_taskBarList, _hwnd, fullscreen);
}
}
/// <summary>
/// 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)

Loading…
Cancel
Save