Получить положение мыши на холсте с прозрачным фоном

Я строю простую WPF приложение. У меня прозрачный развернут Window и Canvas (Canvas1).

Я хочу получить положение мыши в canvas1 или в MainWindow (в этом случае одно и то же).

Для этого я использую этот код:

Point p = Mouse.GetPosition(canvas1); //and then I have p.X and p.Y

Этот код отлично работает для непрозрачного Canvas, Проблема в том, что у меня прозрачный Canvas, и этот код не работает... (Он не дает мне ошибок, но координаты p.X = 0 а также p.Y = 0).

Как я могу исправить эту проблему?

2 ответа

Решение

Одним из возможных решений является использование GetCursorPos Win32 функция:

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetCursorPos(out System.Drawing.Point lpPoint); 

Вы должны конвертировать координаты из пикселей в точки, если вы хотите использовать его в WPF.

Пример использования:

System.Drawing.Point point;
if(!GetCursorPos(out point))
    throw new InvalidOperationException("GetCursorPos failed");
// point contains cursor's position in screen coordinates.

C#

    using System.Windows;
    using System.Windows.Input;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System;
    using System.Windows.Threading;
    namespace Test
    {
        public partial class MainWindow : Window
        {
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            internal static extern bool GetCursorPos(ref Win32Point pt);

            [StructLayout(LayoutKind.Sequential)]
            internal struct Win32Point
            {
                public Int32 X;
                public Int32 Y;
            };
            public static Point GetMousePosition()
            {
                Win32Point w32Mouse = new Win32Point();
                GetCursorPos(ref w32Mouse);
                return new Point(w32Mouse.X, w32Mouse.Y);
            }

            private double screenWidth;
            private double screenHeight;

            public MainWindow()
            {
                InitializeComponent();
            }

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
                screenHeight = System.Windows.SystemParameters.PrimaryScreenHeight;

                this.Width = screenWidth;
                this.Height = screenHeight;
                this.Top = 0;
                this.Left = 0;
                DispatcherTimer timer = new DispatcherTimer();
                timer.Tick += new EventHandler(timer_Tick);
                timer.Start();
            }

            void timer_Tick(object sender, EventArgs e)
            {
                var mouseLocation = GetMousePosition();
                elipse1.Margin = new Thickness(mouseLocation.X, mouseLocation.Y, screenWidth - mouseLocation.X - elipse1.Width, screenHeight - mouseLocation.Y- elipse1.Height);
            }
        }
    }

XAML

    <Window x:Class="Test.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" 
            Height="350" Width="525" 
            WindowStyle="None" 
            Topmost="True" 
            AllowsTransparency="True" 
            Background="Transparent"
            ShowInTaskbar="False"
            Loaded="Window_Loaded">
        <Grid>
                <Ellipse Width="20" Height="20" Fill="Red" Name="elipse1"/>
        </Grid>
    </Window>

Решено! Но поздно:(

Другие вопросы по тегам