add SystemMenuHook

This commit is contained in:
NaBian committed 2019-08-21 21:48:05 +08:00
1 parent a9720f080b
commit 3d32e17afd
15 files changed
+236 -219

No files matched your search

@@ -1,54 +0,0 @@
using System;
using System.Text;
namespace HandyControl.Tools
{
internal class CreateParams
{
public string ClassName { get; set; }
public string Caption { get; set; }
public int Style { get; set; }
public int ExStyle{ get; set; }
public int ClassStyle { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public IntPtr Parent { get; set; }
public object Param { get; set; }
public override string ToString()
{
var sb = new StringBuilder(64);
sb.Append("CreateParams {'");
sb.Append(ClassName);
sb.Append("', '");
sb.Append(Caption);
sb.Append("', 0x");
sb.Append(Convert.ToString(Style, 16));
sb.Append(", 0x");
sb.Append(Convert.ToString(ExStyle, 16));
sb.Append(", {");
sb.Append(X);
sb.Append(", ");
sb.Append(Y);
sb.Append(", ");
sb.Append(Width);
sb.Append(", ");
sb.Append(Height);
sb.Append("}");
sb.Append("}");
return sb.ToString();
}
}
}
@@ -1,17 +1,12 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using HandyControl.Tools.Interop;
using HandyControl.Tools.Extension;
namespace HandyControl.Tools
{
public class VisualHelper
public static class VisualHelper
{
internal static VisualStateGroup TryGetVisualStateGroup(DependencyObject d, string groupName)
{
@@ -52,136 +47,7 @@ namespace HandyControl.Tools
return default;
}
/// <summary>
/// 获取当前应用中处于激活的一个窗口
/// </summary>
/// <returns></returns>
public static Window GetActiveWindow() => Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
private static readonly BitArray _cacheValid = new BitArray((int)CacheSlot.NumSlots);
private static bool _setDpiX = true;
private static bool _dpiInitialized;
private static readonly object _dpiLock = new object();
private static int _dpi;
internal static int Dpi
{
[SecurityCritical, SecuritySafeCritical]
get
{
if (!_dpiInitialized)
{
lock (_dpiLock)
{
if (!_dpiInitialized)
{
var desktopWnd = new HandleRef(null, IntPtr.Zero);
// Win32Exception will get the Win32 error code so we don't have to
var dc = UnsafeNativeMethods.GetDC(desktopWnd);
// Detecting error case from unmanaged call, required by PREsharp to throw a Win32Exception
if (dc == IntPtr.Zero)
{
throw new Win32Exception();
}
try
{
_dpi = UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, dc), NativeMethods.LOGPIXELSY);
_dpiInitialized = true;
}
finally
{
UnsafeNativeMethods.ReleaseDC(desktopWnd, new HandleRef(null, dc));
}
}
}
}
return _dpi;
}
}
private static int _dpiX;
internal static int DpiX
{
[SecurityCritical, SecuritySafeCritical]
get
{
if (_setDpiX)
{
lock (_cacheValid)
{
if (_setDpiX)
{
_setDpiX = false;
var desktopWnd = new HandleRef(null, IntPtr.Zero);
var dc = UnsafeNativeMethods.GetDC(desktopWnd);
if (dc == IntPtr.Zero)
{
throw new Win32Exception();
}
try
{
_dpiX = UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, dc), NativeMethods.LOGPIXELSX);
_cacheValid[(int)CacheSlot.DpiX] = true;
}
finally
{
UnsafeNativeMethods.ReleaseDC(desktopWnd, new HandleRef(null, dc));
}
}
}
}
return _dpiX;
}
}
private static Thickness _windowResizeBorderThickness;
internal static Thickness WindowResizeBorderThickness
{
[SecurityCritical]
get
{
lock (_cacheValid)
{
while (!_cacheValid[(int)CacheSlot.WindowResizeBorderThickness])
{
_cacheValid[(int)CacheSlot.WindowResizeBorderThickness] = true;
var frameSize = new Size(NativeMethods.GetSystemMetrics(SM.CXSIZEFRAME), NativeMethods.GetSystemMetrics(SM.CYSIZEFRAME));
var frameSizeInDips = DpiHelper.DeviceSizeToLogical(frameSize, DpiX / 96.0, Dpi / 96.0);
_windowResizeBorderThickness = new Thickness(frameSizeInDips.Width, frameSizeInDips.Height, frameSizeInDips.Width, frameSizeInDips.Height);
}
}
return _windowResizeBorderThickness;
}
}
public static Thickness WindowMaximizedPadding
{
get
{
#if netle40
return WindowResizeBorderThickness;
#elif Core
var hdc = UnsafeNativeMethods.GetDC(IntPtr.Zero);
var scale = UnsafeNativeMethods.GetDeviceCaps(hdc, NativeMethods.DESKTOPVERTRES) / (float)UnsafeNativeMethods.GetDeviceCaps(hdc, NativeMethods.VERTRES);
UnsafeNativeMethods.ReleaseDC(IntPtr.Zero, hdc);
return WindowResizeBorderThickness.Add(new Thickness(4 * scale));
#else
return WindowResizeBorderThickness.Add(new Thickness(4));
#endif
}
}
public static IntPtr GetHandle(this Visual visual) =>
(PresentationSource.FromVisual(visual) as HwndSource)?.Handle ?? IntPtr.Zero;
}
}
@@ -0,0 +1,152 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Windows;
using System.Windows.Interop;
using HandyControl.Tools.Extension;
using HandyControl.Tools.Interop;
namespace HandyControl.Tools
{
public static class WindowHelper
{
/// <summary>
/// 获取当前应用中处于激活的一个窗口
/// </summary>
/// <returns></returns>
public static Window GetActiveWindow() => Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
private static readonly BitArray _cacheValid = new BitArray((int)CacheSlot.NumSlots);
private static bool _setDpiX = true;
private static bool _dpiInitialized;
private static readonly object _dpiLock = new object();
private static int _dpi;
internal static int Dpi
{
[SecurityCritical, SecuritySafeCritical]
get
{
if (!_dpiInitialized)
{
lock (_dpiLock)
{
if (!_dpiInitialized)
{
var desktopWnd = new HandleRef(null, IntPtr.Zero);
// Win32Exception will get the Win32 error code so we don't have to
var dc = UnsafeNativeMethods.GetDC(desktopWnd);
// Detecting error case from unmanaged call, required by PREsharp to throw a Win32Exception
if (dc == IntPtr.Zero)
{
throw new Win32Exception();
}
try
{
_dpi = UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, dc), NativeMethods.LOGPIXELSY);
_dpiInitialized = true;
}
finally
{
UnsafeNativeMethods.ReleaseDC(desktopWnd, new HandleRef(null, dc));
}
}
}
}
return _dpi;
}
}
private static int _dpiX;
internal static int DpiX
{
[SecurityCritical, SecuritySafeCritical]
get
{
if (_setDpiX)
{
lock (_cacheValid)
{
if (_setDpiX)
{
_setDpiX = false;
var desktopWnd = new HandleRef(null, IntPtr.Zero);
var dc = UnsafeNativeMethods.GetDC(desktopWnd);
if (dc == IntPtr.Zero)
{
throw new Win32Exception();
}
try
{
_dpiX = UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, dc), NativeMethods.LOGPIXELSX);
_cacheValid[(int)CacheSlot.DpiX] = true;
}
finally
{
UnsafeNativeMethods.ReleaseDC(desktopWnd, new HandleRef(null, dc));
}
}
}
}
return _dpiX;
}
}
private static Thickness _windowResizeBorderThickness;
internal static Thickness WindowResizeBorderThickness
{
[SecurityCritical]
get
{
lock (_cacheValid)
{
while (!_cacheValid[(int)CacheSlot.WindowResizeBorderThickness])
{
_cacheValid[(int)CacheSlot.WindowResizeBorderThickness] = true;
var frameSize = new Size(NativeMethods.GetSystemMetrics(SM.CXSIZEFRAME), NativeMethods.GetSystemMetrics(SM.CYSIZEFRAME));
var frameSizeInDips = DpiHelper.DeviceSizeToLogical(frameSize, DpiX / 96.0, Dpi / 96.0);
_windowResizeBorderThickness = new Thickness(frameSizeInDips.Width, frameSizeInDips.Height, frameSizeInDips.Width, frameSizeInDips.Height);
}
}
return _windowResizeBorderThickness;
}
}
public static Thickness WindowMaximizedPadding
{
get
{
#if netle40
return WindowResizeBorderThickness;
#elif Core
var hdc = UnsafeNativeMethods.GetDC(IntPtr.Zero);
var scale = UnsafeNativeMethods.GetDeviceCaps(hdc, NativeMethods.DESKTOPVERTRES) / (float)UnsafeNativeMethods.GetDeviceCaps(hdc, NativeMethods.VERTRES);
UnsafeNativeMethods.ReleaseDC(IntPtr.Zero, hdc);
return WindowResizeBorderThickness.Add(new Thickness(4 * scale));
#else
return WindowResizeBorderThickness.Add(new Thickness(4));
#endif
}
}
public static IntPtr CreateHandle() => new WindowInteropHelper(new Window()).EnsureHandle();
public static IntPtr GetHandle(this Window window) => new WindowInteropHelper(window).EnsureHandle();
}
}