mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-27 04:34:18 +00:00
abstract plugin interface
This commit is contained in:
60
QuickLook.Plugin.IViewerPlugin/Helpers/DpiHelper.cs
Normal file
60
QuickLook.Plugin.IViewerPlugin/Helpers/DpiHelper.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
// 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.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace QuickLook.Common.Helpers
|
||||
{
|
||||
public static class DpiHelper
|
||||
{
|
||||
public const float DefaultDpi = 96;
|
||||
|
||||
public static ScaleFactor GetCurrentScaleFactor()
|
||||
{
|
||||
var g = Graphics.FromHwnd(IntPtr.Zero);
|
||||
var desktop = g.GetHdc();
|
||||
|
||||
var horizontalDpi = GetDeviceCaps(desktop, (int) DeviceCap.LOGPIXELSX);
|
||||
var verticalDpi = GetDeviceCaps(desktop, (int) DeviceCap.LOGPIXELSY);
|
||||
|
||||
return new ScaleFactor {Horizontal = horizontalDpi / DefaultDpi, Vertical = verticalDpi / DefaultDpi};
|
||||
}
|
||||
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
|
||||
private static extern int GetDeviceCaps(IntPtr hDC, int nIndex);
|
||||
|
||||
private enum DeviceCap
|
||||
{
|
||||
/// <summary>
|
||||
/// Logical pixels inch in X
|
||||
/// </summary>
|
||||
LOGPIXELSX = 88,
|
||||
/// <summary>
|
||||
/// Logical pixels inch in Y
|
||||
/// </summary>
|
||||
LOGPIXELSY = 90
|
||||
}
|
||||
|
||||
public struct ScaleFactor
|
||||
{
|
||||
public float Horizontal;
|
||||
public float Vertical;
|
||||
}
|
||||
}
|
||||
}
|
134
QuickLook.Plugin.IViewerPlugin/Helpers/FileHelper.cs
Normal file
134
QuickLook.Plugin.IViewerPlugin/Helpers/FileHelper.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
// 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.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace QuickLook.Common.Helpers
|
||||
{
|
||||
public class FileHelper
|
||||
{
|
||||
public static bool IsExecutable(string path, out string appFriendlyName)
|
||||
{
|
||||
appFriendlyName = string.Empty;
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
var isExe = new[] {".cmd", ".bat", ".pif", ".scf", ".exe", ".com", ".scr"}.Contains(ext.ToLower());
|
||||
|
||||
if (!isExe)
|
||||
return false;
|
||||
|
||||
appFriendlyName = FileVersionInfo.GetVersionInfo(path).FileDescription;
|
||||
if (string.IsNullOrEmpty(appFriendlyName))
|
||||
appFriendlyName = Path.GetFileName(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool GetAssocApplication(string path, out string appFriendlyName)
|
||||
{
|
||||
appFriendlyName = string.Empty;
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
|
||||
// no assoc. app. found
|
||||
if (string.IsNullOrEmpty(GetAssocApplicationNative(ext, AssocStr.Command)))
|
||||
if (string.IsNullOrEmpty(GetAssocApplicationNative(ext, AssocStr.AppId))) // UWP
|
||||
return false;
|
||||
|
||||
appFriendlyName = GetAssocApplicationNative(ext, AssocStr.FriendlyAppName);
|
||||
if (string.IsNullOrEmpty(appFriendlyName))
|
||||
appFriendlyName = Path.GetFileName(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra,
|
||||
[Out] StringBuilder sOut, [In] [Out] ref uint nOut);
|
||||
|
||||
private static string GetAssocApplicationNative(string fileExtensionIncludingDot, AssocStr str)
|
||||
{
|
||||
uint cOut = 0;
|
||||
if (AssocQueryString(AssocF.Verify | AssocF.RemapRunDll | AssocF.InitIgnoreUnknown, str,
|
||||
fileExtensionIncludingDot, null, null,
|
||||
ref cOut) != 1)
|
||||
return null;
|
||||
|
||||
var pOut = new StringBuilder((int) cOut);
|
||||
if (AssocQueryString(AssocF.Verify | AssocF.RemapRunDll | AssocF.InitIgnoreUnknown, str,
|
||||
fileExtensionIncludingDot, null, pOut,
|
||||
ref cOut) != 0)
|
||||
return null;
|
||||
|
||||
return pOut.ToString();
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
[Flags]
|
||||
private enum AssocF
|
||||
{
|
||||
InitNoRemapCLSID = 0x1,
|
||||
InitByExeName = 0x2,
|
||||
OpenByExeName = 0x2,
|
||||
InitDefaultToStar = 0x4,
|
||||
InitDefaultToFolder = 0x8,
|
||||
NoUserSettings = 0x10,
|
||||
NoTruncate = 0x20,
|
||||
Verify = 0x40,
|
||||
RemapRunDll = 0x80,
|
||||
NoFixUps = 0x100,
|
||||
IgnoreBaseClass = 0x200,
|
||||
InitIgnoreUnknown = 0x400,
|
||||
InitFixedProgid = 0x800,
|
||||
IsProtocol = 0x1000,
|
||||
InitForFile = 0x2000
|
||||
}
|
||||
|
||||
//[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
private enum AssocStr
|
||||
{
|
||||
Command = 1,
|
||||
Executable,
|
||||
FriendlyDocName,
|
||||
FriendlyAppName,
|
||||
NoOpen,
|
||||
ShellNewValue,
|
||||
DdeCommand,
|
||||
DdeIfExec,
|
||||
DdeApplication,
|
||||
DdeTopic,
|
||||
InfoTip,
|
||||
QuickTip,
|
||||
TileInfo,
|
||||
ContentType,
|
||||
DefaultIcon,
|
||||
ShellExtension,
|
||||
DropTarget,
|
||||
DelegateExecute,
|
||||
SupportedUriProtocols,
|
||||
ProgId,
|
||||
AppId,
|
||||
AppPublisher,
|
||||
AppIconReference,
|
||||
Max
|
||||
}
|
||||
}
|
||||
}
|
79
QuickLook.Plugin.IViewerPlugin/Helpers/ProcessHelper.cs
Normal file
79
QuickLook.Plugin.IViewerPlugin/Helpers/ProcessHelper.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
// 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.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using QuickLook.Common.NativeMethods;
|
||||
|
||||
namespace QuickLook.Common.Helpers
|
||||
{
|
||||
public class ProcessHelper
|
||||
{
|
||||
private const int ErrorInsufficientBuffer = 0x7A;
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public static void PerformAggressiveGC()
|
||||
{
|
||||
// delay some time to make sure that all windows are closed
|
||||
Task.Delay(2000).ContinueWith(t => GC.Collect(GC.MaxGeneration));
|
||||
}
|
||||
|
||||
public static bool IsRunningAsUWP()
|
||||
{
|
||||
try
|
||||
{
|
||||
uint len = 0;
|
||||
var r = Kernel32.GetCurrentPackageFullName(ref len, null);
|
||||
|
||||
return r == ErrorInsufficientBuffer;
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public static bool IsOnWindows10S()
|
||||
{
|
||||
const uint PRODUCT_CLOUD = 0x000000B2; // Windows 10 S
|
||||
const uint PRODUCT_CLOUDN = 0x000000B3; // Windows 10 S N
|
||||
|
||||
Kernel32.GetProductInfo(Environment.OSVersion.Version.Major,
|
||||
Environment.OSVersion.Version.Minor, 0, 0, out var osType);
|
||||
|
||||
return osType == PRODUCT_CLOUD || osType == PRODUCT_CLOUDN;
|
||||
}
|
||||
|
||||
public static void WriteLog(string msg)
|
||||
{
|
||||
var logFilePath = Path.Combine(SettingHelper.LocalDataPath, @"QuickLook.Exception.log");
|
||||
|
||||
using (var writer = new StreamWriter(new FileStream(logFilePath, FileMode.OpenOrCreate,
|
||||
FileAccess.ReadWrite, FileShare.Read)))
|
||||
{
|
||||
writer.BaseStream.Seek(0, SeekOrigin.End);
|
||||
|
||||
writer.WriteLine($"========{DateTime.Now}========");
|
||||
writer.WriteLine(msg);
|
||||
writer.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
116
QuickLook.Plugin.IViewerPlugin/Helpers/SettingHelper.cs
Normal file
116
QuickLook.Plugin.IViewerPlugin/Helpers/SettingHelper.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
// Copyright © 2018 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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Xml;
|
||||
|
||||
namespace QuickLook.Common.Helpers
|
||||
{
|
||||
public class SettingHelper
|
||||
{
|
||||
public static readonly string LocalDataPath =
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"pooi.moe\QuickLook\");
|
||||
|
||||
private static readonly Dictionary<string, XmlDocument> FileCache = new Dictionary<string, XmlDocument>();
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static T Get<T>(string id, T failsafe = default(T), Assembly calling = null)
|
||||
{
|
||||
if (!typeof(T).IsSerializable && !typeof(ISerializable).IsAssignableFrom(typeof(T)))
|
||||
throw new InvalidOperationException("A serializable Type is required");
|
||||
|
||||
var file = Path.Combine(LocalDataPath,
|
||||
(calling ?? Assembly.GetCallingAssembly()).GetName().Name + ".config");
|
||||
|
||||
var doc = GetConfigFile(file);
|
||||
|
||||
// try to get setting
|
||||
var s = GetSettingFromXml(doc, id, failsafe);
|
||||
|
||||
return s != null ? s : failsafe;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void Set(string id, object value, Assembly calling = null)
|
||||
{
|
||||
if (!value.GetType().IsSerializable)
|
||||
throw new NotSupportedException("New value if not serializable.");
|
||||
|
||||
var file = Path.Combine(LocalDataPath,
|
||||
(calling ?? Assembly.GetCallingAssembly()).GetName().Name + ".config");
|
||||
|
||||
WriteSettingToXml(GetConfigFile(file), id, value);
|
||||
}
|
||||
|
||||
private static T GetSettingFromXml<T>(XmlDocument doc, string id, T failsafe)
|
||||
{
|
||||
var v = doc.SelectSingleNode($@"/Settings/{id}");
|
||||
var result = v == null ? failsafe : (T) Convert.ChangeType(v.InnerText, typeof(T));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void WriteSettingToXml(XmlDocument doc, string id, object value)
|
||||
{
|
||||
var v = doc.SelectSingleNode($@"/Settings/{id}");
|
||||
|
||||
if (v != null)
|
||||
{
|
||||
v.InnerText = value.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
var node = doc.CreateNode(XmlNodeType.Element, id, doc.NamespaceURI);
|
||||
node.InnerText = value.ToString();
|
||||
doc.SelectSingleNode(@"/Settings").AppendChild(node);
|
||||
}
|
||||
|
||||
doc.Save(new Uri(doc.BaseURI).LocalPath);
|
||||
}
|
||||
|
||||
private static XmlDocument GetConfigFile(string file)
|
||||
{
|
||||
if (FileCache.ContainsKey(file))
|
||||
return FileCache[file];
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(file));
|
||||
if (!File.Exists(file))
|
||||
CreateNewConfig(file);
|
||||
|
||||
var doc = new XmlDocument();
|
||||
doc.Load(file);
|
||||
FileCache.Add(file, doc);
|
||||
return doc;
|
||||
}
|
||||
|
||||
private static void CreateNewConfig(string file)
|
||||
{
|
||||
using (var writer = XmlWriter.Create(file))
|
||||
{
|
||||
writer.WriteStartDocument();
|
||||
writer.WriteStartElement("Settings");
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndDocument();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
86
QuickLook.Plugin.IViewerPlugin/Helpers/TranslationHelper.cs
Normal file
86
QuickLook.Plugin.IViewerPlugin/Helpers/TranslationHelper.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Xml.XPath;
|
||||
|
||||
namespace QuickLook.Common.Helpers
|
||||
{
|
||||
public class TranslationHelper
|
||||
{
|
||||
private static readonly CultureInfo CurrentCultureInfo = CultureInfo.CurrentUICulture;
|
||||
//private static readonly CultureInfo CurrentCultureInfo = CultureInfo.GetCultureInfo("zh-CN");
|
||||
|
||||
private static readonly Dictionary<string, XPathNavigator> FileCache = new Dictionary<string, XPathNavigator>();
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static string Get(string id, string file = null, CultureInfo locale = null, string failsafe = null,
|
||||
Assembly calling = null)
|
||||
{
|
||||
if (file == null)
|
||||
file = Path.Combine(Path.GetDirectoryName((calling ?? Assembly.GetCallingAssembly()).Location),
|
||||
"Translations.config");
|
||||
|
||||
if (!File.Exists(file))
|
||||
return failsafe ?? id;
|
||||
|
||||
if (locale == null)
|
||||
locale = CurrentCultureInfo;
|
||||
|
||||
var nav = GetLangFile(file);
|
||||
|
||||
// try to get string
|
||||
var s = GetStringFromXml(nav, id, locale);
|
||||
if (s != null)
|
||||
return s;
|
||||
|
||||
// try again for parent language
|
||||
if (locale.Parent.Name != string.Empty)
|
||||
s = GetStringFromXml(nav, id, locale.Parent);
|
||||
if (s != null)
|
||||
return s;
|
||||
|
||||
// use fallback language
|
||||
s = GetStringFromXml(nav, id, CultureInfo.GetCultureInfo("en"));
|
||||
if (s != null)
|
||||
return s;
|
||||
|
||||
return failsafe ?? id;
|
||||
}
|
||||
|
||||
private static string GetStringFromXml(XPathNavigator nav, string id, CultureInfo locale)
|
||||
{
|
||||
var result = nav.SelectSingleNode($@"/Translations/{locale.Name}/{id}");
|
||||
|
||||
return result?.Value;
|
||||
}
|
||||
|
||||
private static XPathNavigator GetLangFile(string file)
|
||||
{
|
||||
if (FileCache.ContainsKey(file))
|
||||
return FileCache[file];
|
||||
|
||||
var res = new XPathDocument(file).CreateNavigator();
|
||||
FileCache.Add(file, res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
157
QuickLook.Plugin.IViewerPlugin/Helpers/WindowHelper.cs
Normal file
157
QuickLook.Plugin.IViewerPlugin/Helpers/WindowHelper.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
// 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)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user