Files
QuickLook/QuickLook.Common/Helpers/WindowHelper.cs
2018-06-23 17:41:21 +03:00

159 lines
5.4 KiB
C#

// Copyright © 2017 Paddy Xu
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using System.Windows.Media;
using QuickLook.Common.NativeMethods;
namespace QuickLook.Common.Helpers
{
public static class WindowHelper
{
public enum WindowCompositionAttribute
{
WcaAccentPolicy = 19
}
public static Rect GetCurrentWindowRect()
{
var screen = Screen.FromPoint(Cursor.Position).WorkingArea;
var scale = DpiHelper.GetCurrentScaleFactor();
return new Rect(
new Point(screen.X / scale.Horizontal, screen.Y / scale.Vertical),
new Size(screen.Width / scale.Horizontal, screen.Height / scale.Vertical));
}
public static void BringToFront(this Window window, bool keep)
{
var handle = new WindowInteropHelper(window).Handle;
User32.SetWindowPos(handle, User32.HWND_TOPMOST, 0, 0, 0, 0,
User32.SWP_NOMOVE | User32.SWP_NOSIZE | User32.SWP_NOACTIVATE);
if (!keep)
User32.SetWindowPos(handle, User32.HWND_NOTOPMOST, 0, 0, 0, 0,
User32.SWP_NOMOVE | User32.SWP_NOSIZE | User32.SWP_NOACTIVATE);
}
public static void MoveWindow(this Window window,
double left,
double top,
double width,
double height)
{
int pxLeft = 0, pxTop = 0;
if (left != 0 || top != 0)
TransformToPixels(window, left, top,
out pxLeft, out pxTop);
TransformToPixels(window, width, height,
out var pxWidth, out var pxHeight);
User32.MoveWindow(new WindowInteropHelper(window).Handle, pxLeft, pxTop, pxWidth, pxHeight, true);
}
private static void TransformToPixels(this Visual visual,
double unitX,
double unitY,
out int pixelX,
out int pixelY)
{
Matrix matrix;
var source = PresentationSource.FromVisual(visual);
if (source != null)
matrix = source.CompositionTarget.TransformToDevice;
else
using (var src = new HwndSource(new HwndSourceParameters()))
{
matrix = src.CompositionTarget.TransformToDevice;
}
pixelX = (int) Math.Round(matrix.M11 * unitX);
pixelY = (int) Math.Round(matrix.M22 * unitY);
}
public static bool IsForegroundWindowBelongToSelf()
{
var hwnd = User32.GetForegroundWindow();
if (hwnd == IntPtr.Zero)
return false;
User32.GetWindowThreadProcessId(hwnd, out var procId);
return procId == Process.GetCurrentProcess().Id;
}
public static void SetNoactivate(WindowInteropHelper window)
{
User32.SetWindowLong(window.Handle, User32.GWL_EXSTYLE,
User32.GetWindowLong(window.Handle, User32.GWL_EXSTYLE) |
User32.WS_EX_NOACTIVATE);
}
public static void EnableBlur(Window window)
{
var accent = new AccentPolicy();
var accentStructSize = Marshal.SizeOf(accent);
accent.AccentState = AccentState.AccentEnableBlurbehind;
accent.AccentFlags = 2;
accent.GradientColor = 0x99FFFFFF;
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false);
var data = new WindowCompositionAttributeData
{
Attribute = WindowCompositionAttribute.WcaAccentPolicy,
SizeOfData = accentStructSize,
Data = accentPtr
};
User32.SetWindowCompositionAttribute(new WindowInteropHelper(window).Handle, ref data);
Marshal.FreeHGlobal(accentPtr);
}
[StructLayout(LayoutKind.Sequential)]
public struct WindowCompositionAttributeData
{
public WindowCompositionAttribute Attribute;
public IntPtr Data;
public int SizeOfData;
}
private enum AccentState
{
AccentDisabled = 0,
AccentEnableGradient = 1,
AccentEnableTransparentgradient = 2,
AccentEnableBlurbehind = 3,
AccentInvalidState = 4
}
[StructLayout(LayoutKind.Sequential)]
private struct AccentPolicy
{
public AccentState AccentState;
public int AccentFlags;
public uint GradientColor;
public readonly int AnimationId;
}
}
}