问题
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