"When the application window does NOT have the focus, sometimes the click handler is not called on button-touch."
System:
Windows 8.1 with a multi-touch input device.
Software:
A simple WPF 4.5.2 application with just one button that logs if the click handler is called (just create a new project and add a button with a click handler to the MainWindow).
Phenomenon:
Normally when touching the button its click handler is called. But when the application window does NOT have the focus, sometimes the click handler is not called on button-touch (although the button color changes to blue). When the application window has already the focus, touching the button works all the time. This happens only sometimes but occurs on various systems with different touch hardware (all windows 8.1). I never experienced it on windows 7. With the mouse it works regardless if the window is focused or not.
(Happens in release and debug mode, with and without debugger attached)
Testing:
I checked the various touch settings in windows and played with it. I also re-calibrating the touch -> no difference.
When checking the WPF button mouse and touch events, then in the error case the last received event is PreviewMouseUp but no Click!
When I look at the received window messages (spy++) I get the following (WM_IME_SETCONTEXT, WM_GETTEXT, WM_NCHITTEST, WM_GETOBJECT removed for a better overview):
Click was received:
R WM_POINTERACTIVATE pmsd->lResult:FFFFFFFFFFFFFFFF
S WM_MOUSEACTIVATE hwndTopLevel:000503F8 nHittest:HTCLIENT uMsg:WM_POINTERDOWN
R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
S WM_WINDOWPOSCHANGING lpwp:000000E9E3D9E410
R WM_WINDOWPOSCHANGING
S WM_WINDOWPOSCHANGED lpwp:000000E9E3D9E410
R WM_WINDOWPOSCHANGED
S WM_ACTIVATEAPP fActive:True dwThreadID:00000000
R WM_ACTIVATEAPP
S WM_NCACTIVATE fActive:True
R WM_NCACTIVATE
S WM_ACTIVATE fActive:WA_ACTIVE fMinimized:False hwndPrevious:(null)
S WM_IME_NOTIFY dwCommand:IMN_OPENSTATUSWINDOW dwCommand:00000002 dwData:00000000
R WM_IME_NOTIFY
S WM_SETFOCUS hwndLoseFocus:(null)
R WM_SETFOCUS
R WM_ACTIVATE
S message:0x02CC [Unknown] wParam:00000000 lParam:00C50BA8
R message:0x02CC [Unknown] lResult:00000100
P WM_POINTERENTER wPointerID:0099 wFlags:6017
S WM_SETCURSOR hwnd:000503F8 nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
R WM_SETCURSOR fHaltProcessing:False
P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:145 yPos:62
R WM_POINTERCAPTURECHANGED
P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:145 yPos:62
P WM_POINTERLEAVE wPointerID:0099 wFlags:6000
P WM_LBUTTONUP fwKeys:0000 xPos:145 yPos:62
P WM_MOUSEMOVE fwKeys:0000 xPos:145 yPos:62
S WM_CAPTURECHANGED hwndNewCapture:000503F8
R WM_CAPTURECHANGED
S WM_CAPTURECHANGED hwndNewCapture:00000000
R WM_CAPTURECHANGED
S WM_SETCURSOR hwnd:000503F8 nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
R WM_SETCURSOR fHaltProcessing:False
P WM_MOUSEMOVE fwKeys:0000 xPos:145 yPos:62
Click NOT received
S message:0x02CC [Unknown] wParam:00000000 lParam:00AE0BA9
R message:0x02CC [Unknown] lResult:00000100
R WM_POINTERACTIVATE pmsd->lResult:FFFFFFFFFFFFFFFF
S WM_MOUSEACTIVATE hwndTopLevel:000503F8 nHittest:HTCLIENT uMsg:WM_POINTERDOWN
R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
S WM_WINDOWPOSCHANGING lpwp:000000E9E3D9E410
R WM_WINDOWPOSCHANGING
S WM_WINDOWPOSCHANGED lpwp:000000E9E3D9E410
R WM_WINDOWPOSCHANGED
S WM_ACTIVATEAPP fActive:True dwThreadID:00000000
R WM_ACTIVATEAPP
S WM_NCACTIVATE fActive:True
R WM_NCACTIVATE
S WM_ACTIVATE fActive:WA_ACTIVE fMinimized:False hwndPrevious:(null)
S WM_IME_NOTIFY dwCommand:IMN_OPENSTATUSWINDOW dwCommand:00000002 dwData:00000000
R WM_IME_NOTIFY
S WM_SETFOCUS hwndLoseFocus:(null)
R WM_SETFOCUS
R WM_ACTIVATE
P WM_POINTERENTER wPointerID:0090 wFlags:6017
S WM_SETCURSOR hwnd:000503F8 nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
R WM_SETCURSOR fHaltProcessing:False
P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:147 yPos:39
R WM_POINTERCAPTURECHANGED
S WM_SETCURSOR hwnd:000503F8 nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
R WM_SETCURSOR fHaltProcessing:False
P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:147 yPos:39
P WM_POINTERLEAVE wPointerID:0090 wFlags:6000
S WM_SETCURSOR hwnd:000503F8 nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
R WM_SETCURSOR fHaltProcessing:False
P WM_LBUTTONUP fwKeys:0000 xPos:147 yPos:39
S WM_SETCURSOR hwnd:000503F8 nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
R WM_SETCURSOR fHaltProcessing:False
P WM_MOUSEMOVE fwKeys:0000 xPos:147 yPos:39
S WM_SETCURSOR hwnd:000503F8 nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
R WM_SETCURSOR fHaltProcessing:False
P WM_MOUSEMOVE fwKeys:0000 xPos:147 yPos:39
S WM_SETCURSOR hwnd:000503F8 nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
R WM_SETCURSOR fHaltProcessing:False
P WM_MOUSEMOVE fwKeys:0000 xPos:147 yPos:39
In the error there are additional lines
S WM_SETCURSOR hwnd:000503F8 nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
R WM_SETCURSOR fHaltProcessing:False
before WM_LBUTTONUP. But I don't know if this matter.
I already tried to debug the .net code to see which condition causes to not call the Click handler but I soon got lost in the System.Windows.Input.InputManager and the PromoteMainToMouse() function of System.Windows.Input.StylusLogic.
I'm really running out of ideas what to check. So it would be great if someone could give me advice what else to test or where to set breakpoints in .net to find the root-cause. Or even better find a solution/workaround.
UPDATE:
I found out that I can reproduced the phenomenon also if the mouse pointer is just moved away from the application window (at least on our platforms). And the probability for the bug to occur seems to increase with the complexity of the user interface – my test app not always fails to recognize the click but a complex WPF app fails each time.
You should be able to reproduce it with the WPF developer studio (e.g. version 2013) on Windows 8.1 with a touch device:
- have the developer studio open to cover only half of the touch screen
- move away the move so that the cursor points to the desktop area
- touch to a button (e.g. “start debugging” – the play button): In my case the first touch never causes a click event.
It has turned out to be a BUG in WPF. There is a workaround available until a KB is released.
The workaround is to call Mouse.Synchronize();
in the PreviewTouchDown
event handler of the affected UIElement of MainWindow.
I tested it and it works fine.
I had the same issue and found that disabling the RealTimeStylus (effectivly disabling touch support) worked for me and resulted in mouse events always being raised on touch.
We were using an industrial touchscreen with multitouch support on Windows 10.
public static void DisableWPFTabletSupport()
{
// Get a collection of the tablet devices for this window.
TabletDeviceCollection devices = System.Windows.Input.Tablet.TabletDevices;
if (devices.Count > 0)
{
// Get the Type of InputManager.
Type inputManagerType = typeof(System.Windows.Input.InputManager);
// Call the StylusLogic method on the InputManager.Current instance.
object stylusLogic = inputManagerType.InvokeMember("StylusLogic",
BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
null, InputManager.Current, null);
if (stylusLogic != null)
{
// Get the type of the stylusLogic returned from the call to StylusLogic.
Type stylusLogicType = stylusLogic.GetType();
// Loop until there are no more devices to remove.
while (devices.Count > 0)
{
// Remove the first tablet device in the devices collection.
stylusLogicType.InvokeMember("OnTabletRemoved",
BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
null, stylusLogic, new object[] { (uint)0 });
}
}
}
}
来源:https://stackoverflow.com/questions/28441538/touching-a-wpf-button-does-sometimes-not-invoke-the-click-handler-under-windows