PowerToys/Wox/Helper/WindowIntelopHelper.cs
Boris Makogonyuk 83985aa44c Added Pixel to Device Independent Pixel transformation to WindowIntelopHelper
MainWindow GetWindowsTop and GetWindowsLeft will use DIP when searching for the center of the screen
2015-12-13 04:22:01 +01:00

120 lines
4.1 KiB
C#

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using System.Windows.Media;
using Point = System.Windows.Point;
namespace Wox.Helper
{
public class WindowIntelopHelper
{
private const int GWL_STYLE = -16; //WPF's Message code for Title Bar's Style
private const int WS_SYSMENU = 0x80000; //WPF's Message code for System Menu
private static IntPtr _hwnd_shell;
private static IntPtr _hwnd_desktop;
//Accessors for shell and desktop handlers
//Will set the variables once and then will return them
private static IntPtr HWND_SHELL
{
get
{
return _hwnd_shell != IntPtr.Zero ? _hwnd_shell : _hwnd_shell = GetShellWindow();
}
}
private static IntPtr HWND_DESKTOP
{
get
{
return _hwnd_desktop != IntPtr.Zero ? _hwnd_desktop : _hwnd_desktop = GetDesktopWindow();
}
}
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetShellWindow();
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowRect(IntPtr hwnd, out RECT rc);
public static bool IsWindowFullscreen()
{
RECT foreWinBounds;
Rectangle screenBounds;
var hWnd = GetForegroundWindow();
if (!hWnd.Equals(IntPtr.Zero))
{
if (!(hWnd.Equals(HWND_DESKTOP) || hWnd.Equals(HWND_SHELL)))
{
GetWindowRect(hWnd, out foreWinBounds);
screenBounds = Screen.FromHandle(hWnd).Bounds;
if ((foreWinBounds.Bottom - foreWinBounds.Top) == screenBounds.Height && (foreWinBounds.Right - foreWinBounds.Left) == screenBounds.Width)
{
return true;
}
}
}
return false;
}
/// <summary>
/// disable windows toolbar's control box
/// this will also disable system menu with Alt+Space hotkey
/// </summary>
public static void DisableControlBox(Window win)
{
var hwnd = new WindowInteropHelper(win).Handle;
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
}
/// <summary>
/// Transforms pixels to Device Independent Pixels used by WPF
/// </summary>
/// <param name="visual">current window, required to get presentation source</param>
/// <param name="unitX">horizontal position in pixels</param>
/// <param name="unitY">vertical position in pixels</param>
/// <returns>point containing device independent pixels</returns>
public static Point TransformPixelsToDIP(Visual visual, double unitX, double unitY)
{
Matrix matrix;
var source = PresentationSource.FromVisual(visual);
if (source != null)
{
matrix = source.CompositionTarget.TransformFromDevice;
}
else
{
using (var src = new HwndSource(new HwndSourceParameters()))
{
matrix = src.CompositionTarget.TransformFromDevice;
}
}
return new Point((int) (matrix.M11*unitX), (int) (matrix.M22*unitY));
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
}
}