在 WPF 中获取窗口的真实位置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22668051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:21:23  来源:igfitidea点击:

Get real Position of Window in WPF

c#wpf

提问by user1130329

how do I get the real Position (in Pixels) of a WPF-Window?

如何获得 WPF 窗口的真实位置(以像素为单位)?

this.PointFromScreen( new Point( 0, 0 ) );does not gives real Position on Screen when I use DPI of 150% for Font. I guess this has something to do with scaling, but in my case I need the "real" position on Screen.

this.PointFromScreen( new Point( 0, 0 ) );当我将 150% 的 DPI 用于字体时,不会在屏幕上给出真正的位置。我想这与缩放有关,但就我而言,我需要屏幕上的“真实”位置。

回答by Tejas Sharma

I think you want PointToScreen. PointFromScreenconverts screen coordinates into the coordinate system of the Visual.

我想你想PointToScreenPointFromScreen将屏幕坐标转换为Visual.

var window = new Window();
Point screenCoordinates = window.PointToScreen(new Point(0,0)); 

回答by Mario Vernari

I have this piece of code, but honestly I didn't remember if it was used once at least. I believe it should work "decently"...

我有这段代码,但老实说我不记得它是否至少使用过一次。我相信它应该“体面”地工作......

BTW, I wonder why do you need a similar information.

顺便说一句,我想知道您为什么需要类似的信息。

    [StructLayout(LayoutKind.Sequential)]
    private struct POINT
    {
        public int X;
        public int Y;
    }


    /// <summary>
    /// The ClientToScreen function converts the client-area coordinates of a specified point to screen coordinates.
    /// </summary>
    /// <param name="hWnd">Handle to the window whose client area is used for the conversion.</param>
    /// <param name="pt">Pointer to a POINT structure that contains the client coordinates to be converted. The new screen coordinates are copied into this structure if the function succeeds.</param>
    /// <returns>If the function succeeds, the return value is nonzero.</returns>
    [DllImport("User32", EntryPoint = "ClientToScreen", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool ClientToScreen(
        IntPtr hWnd,
        ref POINT pt);


    /// <summary>
    /// Code for getting screen relative Position in WPF
    /// </summary>
    /// <param name="point">The source point to be trasnformed</param>
    /// <param name="relativeTo">The Visual object used as reference</param>
    /// <returns>The screen-relative point obtained by the trasformation</returns>
    /// <remarks>
    /// http://blogs.msdn.com/llobo/archive/2006/05/02/Code-for-getting-screen-relative-Position-in-WPF.aspx
    /// One of the common customer queries that we see on the forums 
    /// is to get the screen relative position of  a point.
    /// Currently we do not provide an API which allows this functionality.
    /// However, Nick Kramer came up with this code on the forum 
    /// and it works great for LTR (left to right) systems. 
    /// Following is the code for getting the screen relative position.
    /// </remarks>
    [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
    public static Point? TransformToScreen(
        Point point,
        Visual relativeTo)
    {
        // Translate the point from the visual to the root.
        var hwndSource = PresentationSource.FromVisual(relativeTo) as HwndSource;
        if (hwndSource == null)
            return null;
        var root = hwndSource.RootVisual;

        // Transform the point from the root to client coordinates.
        var transformToRoot = relativeTo.TransformToAncestor(root);
        var pointRoot = transformToRoot.Transform(point);
        var m = Matrix.Identity;
        var transform = VisualTreeHelper.GetTransform(root);
        if (transform != null)
        {
            m = Matrix.Multiply(m, transform.Value);
        }

        // Convert from “device-independent pixels” into pixels.
        var offset = VisualTreeHelper.GetOffset(root);
        m.Translate(offset.X, offset.Y);
        var pointClient = m.Transform(pointRoot);
        pointClient = hwndSource.CompositionTarget.TransformToDevice.Transform(pointClient);

        var pointClientPixels = new POINT();
        pointClientPixels.X = (0 < pointClient.X)
            ? (int)(pointClient.X + 0.5)
            : (int)(pointClient.X - 0.5);
        pointClientPixels.Y = (0 < pointClient.Y)
            ? (int)(pointClient.Y + 0.5)
            : (int)(pointClient.Y - 0.5);

        // Transform the point into screen coordinates.
        var pointScreenPixels = pointClientPixels;

        if (ClientToScreen(
            hwndSource.Handle,
            ref pointScreenPixels))
        {
            return new Point(
                pointScreenPixels.X,
                pointScreenPixels.Y);
        }
        else
        {
            return new Point();
        }
    }