Windows SendInput makes mouse cursor flicker and disappear

纵然是瞬间 提交于 2019-12-02 08:59:47

问题


I'm writing a Windows Desktop program in C++ that consumes all touch screen input, replacing it with mouse input created via SendInput. So far I just want any movement made with a finger on the touch screen to be sent as a mouse delta. I should, for example, be able to use the physical mouse to place the cursor near the top of the screen, then drag my finger in a horizontal line along the bottom of the screen and see the cursor replicate that movement above.

This works except for three issues;

  • Whilst I move my finger the cursor rapidly flickers between a normal mouse icon and one with a progress wheel.
  • When I remove my finger the cursor jumps to my finger's last position, though if I touch the screen again it jumps back.
  • If I hold my finger still on the screen the cursor completely disappears (it could be positioned under my finger but I obviously can't see there)

A little more detail about what I am doing;

I use CreateWindowEx to create an invisible message-only window.

I then use RegisterPointerInputTarget to insure all touch input is sent to my window.

In my WndProc function I return 0 without calling DefWindowProc, for all WM_POINTERENTER, WM_POINTERLEAVE, WM_POINTERUP, WM_POINTERDOWN, WM_POINTERUPDATE, WM_POINTERCAPTURECHANGED and WM_TOUCH messages.

I use WM_POINTERDOWN to detect new touches, WM_POINTERUPDATE to send appropriate mouse updates with SENDINPUT and WM_POINTERUP/WM_POINTERCAPTURECHANGED to stop tracking the touch.

*******EDIT*******

I now have a fix for the cursor disappearing when the user removes their finger from the screen; send two mouse movements from the WM_POINTERUP message. I don't actually want the cursor to move at all so I send one movement of (1, 0) and then one of (-1, 0). This feels like a hack, I am sure it is, so if anyone has a better suggestion please let me know.

To fix the mouse disappearing when the finger is held still on the screen I had to do the same thing in the WM_POINTERUPDATE message; split each movement I would send from there into two messages. I also had to make sure I was sending a movement for each WM_POINTERUPDATE received (I had been skipping empty ones).

This only leaves the mouse flickering problem. This can be reproduced much more simply. Just use visual studio to create a new windows desktop application and add this code to the WndProc function;

    case WM_POINTERUPDATE:
    {
        INPUT Inputs[1] = { 0 };
        Inputs[0].type = INPUT_MOUSE;
        Inputs[0].mi.dx = 1;
        Inputs[0].mi.dy = 0;
        Inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE;
        SendInput(1, Inputs, sizeof(INPUT));
    }

Run the program, touch the screen inside the application window and the flickering occurs, This only happens if the SendInput calls are made from WM_POINTERUDPATE so I suspect the issue is to do with Windows wanting to hide the cursor as this is what normally happens when the user touches the screen.

Any suggestions?

来源:https://stackoverflow.com/questions/56418729/windows-sendinput-makes-mouse-cursor-flicker-and-disappear

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!