views:

256

answers:

2

I am trying to redirect mouse inputs on my Windows 7 application to some other window. If I do this when I get WM_LBUTTONUP, it works (where MouseDown and MouseUp are SendInput functions in Win api):

SetForegroundWindow( other window );
SetCursorPos( somewhere on the window );
MouseDown();
MouseUp();
SetCursorPos( back );
SetForegroundWindow( main window );

But I don't want to only do mouse releases, I want to be able to capture all mouse stuff, including movements and dragging.

So this is next logical thing to do but it doesn't work:

WM_LBUTTONDOWN:
Do everything like before without MouseUp()

WM_LBUTTONUP:
Do everything like before without MouseDown()

This doesn't even work for regular clicks. I can't figure out why. Can anybody help?

A: 

It might be worth looking at the SendMessage/PostMessage P/Invoke calls, and sending the messages directly to the window of the other application. You need to do some translation on the parameters so that the co-ordinates of mouse events tie up with what you want them to in the other application, but it's not a big deal to do that...

Edit -> I dug out some code where I have done this before... This is from a window which appears over the top of a tree view and replaces the default windows tooltip for that tree view.

    private IntPtr _translate(IntPtr LParam)
    {
        // lparam is currently in client co-ordinates, and we need to translate those into client co-ordinates of
        // the tree view we're attached to
        int x = (int)LParam & 0xffff;
        int y = (int)LParam >> 16;

        Point screenPoint = this.PointToScreen(new Point(x, y));
        Point treeViewClientPoint = _tv.PointToClient(screenPoint);

        return (IntPtr)((treeViewClientPoint.Y << 16) | (treeViewClientPoint.X & 0xffff));
    }

    const int MA_NOACTIVATE = 3;

    protected override void WndProc(ref Message m)
    {
        switch ((WM)m.Msg)
        {
            case WM.LBUTTONDBLCLK:
            case WM.RBUTTONDBLCLK:
            case WM.MBUTTONDBLCLK:
            case WM.XBUTTONDBLCLK:
            {
                IntPtr i = _translate(m.LParam);
                _hide();
                InteropHelper.PostMessage(_tv.Handle, m.Msg, m.WParam, i);
                return;
            }
            case WM.MOUSEACTIVATE:
            {
                m.Result = new IntPtr(MA_NOACTIVATE);
                return;
            }
            case WM.MOUSEMOVE:
            case WM.MOUSEHWHEEL:
            case WM.LBUTTONUP:
            case WM.RBUTTONUP:
            case WM.MBUTTONUP:
            case WM.XBUTTONUP:
            case WM.LBUTTONDOWN:
            case WM.RBUTTONDOWN:
            case WM.MBUTTONDOWN:
            case WM.XBUTTONDOWN:
            {
                IntPtr i = _translate(m.LParam);
                InteropHelper.PostMessage(_tv.Handle, m.Msg, m.WParam, i);
                return;
            }         
        }
        base.WndProc(ref m);
    }
Matt Whitfield
I couldn't get SendMessage or PostMessage to work for sending mouse inputs. It is processed but not responded by the window.
Dogan Demir
I've updated my answer with some code where I've done that before.
Matt Whitfield
A: 

Mouse buttons are funky. When it gets an down then up, at some level those are converted to a click (and I think at some point the mouse up gets eaten, but I may not be recalling that correctly).

It could be any number of things, but if the other windows is (or is not) converting the buttondown/up to mouse clicks, it could be confusing your code.

I suggest you print a lot of debugging info and try to figure out exactly what the system is doing.

Bill K
Yeah but if you are doing for instance dragging, the fact that down and up are not converted to clicks should be perfectly normal, right?
Dogan Demir
Honestly I can't say. The bowels of Swing (and worse yet, awt) are deep and frightening. I do not tackle with the inner workings of AWT unless it absolutely can't be avoided. Are you sure it can't be avoided? Can your primary window's event handlers just manage the secondary window directly?
Bill K