Невозможно получить ввод с помощью мыши из окна в моем собственном процессе

Я пытался добавить поддержку видео в свое приложение для просмотра изображений, которое я сделал в .Net 4. После долгих исследований и многих тестов я решил использовать LibVLC, который является бесплатным и поддерживает большое количество форматов файлов (например, больше, чем Windows Media Player). Для .Net есть библиотека-оболочка под названием Meta.VLC, которая, похоже, работает нормально. Для простоты я сохраняю все в 32-битной области. Проблема возникает, когда я хочу обработать события мыши на видеокадре, который нарисован в одном из моих элементов управления (я даю библиотеке свой HWND, и она, по-видимому, использует Direct3D для рендеринга).

Библиотека не предоставляет никаких событий мыши, но я сказал: «Эй! Нет проблем! Я знаю достаточно Win32 API, чтобы разобраться в этом». Во-первых, я подумал, что могу перехватить сообщения мыши из моей формы, переопределив его WndProc. Неа. Тогда я подумал, что могу реализовать IMessageFilter.PreFilterMessage. Опять нет. WM_LMOUSEDOWN и другие связанные события мыши не доходят до моей формы. Как-то их «съедает» дочернее окно. Я использовал Spy ++, и я установлено, что видеоокно действительно находится в моем процессе и является потомком моей формы:

My control HWND contains
    Caption: "VLC (Direct3D output)", Class: "VLC video main 087CCA50"
which contains
    Caption: "", Class: "VLC video output 087CCA50"
which receives all the mouse input.

С помощью Spy ++ я вижу, что события мыши действительно генерируются и без проблем отправляются в окно вывода видео. Однако я не вижу их в своей форме. Потом! Я думал, что могу создать подкласс либо дочернее окно, либо окно внука, используя SetWindowsLong (GWL_WNDPROC), но хотя мне удалось создать подклассы окон, сообщения мыши по-прежнему скрыты для меня!

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

В заключение, я получаю сообщения WM_PARENTNOTIFY, но только для WM_LMOUSEDOWN; Мне нужна полная поддержка мыши, например WM_LMOUSEUP, WM_RMOUSEDOWN, WM_MOUSEWHEEL, WM_MOUSEMOVE и т. Д., Которые я не получаю. Кроме того, я не хочу использовать захват мыши (SetCapture ()): мышь должна оставаться свободной, чтобы перемещаться между окнами.

Я удивлен, что нет возможности получить ввод от мыши из этого видеокадра. Я думаю, что мне не хватает чего-то действительно очевидного, но я не могу этого найти.

Итак, вопрос: используя вызовы .Net или Win32 API, как мне получить ввод от мыши из окна, которое отказывается сотрудничать, учитывая, что окно работает в моем собственном процессе, и у меня есть его дескриптор. Или - если это невозможно - почему я не могу?


person Guillermo Prandi    schedule 25.05.2016    source источник
comment
Вы можете попробовать установить для свойства формы KeyPreview значение true, но если это не сработает, тогда Необработанный ввод, вероятно, ваш лучший выбор.   -  person theB    schedule 25.05.2016
comment
Возможно, вы можете попробовать добавить прозрачное окно поверх окна VLC и получить ввод мыши из этого окна.   -  person Ton Plooij    schedule 25.05.2016
comment
@theB AFAIK, KeyPreview работает только для ключей. Я рассматривал необработанный ввод, но считаю, что не смогу перевести положение мыши в точку формы, поскольку он работает со значениями устройства (например, до баллистики)? В структуре RAWMOUSE есть флаг MOUSE_VIRTUAL_DESKTOP, но неясно, будут ли сообщения содержать этот флаг и когда это будет. :(   -  person Guillermo Prandi    schedule 25.05.2016
comment
@TonPlooij Я попробую! Выглядит многообещающе.   -  person Guillermo Prandi    schedule 25.05.2016
comment
Они будут съедены сфокусированным контролем. Я ничего не знаю о LibBLC, но я поискал в Google события мыши в LibVLC и обнаружил функцию libvlc_video_set_mouse_input, которая позволяет включать или отключать обработку событий щелчка мыши. Похоже на то, что ты хочешь. Ваша цель - отключить LibVLC от использования событий мыши, чтобы вы могли их обрабатывать. (Я бы по возможности избегал гигантского взлома создания прозрачного окна ...)   -  person Cody Gray    schedule 25.05.2016
comment
@CodyGray Meta.VLC, оболочка C #, которую я использую, не предоставляет libvlc_video_set_mouse_input (). :( Я все равно разберусь.   -  person Guillermo Prandi    schedule 25.05.2016
comment
@TonPlooij Прозрачное окно сделало это !!!! Большое тебе спасибо!!   -  person Guillermo Prandi    schedule 26.05.2016
comment
Приятно слышать, спасибо! Если вы не против, я отправлю свой комментарий в качестве ответа, чтобы вы могли отметить вопрос как ответ.   -  person Ton Plooij    schedule 26.05.2016
comment
Кстати, после этого я узнал, что сообщения, вводимые мышью, не являются настоящими сообщениями: они сфабрикованы вызовом GetMessage () с установленными в потоке флагами. Видимо, поэтому подклассы окон не работали.   -  person Guillermo Prandi    schedule 27.05.2016


Ответы (2)


Возможно, вы можете попробовать добавить прозрачное окно поверх окна VLC и получить ввод мыши из этого окна.

person Ton Plooij    schedule 26.05.2016

Крючок для мыши у меня сработал. Посмотрите источники веб-плагина VLC: https://code.videolan.org/videolan/npapi-vlc/blob/master/common/win32_fullscreen.cpp

person RSATom    schedule 04.06.2016
comment
У меня это не сработало. Возможно, это из-за управляемых / неуправляемых переходов в .Net? В любом случае прозрачное окно работает как шарм. Спасибо! - person Guillermo Prandi; 05.06.2016