在我自己的进程中无法从 window 获取鼠标输入
Impossible to get mouse input from a window in my own process
我一直在尝试为我在 .Net 4 中制作的图像查看器应用程序添加视频支持。经过长时间的研究和多次测试,我决定使用 LibVLC, which is free and supports a large number of file formats (more than Windows Media Player, for instance). There's a wrapper library for .Net called Meta.VLC,这似乎工作正常。为简单起见,我将所有内容都保留在 32 位范围内。当我想处理视频帧上的鼠标事件时,问题就来了,它被绘制到我的一个控件中(我给库我的 HWND,它显然使用 Direct3D 进行渲染)。
库不公开任何鼠标事件,但我说 "Hey! No problem! I know enough Win32 API to sort this out"。首先,我认为我可以通过覆盖它的 WndProc. Nope. Then I thought I could implement IMessageFilter.PreFilterMessage. Nope again. WM_LMOUSEDOWN and other related mouse events do not reach my form. Somehow they're "eaten up" by the child window. I've used Spy++ 来拦截来自我的表单的鼠标消息,并且我确定视频 window 确实在我的进程中并且是我的表单的后代:
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++ 我可以看到鼠标事件确实正在生成并发送到视频输出 window 没问题。但是,我无法从我的表格中看到它们。然后!我以为我可以通过使用 SetWindowsLong(GWL_WNDPROC) 子类化子类或孙子类 window,但是尽管我成功地子类化了 windows,鼠标消息对我来说仍然是隐藏的!
WH_MOUSE (SetWindowsHookEx) 的本地 Windows 挂钩也不起作用。我可以看到我的线程的鼠标事件,但看不到视频 window 的鼠标事件。我想我可以使用全局挂钩 (WH_MOUSE_LL) 来做到这一点,但这需要管理员访问权限,我想保持我的应用低调。
最后一点,我确实收到了 WM_PARENTNOTIFY 条消息,但仅限于 WM_LMOUSEDOWN;我想要完整的鼠标支持,例如 WM_LMOUSEUP、WM_RMOUSEDOWN、WM_MOUSEWHEEL、WM_MOUSEMOVE 等,但我没有收到。另外,我不想使用鼠标捕获(SetCapture() 功能):鼠标应该在 windows.
之间自由进出
我很惊讶无法从此视频帧获取鼠标输入。我想我一定遗漏了一些非常明显的东西,但我找不到它。
所以,问题是:使用 .Net 或 Win32 API 调用,如果 window 运行,我如何从拒绝合作的 window 获取鼠标输入在我自己的过程中,我有它的句柄。或者 - 如果做不到 - 为什么我不能?
也许您可以尝试在 VLC window 上添加透明 window 并从该 window 获取鼠标输入。
鼠标挂钩对我有用。查看 VLC Web 插件的来源:https://code.videolan.org/videolan/npapi-vlc/blob/master/common/win32_fullscreen.cpp
我一直在尝试为我在 .Net 4 中制作的图像查看器应用程序添加视频支持。经过长时间的研究和多次测试,我决定使用 LibVLC, which is free and supports a large number of file formats (more than Windows Media Player, for instance). There's a wrapper library for .Net called Meta.VLC,这似乎工作正常。为简单起见,我将所有内容都保留在 32 位范围内。当我想处理视频帧上的鼠标事件时,问题就来了,它被绘制到我的一个控件中(我给库我的 HWND,它显然使用 Direct3D 进行渲染)。
库不公开任何鼠标事件,但我说 "Hey! No problem! I know enough Win32 API to sort this out"。首先,我认为我可以通过覆盖它的 WndProc. Nope. Then I thought I could implement IMessageFilter.PreFilterMessage. Nope again. WM_LMOUSEDOWN and other related mouse events do not reach my form. Somehow they're "eaten up" by the child window. I've used Spy++ 来拦截来自我的表单的鼠标消息,并且我确定视频 window 确实在我的进程中并且是我的表单的后代:
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++ 我可以看到鼠标事件确实正在生成并发送到视频输出 window 没问题。但是,我无法从我的表格中看到它们。然后!我以为我可以通过使用 SetWindowsLong(GWL_WNDPROC) 子类化子类或孙子类 window,但是尽管我成功地子类化了 windows,鼠标消息对我来说仍然是隐藏的!
WH_MOUSE (SetWindowsHookEx) 的本地 Windows 挂钩也不起作用。我可以看到我的线程的鼠标事件,但看不到视频 window 的鼠标事件。我想我可以使用全局挂钩 (WH_MOUSE_LL) 来做到这一点,但这需要管理员访问权限,我想保持我的应用低调。
最后一点,我确实收到了 WM_PARENTNOTIFY 条消息,但仅限于 WM_LMOUSEDOWN;我想要完整的鼠标支持,例如 WM_LMOUSEUP、WM_RMOUSEDOWN、WM_MOUSEWHEEL、WM_MOUSEMOVE 等,但我没有收到。另外,我不想使用鼠标捕获(SetCapture() 功能):鼠标应该在 windows.
之间自由进出我很惊讶无法从此视频帧获取鼠标输入。我想我一定遗漏了一些非常明显的东西,但我找不到它。
所以,问题是:使用 .Net 或 Win32 API 调用,如果 window 运行,我如何从拒绝合作的 window 获取鼠标输入在我自己的过程中,我有它的句柄。或者 - 如果做不到 - 为什么我不能?
也许您可以尝试在 VLC window 上添加透明 window 并从该 window 获取鼠标输入。
鼠标挂钩对我有用。查看 VLC Web 插件的来源:https://code.videolan.org/videolan/npapi-vlc/blob/master/common/win32_fullscreen.cpp