Низкоуровневый крючок мыши - зависание мыши на точке останова

Я хотел бы самостоятельно рисовать и перемещать свои окна (используя хромированный фреймворк). Для этого мне нужен глобальный обратный вызов, когда мышь перемещается за пределы моего окна, поэтому я установил крючок мыши низкого уровня:

hMouseLLHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)mouseHookProc, hInstance, NULL);

Хук простой захватывает события мыши и вызывает CallNextHookEx. Здесь проблем нет, все работает как положено. Моя проблема сейчас: если отладчик ломается или возникает исключение, я больше не могу двигать мышью ..

Я попытался обработать крючок в другом потоке, например:

HANDLE mouseProcHandle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)mouseProcessor, NULL, NULL, &dwMouseProcThread);

DWORD WINAPI Win32Application::mouseProcessor(LPVOID lpParm) {
    hMouseLLHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)mouseHookProc, ((Win32Application*)Application::getInstance())->hInstance, NULL);

    MSG message;
    while (GetMessage(&message, NULL, 0, 0)) {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }

    UnhookWindowsHookEx(hMouseLLHook);
    return 0;
}

Но это тоже не решает проблемы. Есть ли обходной путь, решение или другой способ сделать это? Кроме того, я думаю, что ловушка низкого уровня может не понадобиться, так как мне нужно только знать о движении, и не было бы проблем, если бы я был последним в очереди, чтобы система / другие процессы могли обрабатывать сначала обратные вызовы мыши.


person lunatix    schedule 02.03.2014    source источник
comment
Крючок не сломаешь, крючок тебя сломает!   -  person CodeAngry    schedule 02.03.2014
comment
Неужели для этого нужен крючок? Захват недостаточно хорош?   -  person Raymond Chen    schedule 02.03.2014
comment
Было бы достаточно, но он должен быть везде и независимо от окон. У вас есть другое решение для архивации этого?   -  person lunatix    schedule 02.03.2014


Ответы (2)


Поскольку ваш отладчик останавливает всю программу (все ее потоки)
вероятно, нет обходного пути при использовании ловушки.
Не так точно, но вместо этого вы можете опросить GetCursorPos в потоке.

person deviantfan    schedule 02.03.2014
comment
это было бы приемлемым решением для отладочной версии, я думаю ... не очень хороший обходной путь, но он сработает :) - person lunatix; 02.03.2014
comment
... или, может быть, social.msdn.microsoft.com/Forums/vstudio/en-US/ помогает. Я тоже не знал, что это возможно до сих пор (если это правильно), спасибо, что подняли эту тему :) - person deviantfan; 02.03.2014
comment
Принял этот ответ, потому что он указал мне правильное направление. Окончательное решение заключалось в использовании обычного крючка мыши (не нижнего уровня) для каждого из окон, которые создаются из хрома - отображение выполняется с помощью дескриптора HWND (это дочернее окно, поэтому просто найдите его родительское) данного MOUSEHOOKSTRUCTEX. Работает как шарм. Спасибо всем :) - person lunatix; 05.03.2014

Чтобы пролить немного больше света на это: когда вы перехватываете все события перемещения мыши, все они попадают в ваш крючок, который может их изменить или проглотить. Таким образом, система вызывает для каждого события перемещения мыши вашу ловушку и ждет, пока ваша процедура ловушки не закончит с ней, пока она снова не вызовет вашу ловушку для следующего ожидающего события перемещения мыши.

Угадайте, что происходит, когда вы вторгаетесь в отладчик в своем событии перехвата? Никаких больше событий мыши, пока вы не пройдете через процедуру ловушки. Обычно вы можете вывести из строя всю вашу систему с помощью такого центрального крючка. Но, к счастью, Windows предвидела плохие ловушки. Вы заметите, что через некоторое время система снова реагирует на события мыши. Я предполагаю, что Windows просто удалит ваш крючок, когда он однажды зависнет.

Теперь об отладке: единственный способ безопасно взломать отладчик - никогда не касаться мыши после того, как вы попали в ловушку. Не очень практично. Единственный выход - отследить интересные вещи и посмотреть в файл журнала, что же произошло внутри хука. Если вам нужен пример кода, как подключать события мыши и клавиатуры, вы можете посмотреть здесь:

http://etwcontroler.codeplex.com/SourceControl/latest#ETWControler/Hooking/Hooker.cs < / а>

person Alois Kraus    schedule 02.03.2014
comment
Hooker.cs - классика! - person CodeAngry; 02.03.2014
comment
Спасибо за ссылку на C #, я буду иметь это в виду при разработке .net :) О, и я не говорил о взломе только внутри самого крючка, это было более общим - нарушение где-либо вызывает проблему - как будто вы это упомянули , потому что мой метод останавливает очередь обратного вызова. Мое приложение запускает несколько потоков, поэтому, возможно, можно остановить только поток приложений, но не поток-перехватчик (например, @deviantfan, опубликованный выше). - person lunatix; 02.03.2014