tldr: я использую LowLevelMouseProc для захвата всех событий касания с сенсорного экрана. Это работает для моего приложения и некоторых других приложений, но, к сожалению, не для всех приложений. Может кто-нибудь объяснить мне, почему?
Полная история:
У меня есть приложение C #, которое использует LowLevelMouseProc + SetWindowsHookEx для определения положения касания на сенсорном экране. Крючок позволяет мне фиксировать все прикосновения к сенсорному экрану.
- если мое приложение на переднем плане
- для рабочего стола Windows (мое приложение свернуто)
- для некоторых приложений, например Visual Studio или Firefox
К сожалению, этот механизм работает не для всех приложений, например он не фиксирует никаких касаний, сделанных в области отображения, охватываемой Google Chrome.
- Означает ли это, что, например, Google Chrome уже использует событие касания и не вызывает последующих обработчиков событий (включая мою ловушку)? Кто-то еще сделал аналогичное наблюдение? Кто-нибудь может объяснить такое поведение?
Обновление. Сенсорные хуки работают даже в Chrome, но только в области контекстных меню (например, во всплывающем окне, которое появляется при щелчке правой кнопкой мыши на веб-сайте). Это может поддерживать теорию о том, что Chrome использует события касания.
Другие подчеркнули, что необходимо, чтобы обратный вызов LowLevelMouseProc находился в отдельной DLL. Кроме того, другие говорят, что также требуется, чтобы внешнее приложение и DLL имели одинаковую архитектуру (x86, x64). См. соответствующий пост здесь.
- В моем проекте все методы обработки событий касания находятся в отдельной DLL. Кроме того, у обратного вызова есть собственный поток. Как было сказано выше, это хорошо работает для некоторых приложений, но не для всех, независимо от того, скомпилирован ли мой проект (* .exe + * .dll) как приложение x86 / x64.
Интересно, что ловушка работает для всех приложений, включая Google Chrome, при захвате событий мыши. Для событий мыши и касания используется один и тот же обратный вызов:
[StructLayout(LayoutKind.Sequential)]
public struct MSLLHOOKSTRUCT
{
public POINT pt;
public int mouseData;
public int flags;
public int time;
public UIntPtr dwExtraInfo;
}
... еще код ...
if (wParam == WM.MOUSEMOVE)
{
var info = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
var extraInfo = (uint)info.dwExtraInfo;
if ((extraInfo & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH)
{// Touch Move
Console.WriteLine("Touch move");
} else
{
Console.WriteLine("Mouse move");
}
}
Это означает, что сначала должно произойти событие WM.MOUSEMOVE (= WM_MOUSEMOVE). Затем код идентифицирует события касания / мыши, просматривая info.dwExtraInfo.
Это наблюдение похоже на вопрос (1) и может означать, что Google Chrome имеет собственный перехватчик касаний и не вызывает последующих обратных вызовов (возможно, из соображений безопасности?). Кто-нибудь может это проверить?
В конечном итоге я заинтересован в захвате всех событий касания, независимо от приложения на переднем плане. Кто-нибудь знает более надежный подход?