2012-07-31 144 views
2

我建立一个简单的应用WPF。我有一个透明最大化WindowCanvas(canvas1)。获取在画布上鼠标的位置与透明背景

我想获取鼠标位置canvas1MainWindow(在这种情况下是相同的事情)。

这样做我用这个代码:

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

此代码工作正常的不透明Canvas。问题是,我有一个透明Canvas,而这个代码不工作...(它不给我的错误,但坐标是p.X = 0p.Y = 0)。

我怎样才能解决这个问题?

+0

你可以给你的画布'Z-Index'属性,因为它是可以接近你的应用程序有一些其他的东西 – harry180 2012-07-31 10:14:22

+2

Z-指数=也许你?会提出一个答案。如果它帮助我,我会+1并标记它。 – 2012-07-31 10:15:51

+0

您是否尝试过使用不透明背景而不使用透明背景? – Alex 2012-07-31 10:17:11

回答

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. 
+0

@John,'System.Drawing.Point point; GetCursorPos(out point);'。 'point'将包含鼠标坐标。不要忘记添加System.Drawing.dll参考。 – Dmitry 2012-07-31 11:24:37

+1

只是一句话。这个论点最终并不是一个'System.Drawing.Point'。在Win32中,它是[POINT](http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805(v = vs.85).aspx)结构。你也可以用两个整数成员来定义你自己的结构,并将它用作参数类型。因此你会摆脱'System.Drawing.dll'的依赖。 – Clemens 2012-07-31 11:43:43

+0

@John还有一个问题。你现在将如何使用这个功能?在无尽的循环中不断更新当前的鼠标位置?我仍然认为你需要[MouseHook](http://stackoverflow.com/q/11607133/1136211)。 – Clemens 2012-07-31 11:44:56

1

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> 

解决了!但后期:(

+1

哦,谢谢。但就像我在评论中所说的,我不想要一个半透明的画布:Opacity =“0.01”...因为我想要点击另一个窗口(例如Firefox窗口),WPF窗口保持在最前面。 – 2012-07-31 10:51:39

+1

@John您如何期望在两个应用程序中同时获得鼠标事件?鼠标移动到透明覆盖窗口并点击其他应用程序?那不行! – Clemens 2012-07-31 10:54:38

+0

@Clemens我相信它可以通过Win32来完成。我记得很久以前读过关于win32消息hackery的东西,但我不记得细节。 – Dmitry 2012-07-31 11:03:36