1

我创建了一个小型示例应用程序来说明我在使用GetWindowRect. 当我单击 Foo 按钮时,它显示Left返回的值GetWindowRect不同于Window.Left.

看起来返回的值Window.Left是相对的,但我不确定是什么。也很奇怪,我无法在每台机器上重现此问题,在有或没有额外显示器的家用笔记本电脑上,我可以重现此问题,在我的工作电脑上,问题不会发生。两个系统都运行 Windows 7

为什么这些值不同,我该如何解决?

主窗口.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);
        }
    }
}

主窗口.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>
4

1 回答 1

5

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

于 2013-03-09T19:43:42.237 回答