2012-07-31 108 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