views:

366

answers:

3

I catch the windows mouse movement events and calculate an relative mouse movement to send it to another pc. So far so good, works well.

But if I block the mouse movement on the screen that is sending the mouse coordinates (the client) or reach one side of the screen, there is a second mouse event fired by the windows api, that snaps the mouse back.

My first thought is to record the relative movements and ignore every "inverted" movement. But I'm looking for a better method.

First I call:

Cursor.Position = new Point(0, 0);

    void HookManager_MouseMoveExt(object sender, MouseEventExtArgs e)
    {
        Logger.Log(String.Format("Pos: {0} {1} Delta: {2} {3}", e.X, e.Y, e.DeltaX, e.DeltaY), LogLevel.Info);

        if (hasControl)
            server.MouseMove(e.DeltaX, e.DeltaY, true); // send the coordinates to the client

        e.Handled = true; // Don't move the mouse
    }

Now I start the app and move the mouse to the upper left direction. I only want to receive only negative deltas, but this happens:

09.04.2009 00:29:31 <10> Pos: 0 -1 Delta: 0 -1
09.04.2009 00:29:31 <10> Pos: -1 0 Delta: -1 0
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: 0 -1
09.04.2009 00:29:31 <10> Pos: 0 0 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -1 0 Delta: -1 0
09.04.2009 00:29:31 <10> Pos: 0 -1 Delta: 0 -1
09.04.2009 00:29:31 <10> Pos: -1 0 Delta: -1 0
09.04.2009 00:29:31 <10> Pos: 0 -1 Delta: 0 -1
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: -1 0
09.04.2009 00:29:31 <10> Pos: -1 0 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: 0 0 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: -1 -1
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -1 0 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: 0 -1
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -2 -1 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: 1 0 // Here it starts to snap back first time
09.04.2009 00:29:31 <10> Pos: -1 0 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: 0 -1
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -2 -1 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -2 -1 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -2 -1 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -1 -2 Delta: 1 0
09.04.2009 00:29:31 <10> Pos: -3 -1 Delta: 0 1
09.04.2009 00:29:31 <10> Pos: -2 -2 Delta: 1 0
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: 1 1
09.04.2009 00:29:31 <10> Pos: -3 -1 Delta: 0 0
09.04.2009 00:29:31 <10> Pos: -1 0 Delta: 2 0
09.04.2009 00:29:31 <10> Pos: 0 -1 Delta: 0 -1
09.04.2009 00:29:31 <10> Pos: -1 -1 Delta: -1 0
09.04.2009 00:29:32 <10> Pos: -1 0 Delta: 0 0
09.04.2009 00:29:32 <10> Pos: 0 0 Delta: 0 0
09.04.2009 00:29:32 <10> Pos: -1 -1 Delta: -1 -1
09.04.2009 00:29:32 <10> Pos: -1 -1 Delta: 0 0
09.04.2009 00:29:32 <10> Pos: -1 0 Delta: 0 0
09.04.2009 00:29:32 <10> Pos: 0 -1 Delta: 0 -1
09.04.2009 00:29:32 <10> Pos: -1 0 Delta: -1 0
09.04.2009 00:29:32 <10> Pos: 0 -1 Delta: 0 -1
09.04.2009 00:29:32 <10> Pos: -1 0 Delta: -1 0
09.04.2009 00:29:32 <10> Pos: 0 -1 Delta: 0 -1
09.04.2009 00:29:32 <10> Pos: -1 -1 Delta: -1 0
09.04.2009 00:29:32 <10> Pos: -1 0 Delta: 0 0
09.04.2009 00:29:32 <10> Pos: -1 -1 Delta: 0 -1
09.04.2009 00:29:32 <10> Pos: -1 0 Delta: 0 0
09.04.2009 00:29:32 <10> Pos: -2 -2 Delta: 0 -2
09.04.2009 00:29:32 <10> Pos: 0 0 Delta: 2 2
09.04.2009 00:29:32 <10> Pos: -1 0 Delta: -1 0
09.04.2009 00:29:32 <10> Pos: 0 -1 Delta: 0 -1
09.04.2009 00:29:32 <10> Pos: -1 0 Delta: -1 0
09.04.2009 00:29:32 <10> Pos: -1 -1 Delta: 0 -1
09.04.2009 00:29:33 <10> Pos: -1 -1 Delta: 0 0
09.04.2009 00:29:36 <10> Pos: -1 -1 Delta: 0 0
09.04.2009 00:29:36 <10> Pos: -2 -2 Delta: 0 0
09.04.2009 00:29:36 <10> Pos: -5 -5 Delta: -3 -3
09.04.2009 00:29:36 <10> Pos: -5 -4 Delta: 0 1
09.04.2009 00:29:36 <10> Pos: -6 -6 Delta: -1 -2
09.04.2009 00:29:36 <10> Pos: -8 -7 Delta: -2 -1
09.04.2009 00:29:36 <10> Pos: -8 -7 Delta: 0 0
09.04.2009 00:29:36 <10> Pos: -14 -11 Delta: -6 -4
09.04.2009 00:29:36 <10> Pos: -20 -17 Delta: -6 -6
09.04.2009 00:29:36 <10> Pos: -26 -25 Delta: -6 -8
09.04.2009 00:29:36 <10> Pos: -33 -25 Delta: -7 0
09.04.2009 00:29:36 <10> Pos: -36 -31 Delta: -3 -6
09.04.2009 00:29:36 <10> Pos: -39 -31 Delta: -3 0
09.04.2009 00:29:36 <10> Pos: -38 -29 Delta: 1 2
09.04.2009 00:29:36 <10> Pos: -38 -24 Delta: 0 5
09.04.2009 00:29:36 <10> Pos: -33 -24 Delta: 5 0
09.04.2009 00:29:36 <10> Pos: -28 -21 Delta: 5 3
09.04.2009 00:29:36 <10> Pos: -27 -18 Delta: 1 3
09.04.2009 00:29:36 <10> Pos: -22 -16 Delta: 5 2
09.04.2009 00:29:36 <10> Pos: -19 -12 Delta: 3 4
09.04.2009 00:29:36 <10> Pos: -16 -11 Delta: 3 1
09.04.2009 00:29:36 <10> Pos: -14 -8 Delta: 2 3
09.04.2009 00:29:36 <10> Pos: -11 -8 Delta: 3 0
09.04.2009 00:29:36 <10> Pos: -8 -5 Delta: 3 3
09.04.2009 00:29:36 <10> Pos: -8 -5 Delta: 0 0
09.04.2009 00:29:36 <10> Pos: -4 -2 Delta: 4 3
09.04.2009 00:29:36 <10> Pos: -3 -3 Delta: 1 -1
09.04.2009 00:29:36 <10> Pos: -1 0 Delta: 2 3
+1  A: 

I'm not sure the specifics of what you're trying to do, but why not try clipping the cursor to a small part of the screen and making it invisible. Then every time you detect movement, move the client's cursor back to the center of that clipped box. So you're calculating relative movement from the same on-screen point every time.

This is what Bochs, the PC emulator does (almost--it doesn't clip the cursor to the window).

zildjohn01
+2  A: 

I can't actually answer your question, but are you aware of the open-source program Synergy?

It does what you're trying to do - perhaps you could take a peek at the source for hints.

Blorgbeard
I already looked on their code, but I'm not really familiar with it can't see much. I found out, that they track the mouse movement and use a timer to ignore wrong movement. But it looks complicated. I hope there is an easier method
Tarion
A: 

Got my solution, based on the box method. MouseSimulator.Position just do:

        Cursor.Position = new Point(value, Y);

HookManager_MouseMoveExt is my callback. MouseEventExtArgs are just extended MouseEventArgs, added features like the deltas.

        private bool ignoreNext = false;
        void HookManager_MouseMoveExt(object sender, MouseEventExtArgs e)
        {
            // Should we block all mouse interactions?
            if (Block) {
                e.Handled = true;
                return;
            }

            // Return if we should ignore the nex, because we made a big jump
            if (ignoreNext) {
                ignoreNext = false;
                return;
            }

            if (hasControl) 
            {
                // Lock the mouse to 100,100 : 200,200 and flip back to 150,150 if out of bounds
                if (e.X < 100 || e.X > 200 || e.Y < 100 || e.Y > 200) // Box leaved
                {
                    // If we leave the box, we set the position to the center 
                    // and set the event to handled otherwise the mouse is free
                    MouseSimulator.Position = new System.Drawing.Point(150, 150);
                    e.Handled = true;
                    ignoreNext = true;
                }

                // We moved fine, send the delta to the server
                // The MouseSimulator.Position change will not be visible yet.
                server.MouseMove(e.DeltaX, e.DeltaY, true);

            }

            Logger.Log(String.Format("Pos: {0} {1} Delta: {2} {3}", e.X, e.Y, e.DeltaX, e.DeltaY), LogLevel.Info);
        }
Tarion