C# GetWindowRect与Window不同。左

C# GetWindowRect与Window不同。左,c#,.net,wpf,pinvoke,C#,.net,Wpf,Pinvoke,我创建了一个小示例应用程序来说明使用GetWindowRect时遇到的问题。当我单击Foo按钮时,它显示由GetWindowRect返回的Left值与Window.Left不同 似乎Window.Left返回的值是相对的,但我不确定返回的值是什么。 同样奇怪的是,我不能在每台机器上重现这个问题,在我的家用笔记本电脑上,无论有没有额外的显示器,我都可以重现这个问题,在我的工作电脑上,这个问题不会发生。 两个系统都运行Windows7 为什么这些值不同?我如何解决这个问题 MainWindow.xa

我创建了一个小示例应用程序来说明使用
GetWindowRect
时遇到的问题。当我单击Foo按钮时,它显示由
GetWindowRect
返回的
Left
值与
Window.Left
不同

似乎
Window.Left
返回的值是相对的,但我不确定返回的值是什么。 同样奇怪的是,我不能在每台机器上重现这个问题,在我的家用笔记本电脑上,无论有没有额外的显示器,我都可以重现这个问题,在我的工作电脑上,这个问题不会发生。 两个系统都运行Windows7

为什么这些值不同?我如何解决这个问题

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);
        }
    }
}
使用系统;
使用System.Runtime.InteropServices;
使用System.Windows;
使用System.Windows.Interop;
名称空间位置测试
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
私有IntPtr thishHandle;
公共主窗口()
{
初始化组件();
}
已加载私有无效窗口(对象发送器、路由目标)
{
thisHandle=新的WindowInteropHelper(this).Handle;
}
[DllImport(“user32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
公共静态外部bool GetWindowRect(IntPtr hWnd,ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
公共结构矩形
{
公共int左;
公共int Top;
公共权利;
公共int底部;
}
私有void ReportLocation(对象发送方,RoutedEventArgs e)
{
var rct=new RECT();
GetWindowRect(此句柄,参考rct);
MessageBox.Show(Left.ToString()+“”+rct.Left);
}
}
}
main window.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>


您没有量化差异,有几种解释,但有一个明显的不匹配。Windows和WPF使用不同的单元。GetWindowRect()以像素为单位返回窗口位置,window.Left以1/96英寸为单位返回位置。当视频适配器不是以每英寸96点的速度运行时,它们将不匹配。96 dpi是旧版设置,在更高版本的Windows上很容易更改。WPF使获得dpi设置有点困难,请检查代码。

您没有量化差异,有几种解释,但有一个明显的不匹配。Windows和WPF使用不同的单元。GetWindowRect()以像素为单位返回窗口位置,window.Left以1/96英寸为单位返回位置。当视频适配器不是以每英寸96点的速度运行时,它们将不匹配。96 dpi是旧版设置,在更高版本的Windows上很容易更改。WPF使获得dpi设置有点困难,请检查代码。

wow很好解决了这个问题,我不得不在矩阵上调用Invert,因为我想从rct转换到WPF单元。W很好解决了这个问题,我不得不在矩阵上调用Invert,因为我想从rct转换到WPF单元