From 10549d0213cd69086a9f023c01ced53724180fcf Mon Sep 17 00:00:00 2001 From: "XIECAN\\xiecan" Date: Fri, 29 Sep 2017 13:55:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=BA=E9=99=B7,=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E9=AB=98=E6=96=AF=E6=A8=A1=E7=B3=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ClipOne/util/WinAPIHelper.cs | 19 ++----- ClipOne/view/MainWindow.xaml.cs | 87 ++++++++++++++++++++++++++++----- ClipOne/view/OpacitySet.xaml.cs | 1 + 3 files changed, 81 insertions(+), 26 deletions(-) diff --git a/ClipOne/util/WinAPIHelper.cs b/ClipOne/util/WinAPIHelper.cs index 62bb341..0d2324e 100644 --- a/ClipOne/util/WinAPIHelper.cs +++ b/ClipOne/util/WinAPIHelper.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using static ClipOne.view.MainWindow; namespace ClipOne.util { @@ -82,25 +83,13 @@ public POINT(int x, int y) public static extern IntPtr GetDesktopWindow(); [DllImport("user32", EntryPoint = "GetTopWindow")] public static extern IntPtr GetTopWindow(); - - /*wCmd指定结果窗口与源窗口的关系,它们建立在下述常数基础上: - GW_CHILD - 寻找源窗口的第一个子窗口 - GW_HWNDFIRST - 为一个源子窗口寻找第一个兄弟(同级)窗口,或寻找第一个顶级窗口 - GW_HWNDLAST - 为一个源子窗口寻找最后一个兄弟(同级)窗口,或寻找最后一个顶级窗口 - GW_HWNDNEXT - 为源窗口寻找下一个兄弟窗口 - GW_HWNDPREV - 为源窗口寻找前一个兄弟窗口 - GW_OWNER - 寻找窗口的所有者 - */ + [DllImport("user32.dll", EntryPoint = "GetWindow")]//获取窗体句柄,hwnd为源窗口句柄 public static extern IntPtr GetWindow( IntPtr hwnd, int wCmd ); + [DllImport("user32.dll")] + internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data); } } diff --git a/ClipOne/view/MainWindow.xaml.cs b/ClipOne/view/MainWindow.xaml.cs index 74ab206..0aacb93 100644 --- a/ClipOne/view/MainWindow.xaml.cs +++ b/ClipOne/view/MainWindow.xaml.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -53,7 +54,15 @@ public partial class MainWindow : Window /// ChromiumWebBrowser webView; + /// + /// 隐藏时将left设置为该值 + /// + private int HideLeftValue = -10000; + /// + /// 透明度转换比例 + /// + private double OpacityRatio = 0.06; /// /// 供浏览器JS回调的接口 @@ -157,7 +166,7 @@ public MainWindow() private void Window_Loaded(object sender, RoutedEventArgs e) { - + if (!Directory.Exists(cacheDir)) { Directory.CreateDirectory(cacheDir); @@ -196,7 +205,9 @@ private void Window_Loaded(object sender, RoutedEventArgs e) //初始化预览窗口 InitPreviewForm(); - + + + } @@ -334,9 +345,10 @@ private void InitialTray() opaSet.Click += (sender, e) => { isNotAllowHide = true; + DiyShow(); ShowWindowAndList(); - OpacitySet os = new OpacitySet(this, (1 - opacityValue) / 0.02); + OpacitySet os = new OpacitySet(this, (1 - opacityValue) / OpacityRatio); os.Topmost = true; os.ShowDialog(); @@ -573,7 +585,7 @@ private void SaveSettings() /// public void ChangeOpacity(double value) { - opacityValue = 1 - value * 0.02; + opacityValue = 1 - value * OpacityRatio; this.Opacity = opacityValue; settingsMap["opacity"] = opacityValue.ToString(); SaveSettings(); @@ -714,7 +726,7 @@ public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bo if (hotkeyAtom == wParam.ToInt32()) { - if (this.Opacity != opacityValue) { + if (this.Left == HideLeftValue) { activeHwnd = WinAPIHelper.GetForegroundWindow(); DiyShow(); } @@ -1076,8 +1088,26 @@ private void Window_SourceInitialized(object sender, EventArgs e) exStyle |= (int)0x00000080; WinAPIHelper.SetWindowLong(wpfHwnd, -20, exStyle); + //高斯模糊 + var accent = new AccentPolicy(); + accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND; + + var accentStructSize = Marshal.SizeOf(accent); + + var accentPtr = Marshal.AllocHGlobal(accentStructSize); + Marshal.StructureToPtr(accent, accentPtr, false); + + var data = new WindowCompositionAttributeData(); + data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY; + data.SizeOfData = accentStructSize; + data.Data = accentPtr; + + WinAPIHelper.SetWindowCompositionAttribute(wpfHwnd, ref data); + + Marshal.FreeHGlobal(accentPtr); DiyHide(); + } //显示窗体,透明度为事先设置的值. @@ -1085,7 +1115,8 @@ private void DiyShow() { this.Topmost = true; this.Activate(); - this.Opacity = opacityValue; + //this.Opacity = opacityValue; + @@ -1097,13 +1128,15 @@ private void DiyShow() private void DiyHide() { this.Topmost = false; - - WinAPIHelper.SetForegroundWindow(activeHwnd); + if (activeHwnd != IntPtr.Zero) { + WinAPIHelper.SetForegroundWindow(activeHwnd); + } webView?.GetBrowser()?.MainFrame.ExecuteJavaScriptAsync("hide()"); - this.Opacity = 0; - // this.Hide(); + //this.Opacity = 0; + this.Left = HideLeftValue; + // this.Hide(); } - + internal class MenuHandler : IContextMenuHandler @@ -1136,10 +1169,42 @@ public bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame return false; } } + internal enum AccentState + { + ACCENT_DISABLED = 0, + ACCENT_ENABLE_GRADIENT = 1, + ACCENT_ENABLE_TRANSPARENTGRADIENT = 2, + ACCENT_ENABLE_BLURBEHIND = 3, + ACCENT_INVALID_STATE = 4 + } + [StructLayout(LayoutKind.Sequential)] + internal struct AccentPolicy + { + public AccentState AccentState; + public int AccentFlags; + public int GradientColor; + public int AnimationId; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct WindowCompositionAttributeData + { + public WindowCompositionAttribute Attribute; + public IntPtr Data; + public int SizeOfData; + } + + internal enum WindowCompositionAttribute + { + // ... + WCA_ACCENT_POLICY = 19 + // ... + } } + } diff --git a/ClipOne/view/OpacitySet.xaml.cs b/ClipOne/view/OpacitySet.xaml.cs index 872803e..17a4426 100644 --- a/ClipOne/view/OpacitySet.xaml.cs +++ b/ClipOne/view/OpacitySet.xaml.cs @@ -18,6 +18,7 @@ public OpacitySet(MainWindow window,double opacityValue) InitializeComponent(); this.window = window; sliderOpa.Value = opacityValue; + } private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)