Files
mpv.net/src/MpvNet.Windows/Help/WinApiHelp.cs
2024-08-10 11:19:23 +02:00

131 lines
3.8 KiB
C#

using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using static MpvNet.Windows.Native.WinApi;
namespace MpvNet.Windows.Help;
public static class WinApiHelp
{
public static Version WindowsTen1607 { get; } = new Version(10, 0, 14393); // Windows 10 1607
public static int GetResizeBorder(int v)
{
switch (v)
{
case 1 /* WMSZ_LEFT */ : return 3;
case 3 /* WMSZ_TOP */ : return 2;
case 2 /* WMSZ_RIGHT */ : return 3;
case 6 /* WMSZ_BOTTOM */ : return 2;
case 4 /* WMSZ_TOPLEFT */ : return 1;
case 5 /* WMSZ_TOPRIGHT */ : return 1;
case 7 /* WMSZ_BOTTOMLEFT */ : return 3;
case 8 /* WMSZ_BOTTOMRIGHT */ : return 3;
default: return -1;
}
}
public static void AdjustWindowRectangle(IntPtr hwnd, ref RECT rc, int dpi)
{
uint style = (uint)GetWindowLongPtr(hwnd, -16); // GWL_STYLE
uint styleEx = (uint)GetWindowLongPtr(hwnd, -20); // GWL_EXSTYLE
if (Environment.OSVersion.Version >= WindowsTen1607)
AdjustWindowRectExForDpi(ref rc, style, false, styleEx, (uint)dpi);
else
AdjustWindowRect(ref rc, style, false);
}
public static void AddWindowBorders(IntPtr hwnd, ref RECT rc, int dpi, bool changeTop)
{
RECT win = rc;
AdjustWindowRectangle(hwnd, ref rc, dpi);
if (changeTop)
{
int top = rc.Top;
top -= rc.Top - win.Top;
rc = new RECT(rc.Left, top, rc.Right, rc.Bottom);
}
}
public static void SubtractWindowBorders(IntPtr hwnd, ref RECT rc, int dpi, bool changeTop)
{
RECT r = new RECT();
AddWindowBorders(hwnd, ref r, dpi, changeTop);
rc.Left -= r.Left;
rc.Top -= r.Top;
rc.Right -= r.Right;
rc.Bottom -= r.Bottom;
}
public static int GetTitleBarHeight(IntPtr hwnd, int dpi)
{
RECT rect = new RECT();
AdjustWindowRectangle(hwnd, ref rect, dpi);
return -rect.Top;
}
public static Rectangle GetWorkingArea(IntPtr handle, Rectangle workingArea)
{
if (handle != IntPtr.Zero && GetDwmWindowRect(handle, out RECT dwmRect) &&
GetWindowRect(handle, out RECT rect))
{
int left = workingArea.Left;
int top = workingArea.Top;
int right = workingArea.Right;
int bottom = workingArea.Bottom;
left += rect.Left - dwmRect.Left;
top -= rect.Top - dwmRect.Top;
right -= dwmRect.Right - rect.Right;
bottom -= dwmRect.Bottom - rect.Bottom;
return new Rectangle(left, top, right - left, bottom - top);
}
return workingArea;
}
public static bool GetDwmWindowRect(IntPtr handle, out RECT rect)
{
const uint DWMWA_EXTENDED_FRAME_BOUNDS = 9;
return 0 == DwmGetWindowAttribute(handle, DWMWA_EXTENDED_FRAME_BOUNDS,
out rect, (uint)Marshal.SizeOf<RECT>());
}
public static string GetAppPathForExtension(params string[] extensions)
{
foreach (string it in extensions)
{
string extension = it;
if (!extension.StartsWith("."))
extension = "." + extension;
uint c = 0U;
if (AssocQueryString(0x40, 2, extension, null, null, ref c) == 1)
{
if (c > 0L)
{
var sb = new StringBuilder((int)c);
if (0 == AssocQueryString(0x40, 2, extension, default, sb, ref c))
{
string ret = sb.ToString();
if (File.Exists(ret))
return ret;
}
}
}
}
return "";
}
}