我创建了一个小示例应用程序来说明使用GetWindowRect
时遇到的问题。当我点击Foo按钮时,它会显示Left
返回的GetWindowRect
值与Window.Left
不同。
Window.Left
的返回值似乎是相对的,但我不确定是什么。
同样奇怪的是,我无法在每台机器上重现这一点,在我的家用笔记本电脑上有或没有额外的显示器我可以重现这个问题,在我的工作电脑上问题不会发生。
两个系统都运行Windows 7
为什么这些值不同,我该如何解决?
MainWindow.xaml.cs
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
namespace PositionTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private IntPtr thisHandle;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
thisHandle = new WindowInteropHelper(this).Handle;
}
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
private void ReportLocation(object sender, RoutedEventArgs e)
{
var rct = new RECT();
GetWindowRect(thisHandle, ref rct);
MessageBox.Show(Left.ToString() + " " + rct.Left);
}
}
}
MainWindow.xaml
<Window x:Class="PositionTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Loaded="Window_Loaded" WindowStartupLocation="Manual" Height="150" Width="150" WindowStyle="SingleBorderWindow" ResizeMode="NoResize" BorderThickness="0,1,0,0" >
<Grid>
<Button Content="Foo" HorizontalAlignment="Left" Margin="35,50,0,0" VerticalAlignment="Top" Width="75" Click="ReportLocation"/>
</Grid>
</Window>
答案 0 :(得分:5)
你没有量化差异,有几种解释,但有一个明显的不匹配。 Windows和WPF使用不同的单位。 GetWindowRect()以像素为单位返回窗口位置,Window.Left以1/96英寸返回位置。当视频适配器未以96点/英寸的速度运行时,它们将不匹配。 96 dpi是传统设置,在更高版本的Windows上更改非常容易。 WPF使得获取dpi设置有点困难,请检查this blog post代码。