2

I have a program running with a touch screen, but because the mouse pointer being "on" the touch screen introduces problems, the Windows-mouse behavior of the touch screen has been disabled, and a home-grown program is being used to monitor the touch screen and post messages to the window at the location the screen was touched or untouched (ie. WM_LBUTTONDOWN, WM_LBUTTONUP).

The relevant code looks something like this:

touched = false;

while (1)
{
    if (!touched) {
        // p.x and p.y calculated here based on mouse position at
        // time of touch screen event
        p.x = ...;
        p.y = ...;

        if ((window = WindowFromPoint (p)) != NULL)
            PostMessage (window, WM_LBUTTONDOWN, 0, 0);

        touched = true;
    }
    else
    {
        if ((window = WindowFromPoint (p)) != NULL)
            PostMessage (window, WM_LBUTTONUP, 0, 0);

        touched = false;
    }
}

This works, but doesn't exactly mimic Windows' mouse press behavior -- regardless of the position of the touch when the untouch occurs (ie. if a touch was dragged), the WM_LBUTTONUP is sent to the control that received the WM_LBUTTONDOWN.

What I was trying to do was make it more Windows-like. In any application, open a dialog that has a button on it. Click and hold the mouse on the button, you'll see it depress. Drag the mouse off the button and don't release the mouse, and you'll see the button raise again. Drag the mouse back onto the button and you'll see it depress. If you release the mouse while the pointer is on the button, the button is pressed. If you release the mouse while the pointer is off the button, the button is not pressed.

I set up a low-level mouse hook, and can see that the only mouse events that occur during this sequence are WM_LBUTTONDOWN followed by a series of WM_MOUSEMOVE followed by a WM_LBUTTONUP, regardless of whether the mouse is released on or off the button.

I have tried adding alternative handling for when the mouse is dragged, and have this posting WM_MOUSEMOVE messages, but which control should these be sent to? The button that the WM_LBUTTONDOWN event was originally sent to, or elsewhere? I have tried both the button and the window the button is on, but obviously I've done something wrong as it doesn't seem to work. The best I have been able to achieve is the touch screen button not being "clicked" when I untouch off the button, but the touch screen button is still drawn depressed.

Any suggestions?

Can anyone confirm which events should be sent where during this operation?

Thanks for any advice.

maxx777
  • 1,320
  • 1
  • 20
  • 37
Mark
  • 21
  • 1
  • 2
  • Did you check this question: http://stackoverflow.com/questions/5164774/how-can-i-simulate-mouse-events-from-code – iammilind Jul 14 '11 at 04:17
  • I have tried SendInput, but the problem is that SendInput (unless I did something wrong) makes the mouse pointer react as if the mouse event I sent had actually happened -- so if I'm sending a mouse click to another location, the mouse actually moves to that other location. What it is I'm trying to do is send the underlying WM_LBUTTONDOWN, WM_MOUSEMOVE and WM_LBUTTONUP messages (and any other messages if there are any) to the appropriate control(s) as if the mouse was actually clicked and/or dragged there, but without moving the mouse pointer there. – Mark Jul 14 '11 at 07:25
  • If you want to hide the mouse pointer, your best bet might be to set the mouse pointer to an invisible one. The catch with using WM_ messages instead of using SendInput is that if the target app uses GetCursorPos or Get[Async]KeyState to check mouse position or button state, it will get the actual state, not the one you're trying to fake. (Also, if the app is doing something odd like processing input in a hook or a message loop rather than in a window proc, it might not work when you post messages instead.) But if you own the target app(s) in this case, you can plan for that. – BrendanMcK Dec 15 '11 at 10:08

1 Answers1

0

This is your code:

    PostMessage (window, WM_LBUTTONDOWN, 0, 0);

Can you try this instead of the above line:

    DWORD dw = MAKEWORD(p.x, p.y);
    PostMessage (window, WM_LBUTTONDOWN, MK_LBUTTON, dw);

I think this code should work.

Ajit Vaze
  • 2,686
  • 2
  • 20
  • 24
  • MAKEWORD creates a word from bytes...you need at least MAKELONG, though Windows mouse button messages actually take LPARAM: http://stackoverflow.com/questions/8490389/wm-mousemove-packing-x-and-y-positions/8490518#8490518 – HostileFork says dont trust SE Dec 14 '11 at 09:24