Mouse emulation in a different program
Asked Answered
M

1

6

I'm working on my own software to operate the mouse on my computer using C# and the kinect SDK. I really want to try using it to play a game like Red Alert, or some sort of RTS, or even just for general navigation.

The problem that I've found is that when using a program with a different mouse, like red alert or going into a virtual machine where mouse integration isn't supported, the program will not pick up on the calls that the C# program is making to the System.Windows.Forms.Cursor calls, let alone the mouse_event calls. I'm new to interfacing with windows and what is happening here, can someone explain/pose a solution?

--UPDATE-- As an update, I'm still not entirely sure what's going on, but I seem to have found a workaround for red alert in particular;

Since red alert is a fairly low graphics program, it is trivial to run it within a virtual machine specifically for me, vmware workstation with an XP client. If you use the mouse_event code it works well, HOWEVER, something that I struggled with was finding the correct code to represent mouse movement. It would seem that the MOVE flag moves the mouse relatively, which I didn't want, and the absolute tag didn't move the mouse at all. It is, in fact, the OR of them that produces absolute movement on the screen, so my code for mouse movement and clicking emulation ended up looking like this:

mouse_event((int)0x00000002, cursor.X, cursor.Y, 0, 0);

for clicking and

mouse_event((int)(0x00000001 | 0x00008000), x, y, 0 0);

for mouse movement, where x and y are the new coordinates out of 65535 (the absolute range). Is it perfect? Nah. But it works for now. I think there's something to do with the way windows ignores certain programs when it runs ra, maybe because of compatibility mode? I don't have another game to test it with right now, but I'll post results with a non-compatibility mode in the future.

  • Pete

(It wouldn't let me post as an answer for another two hours and I have to sleep to catch a flight in the morning!)

Misunderstood answered 31/12, 2011 at 22:49 Comment(1)
I recommend using the SendInput function over the deprecated mouse_event function.Caliban
S
1

You will have to do some low level windows messages to get this to work properly. Games using DirectX like Red Alert will not look at the System.Windows.Forms.Cursor at all. You will need to interface with the Windows User32.dll to send the appropriate messages to windows so it can route them appropriately to the other applications.

Here is some code to get you started looking in to sending messages via the User32 DLL in C#:

    [DllImport("USER32.DLL")]
    public static extern IntPtr FindWindow(string lpClassName,
        string lpWindowName);

    // Activate an application window.
    [DllImport("USER32.DLL")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll")]
    private static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

I hope this gets you started, but I don't have the time to go through each mouse message, what the wParam and lParam are, and what the Msg should be for each. I'm sure if you search around you can find the specific messages to send for each event such as mouse move, left click and right click.

Good luck.

Stites answered 31/12, 2011 at 23:12 Comment(3)
Actually, a game using DirectX would not use GetMessage() either, so SendMessage() will most likely have no effect. You need even lower level stuff. The lowest-level stuff that I know of is mouse_event().Complot
Right now I have something a bit hacky that half works. I'm using a mouse_event() in order to click the mouse anyway and I'm also trying to use SetCursorPos() to move thouse mouse. Maybe I'm missing a redraw or something? But when the mouse_event is called it functions properly and redraws the mouse where it should (and clicks), but the SetCursorPos() doesn't. Current Code: [DllImport("user32.dll", EntryPoint = "SetCursorPos")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetCursorPos(int x, int y);Misunderstood
I should also mention that mouse_events() don't seem to work at all in the normal machine, the only way I've even gotten any response from mouse_event is to try running it on a virtual machine (I thought that maybe if I got all of the input running through what the virtual thought was one source it might work).Misunderstood

© 2022 - 2024 — McMap. All rights reserved.