18

It works within a specific control, but it doesn't work out the specific control.

How to get mouse position and use mouse events independently of any control just directly from screen (without Platform Invoke)?

2 needed points:

  1. Mouse events when mouse is not within a control, but on a screen.
  2. Mouse position when mouse is not within a control, but on a screen.

It should be solved without using Platform Invoke.

Next two don't work:

System.Windows.Input.Mouse.GetPosition(this)

Doesn't get mouse position out a specific control.

System.Windows.Forms.Cursor.Position.X

System.Windows.Forms.Cursor.Position doesn't work because it has no types in a WPF app, but it works in a Windows Forms app.

IntelliSense gets System.Windows.Forms.Cursor.Position, but it doesn't get any type of Position, hence I can't get:

Position.X    
Position.Y

and

Point pointToWindow = Mouse.GetPosition(this);

Point pointToScreen = PointToScreen(pointToWindow);

Doesn't get mouse position out a specific control.

Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
Ziya Ceferov
  • 305
  • 1
  • 3
  • 7

4 Answers4

18

Using MouseDown event of a control you can try this:

var point = e.GetPosition(this.YourControl);

EDIT: You can capture mouse event to a specific control using Mouse.Capture(YourControl); so it will capture the mouse events even if it is not on that control. Here is the link

Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
  • You can use it for the main control enclosing all of the controls e.g. `UserControl` or `Window` – Hossein Narimani Rad Apr 23 '15 at 11:29
  • Yes, but in my case i draw on a window when mouse is out the window. My goal is draw on a window at background by mouse, when a user moves mouse doing something else. If it is impossible, let me know. – Ziya Ceferov Apr 23 '15 at 11:31
  • Mouse.Capture(YourControl) works. Second needed point solved, great, now how to solve first point? How to use mouse events independently of controls directly on screen? I can solve it using endless thread, but is there any ready way like with controls? – Ziya Ceferov Apr 23 '15 at 11:42
  • @ZiyaCeferov Not sure if it is possible or not! – Hossein Narimani Rad Apr 23 '15 at 12:04
  • "Not sure if it is possible or not!" - ok, by anyway the major problem is solved. – Ziya Ceferov Apr 23 '15 at 13:10
12

You can use PointToScreen

Converts a Point that represents the current coordinate system of the Visual into a Point in screen coordinates.

Something like this:

private void MouseCordinateMethod(object sender, MouseEventArgs e)
{
    var relativePosition = e.GetPosition(this);
    var point= PointToScreen(relativePosition);
    _x.HorizontalOffset = point.X;
    _x.VerticalOffset = point.Y;
}

Do note that Mouse.GetPosition returns a Point, and PointToScreen converts the point to the screen coordinate

EDIT:

You can use the Mouse.Capture(SepcificControl);. From MSDN

Captures mouse input to the specified element.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • It doesn't work out a specific control. My app has no window, it draws at background by mouse, while a user uses mouse to do something else. It just copies mouse moves. If it is impossible without Platform Invoke, let me know. The question is not answered. – Ziya Ceferov Apr 23 '15 at 11:34
  • @ZiyaCeferov:- Sorry for the late reply but yes you can use the `Mouse.Capture(SpecificControl);` for your task – Rahul Tripathi Apr 23 '15 at 11:43
  • Yes, it works, great. One of the 2 issues solved, what about another one: how to use mouse events without specific controls directly on screen? I can solve it using endless thread or timer, but i ask: is there a ready way like we do with controls? – Ziya Ceferov Apr 23 '15 at 11:49
  • Mouse hook works by Platform Invoke. "Not very much sure" - ok, i consider it is impossible and i need to use timer or endless thread. By anyway the major problem is solved. – Ziya Ceferov Apr 23 '15 at 11:59
3

Why complicate things? Just pass null to get screen coordinates:

private void MouseCordinateMethod(object sender, MouseEventArgs e)
{
    var screenPos = e.GetPosition(null);
    // ...
}
l33t
  • 18,692
  • 16
  • 103
  • 180
2

I have little new found,

Code is below, fisrt build and run the Window ,

then just wheel your mouse one time on the window to invoke the endless screen detect of the Mouse Position.

(Thus I didn't find the way to detect mouse event out of the control in the second point of the question, but similar use an endless thread.)

But I just use a little skill to enable Windows.Forms in WPF Project, by simply use the Forms code in pure method, then refer that method in the Event Code Block.

.

Here's the Code:

Add two references to project:

System.Drawing 
System.Windows.Forms

Xaml part:

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:g="clr-namespace:Gma.UserActivityMonitor;assembly=Gma.UserActivityMonitor"
        Title="MainWindow" Height="350" Width="525" 
        MouseWheel="MainWindow_OnMouseWheel">
    <Grid>
       <TextBlock Name="TBK" /> 
    </Grid>
</Window>

Class Code:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public void KeepReportMousePos()
        {
            //Endless Report Mouse position
            Task.Factory.StartNew(() =>
            {
                while(true){
                    this.Dispatcher.Invoke(
                        DispatcherPriority.SystemIdle,
                        new Action(() =>
                        {
                            GetCursorPos();
                        }));
                }
            });
        }
        public void GetCursorPos()
        {
            //get the mouse position and show on the TextBlock
            System.Drawing.Point p = System.Windows.Forms.Cursor.Position;
            TBK.Text = p.X + " " + p.Y;
        }

        private void MainWindow_OnMouseWheel(object sender, MouseWheelEventArgs e)
        {
            //invoke mouse position detect when wheel the mouse
            KeepReportMousePos();
        }
    }
yu yang Jian
  • 6,680
  • 7
  • 55
  • 80