diff --git a/Wox/Helper/WindowIntelopHelper.cs b/Wox/Helper/WindowIntelopHelper.cs index 4a0223a19e..a61665b54d 100644 --- a/Wox/Helper/WindowIntelopHelper.cs +++ b/Wox/Helper/WindowIntelopHelper.cs @@ -4,6 +4,8 @@ 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 { @@ -80,6 +82,32 @@ namespace Wox.Helper SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU); } + /// + /// Transforms pixels to Device Independent Pixels used by WPF + /// + /// current window, required to get presentation source + /// horizontal position in pixels + /// vertical position in pixels + /// point containing device independent pixels + 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 { diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 04957f26c2..27dfc8c789 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -260,34 +260,21 @@ namespace Wox private double GetWindowsLeft() { - var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); - if (UserSettingStorage.Instance.RememberLastLaunchLocation) - { - var origScreen = Screen.FromRectangle(new Rectangle((int)Left, (int)Top, (int)ActualWidth, (int)ActualHeight)); - var coordX = (Left - origScreen.WorkingArea.Left) / (origScreen.WorkingArea.Width - ActualWidth); - UserSettingStorage.Instance.WindowLeft = (screen.WorkingArea.Width - ActualWidth) * coordX + screen.WorkingArea.Left; - } - else - { - UserSettingStorage.Instance.WindowLeft = (screen.WorkingArea.Width - ActualWidth) / 2 + screen.WorkingArea.Left; - } + if (UserSettingStorage.Instance.RememberLastLaunchLocation) return UserSettingStorage.Instance.WindowLeft; + var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); + var dipPoint = WindowIntelopHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0); + UserSettingStorage.Instance.WindowLeft = (dipPoint.X - ActualWidth)/2; return UserSettingStorage.Instance.WindowLeft; } private double GetWindowsTop() { + if (UserSettingStorage.Instance.RememberLastLaunchLocation) return UserSettingStorage.Instance.WindowTop; + var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); - if (UserSettingStorage.Instance.RememberLastLaunchLocation) - { - var origScreen = Screen.FromRectangle(new Rectangle((int)Left, (int)Top, (int)ActualWidth, (int)ActualHeight)); - var coordY = (Top - origScreen.WorkingArea.Top) / (origScreen.WorkingArea.Height - ActualHeight); - UserSettingStorage.Instance.WindowTop = (screen.WorkingArea.Height - ActualHeight) * coordY + screen.WorkingArea.Top; - } - else - { - UserSettingStorage.Instance.WindowTop = (screen.WorkingArea.Height - tbQuery.ActualHeight) / 4 + screen.WorkingArea.Top; - } + var dipPoint = WindowIntelopHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height); + UserSettingStorage.Instance.WindowTop = (dipPoint.Y - tbQuery.ActualHeight)/4; return UserSettingStorage.Instance.WindowTop; } @@ -534,6 +521,8 @@ namespace Wox private void HideWox() { + UserSettingStorage.Instance.WindowLeft = Left; + UserSettingStorage.Instance.WindowTop = Top; if (IsInContextMenuMode) { BackToResultMode(); diff --git a/Wox/Msg.xaml.cs b/Wox/Msg.xaml.cs index 2dd1d500d7..491fa7cb89 100644 --- a/Wox/Msg.xaml.cs +++ b/Wox/Msg.xaml.cs @@ -5,6 +5,7 @@ using System.Windows.Forms; using System.Windows.Input; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; +using Wox.Helper; namespace Wox { public partial class Msg : Window { @@ -13,15 +14,18 @@ namespace Wox { public Msg() { InitializeComponent(); - - Left = Screen.PrimaryScreen.WorkingArea.Right - this.Width; - Top = Screen.PrimaryScreen.Bounds.Bottom; - showAnimation.From = Screen.PrimaryScreen.Bounds.Bottom; - showAnimation.To = Screen.PrimaryScreen.WorkingArea.Bottom - Height; + var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); + var dipWorkingArea = WindowIntelopHelper.TransformPixelsToDIP(this, + screen.WorkingArea.Width, + screen.WorkingArea.Height); + Left = dipWorkingArea.X - this.Width; + Top = dipWorkingArea.Y; + showAnimation.From = dipWorkingArea.Y; + showAnimation.To = dipWorkingArea.Y - Height; // Create the fade out storyboard fadeOutStoryboard.Completed += new EventHandler(fadeOutStoryboard_Completed); - DoubleAnimation fadeOutAnimation = new DoubleAnimation(Screen.PrimaryScreen.WorkingArea.Bottom - Height, Screen.PrimaryScreen.Bounds.Bottom, new Duration(TimeSpan.FromSeconds(0.3))) { + DoubleAnimation fadeOutAnimation = new DoubleAnimation(dipWorkingArea.Y - Height, dipWorkingArea.Y, new Duration(TimeSpan.FromSeconds(0.3))) { AccelerationRatio = 0.2 }; Storyboard.SetTarget(fadeOutAnimation, this);