3

[please see update at the end]

I'm an old stack overflow user (as most developers on, you know, Earth), but that's my first question here.

I'm trying to use an "air mouse" for gaming (pointing it to the screen), but as the mouse sensor is a gyroscope, there's some problems with off-screen movement that I'd like to try to fix by software.

With this gyro mouse, when the user moves its arm pointing outside the screen, the cursor stops at the screen limit, which is no problem. However, when he moves his arm back, no matter the distance from the screen, the cursor immediately moves on-screen. This causes a giant difference between the air mouse real position and the cursor.

This could be fixed with a simple control over the number of pixels, and direction, travelled off-screen, in conjunction with some event handling. If I could sum the number of "offscreen" pixels traveled in -X, +X, -Y and +Y, it would be possible to prevent/cancel the mouse move event - or set the cursor to its previous position, at the edge of the screen - until the control tells me that the physical mouse is pointing back to the screen. Just then I'd allow the cursor to move freely.

Maybe this isn't that usefull, but it's an interesting problem, and see this working would be fun as hell!

Currently, based on this great project, I can just state when the mouse is off-screen, but cannot control how far and in which direction it is moving, to properly implement what I'm trying. It seems to me that such kind of information would be too low-level for my current Windows knowledge.

So, to be clear: how can I, in C# (other languages accepted, but I'd have to learn a lot ;), get any kind of "delta position" information or direction of movement, when the cursor is at the limit of screen?

With all due respect, I'm not interested on using different kinds of controllers, as well as "you shouldn't do this" answers. I have this problem to solve, with these elements, and it would be great to make this work!

UPDATE:

Ok, here's my progress up to now.

In order to get raw mouse data and know about the mouse movement 'offscreen', I had to register my application, using some windows API functions, to receive WM_INPUT messages.

Based on a very old code I found, I was able to get mouse raw data and implement exactly what I wanted. Except for the fact that this code is based on a WdnProc callback, and so it only works when my application has the focus. And I need it to also work when the focus is elsewhere - after all, I'm trying to improve the pointing provided by a gyro mouse, for third party games.

It seems that I should use a hook (a good example here), but I have no idea how to hook for input messages. Tried to merge the code of the two links above, but the first one needs the message.LParam that is passed to the WdnProc - which seems to be unavailable when merely hooking mouse events.

Now I'm way out of my league to make some real progress. Any ideas?

FabricioNK
  • 31
  • 3
  • You can lock the cursor in your window, that is how games handle this situation (correct me if I'm wrong) – Matthiee Aug 26 '18 at 15:49
  • Thanks for the comment Mattiee. I wasn't clear when stated "for gaming". I'm not developing one, I'm just trying to improve the control of third party games with a specific kind of controller/mouse. So there's no such a thing as "my window". – FabricioNK Aug 26 '18 at 17:14

1 Answers1

0

One of the simplest solution to get cursor position and then detect its movement regardless where the cursor is to use win32 API from the user32.dll.

Here is a simple code which gets the cursor position in every 10ms using the timer in the C# Windows Form application and displays it as the title of the window.

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;

public partial class Form1 : Form
{
    Timer timer = new Timer();

    public Form1()
    {
        InitializeComponent();

        timer.Interval = 10;
        timer.Tick += Timer_Tick;

        timer.Start();
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        // do here whatever you want to do

        // just for testing...
        GetCursorPos(out Point lpPoint);
        this.Text = lpPoint.X + ", " + lpPoint.Y;
    }

    [DllImport("user32.dll")]
    public static extern bool GetCursorPos(out Point p);
}
L_J
  • 2,351
  • 10
  • 23
  • 28
  • Already tried this and, as a hook to the mouse event, GetCursorPos is limited to the screen boundaries. It seems that the OS just passes mouse move messages already converted to pixels limited to the screen. So, to get mouse direction after the screen limits, maybe I should look for something like raw mouse data? – FabricioNK Aug 26 '18 at 18:42