Fix #12 and reduce visual flickering while switching preview target

This commit is contained in:
Paddy Xu
2017-05-17 20:32:25 +03:00
parent 464deb801d
commit 71dc0a29d9
8 changed files with 102 additions and 20 deletions

View File

@@ -1,13 +1,68 @@
using System;
using System.Diagnostics;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using System.Windows.Media;
using QuickLook.NativeMethods;
namespace QuickLook.Helpers
{
internal static class WindowHelper
{
public static Rect GetCurrentWindowRect()
{
var screen = Screen.FromPoint(Cursor.Position).WorkingArea;
var dpi = DpiHelper.GetCurrentDpi();
var scaleX = dpi.HorizontalDpi / DpiHelper.DEFAULT_DPI;
var scaleY = dpi.VerticalDpi / DpiHelper.DEFAULT_DPI;
return new Rect(
new Point(screen.X / scaleX, screen.Y / scaleY),
new Size(screen.Width / scaleX, screen.Height / scaleY));
}
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)
window.TransformToPixels(left, top,
out pxLeft, out pxTop);
int pxWidth, pxHeight;
window.TransformToPixels(width, height,
out pxWidth, out pxHeight);
Debug.WriteLine($"{pxLeft},{pxTop},{pxWidth},{pxHeight}");
var helper = new WindowInteropHelper(window);
User32.MoveWindow(helper.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) (matrix.M11 * unitX);
pixelY = (int) (matrix.M22 * unitY);
}
internal static void SetNoactivate(WindowInteropHelper window)
{
User32.SetWindowLong(window.Handle, User32.GWL_EXSTYLE,

View File

@@ -24,7 +24,8 @@
<DockPanel.Style>
<Style TargetType="{x:Type DockPanel}">
<Style.Triggers>
<DataTrigger Binding="{Binding ContextObject.IsBusy, ElementName=mainWindow, Mode=OneWay}" Value="False">
<DataTrigger Binding="{Binding ContextObject.IsBusy, ElementName=mainWindow, Mode=OneWay}"
Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
@@ -64,7 +65,8 @@
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<DataTrigger Binding="{Binding ContextObject.IsBusy, ElementName=mainWindow, Mode=OneWay}" Value="False">
<DataTrigger Binding="{Binding ContextObject.IsBusy, ElementName=mainWindow, Mode=OneWay}"
Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>

View File

@@ -5,6 +5,7 @@ using System.Windows.Input;
using System.Windows.Threading;
using QuickLook.ExtensionMethods;
using QuickLook.Helpers;
using QuickLook.Helpers.BlurLibrary;
using QuickLook.Plugin;
namespace QuickLook
@@ -25,7 +26,7 @@ namespace QuickLook
if (!Debugger.IsAttached)
Topmost = true;
Loaded += (sender, e) => Helpers.BlurLibrary.BlurWindow.EnableWindowBlur(this);
Loaded += (sender, e) => BlurWindow.EnableWindowBlur(this);
buttonCloseWindow.MouseLeftButtonUp += (sender, e) => { Hide(); };
@@ -57,13 +58,12 @@ namespace QuickLook
// revert UI changes
ContextObject.IsBusy = true;
Height = ContextObject.PreferredSize.Height + titlebar.Height + windowBorder.BorderThickness.Top +
var newHeight = ContextObject.PreferredSize.Height + titlebar.Height + windowBorder.BorderThickness.Top +
windowBorder.BorderThickness.Bottom;
Width = ContextObject.PreferredSize.Width + windowBorder.BorderThickness.Left +
var newWidth = ContextObject.PreferredSize.Width + windowBorder.BorderThickness.Left +
windowBorder.BorderThickness.Right;
Left = (SystemParameters.VirtualScreenWidth - Width) / 2;
Top = (SystemParameters.VirtualScreenHeight - Height) / 2;
ResizeAndCenter(new Size(newWidth, newHeight));
ResizeMode = ContextObject.CanResize ? ResizeMode.CanResizeWithGrip : ResizeMode.NoResize;
@@ -73,6 +73,28 @@ namespace QuickLook
// WindowHelper.SetNoactivate(new WindowInteropHelper(this));
}
private void ResizeAndCenter(Size size)
{
if (!IsLoaded)
{
// if the window is not loaded yet, just leave the problem to WPF
Width = size.Width;
Height = size.Height;
WindowStartupLocation = WindowStartupLocation.CenterScreen;
return;
}
// System.Windows.Forms does not consider DPI, so we need to do it maunally
var screen = WindowHelper.GetCurrentWindowRect();
var newLeft = screen.Left + (screen.Width - size.Width) / 2;
var newTop = screen.Top + (screen.Height - size.Height) / 2;
this.MoveWindow(newLeft, newTop, size.Width, size.Height);
}
private new void Hide()
{
if (App.RunningAsViewer)

View File

@@ -7,6 +7,10 @@ namespace QuickLook.NativeMethods
{
internal static class User32
{
[DllImport("user32.dll")]
public static extern int MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight,
[MarshalAs(UnmanagedType.Bool)] bool bRepaint);
[DllImport("user32.dll")]
internal static extern IntPtr SetWindowsHookEx(int idHook, KeyboardHookProc callback, IntPtr hInstance,
uint threadId);

View File

@@ -4,6 +4,7 @@ using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using QuickLook.Annotations;
using QuickLook.Helpers;
namespace QuickLook.Plugin
{
@@ -66,7 +67,9 @@ namespace QuickLook.Plugin
/// <summary>
/// Set whether user are allowed to set focus at the viewer window.
/// </summary>
public bool Focusable { get; set; } = false;
public bool Focusable { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public void DisposePlugin()
{
@@ -74,8 +77,6 @@ namespace QuickLook.Plugin
ViewerPlugin = null;
}
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Show a notification balloon.
/// </summary>
@@ -114,9 +115,9 @@ namespace QuickLook.Plugin
/// <summary>
/// Get the device-independent resolution.
/// </summary>
public Size GetMaximumDisplayBound()
public Rect GetMaximumDisplayBound()
{
return new Size(SystemParameters.VirtualScreenWidth, SystemParameters.VirtualScreenHeight);
return WindowHelper.GetCurrentWindowRect();
}
internal void Reset()

View File

@@ -1,5 +1,4 @@
using System;
using System.Windows;
using System.Windows;
namespace QuickLook.Plugin.InfoPanel
{

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Reflection;
using QuickLook.ExtensionMethods;
using QuickLook.Plugin;
using QuickLook.Plugin.InfoPanel;
namespace QuickLook
{
@@ -17,7 +18,7 @@ namespace QuickLook
LoadPlugins();
}
internal IViewer DefaultPlugin { get; } = new Plugin.InfoPanel.PluginInterface();
internal IViewer DefaultPlugin { get; } = new PluginInterface();
internal List<IViewer> LoadedPlugins { get; private set; } = new List<IViewer>();

View File

@@ -4,8 +4,6 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using QuickLook.ExtensionMethods;
using QuickLook.Helpers;
using QuickLook.Plugin;