Search code examples
.netwinapimouselibvlc

Impossible to get mouse input from a window in my own process


I've been trying to add video support to my image viewer application which I made in .Net 4. After long research and many tests I've decided for 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 which seems to work alright. For simplicity, I keep everything within the 32 bit realm. The problem comes when I want to process mouse events on the video frame, which is drawn into one of my controls (I give the library my HWND and it apparently uses Direct3D for rendering).

The library doesn't expose any mouse events, but I said "Hey! No problem! I know enough Win32 API to sort this out". First, I've thought I could intercept mouse messages from my form by overriding its 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++ and I established that the video window is indeed within my process and is a descendant of my form:

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.

With Spy++ I can see that mouse events are indeed being generated and are sent to the video output window no problem. However, I cannot see them from my form. Then! I thought I could subclass either the child or the grandchild window by using SetWindowsLong(GWL_WNDPROC), but although I succeeded in subclassing the windows, mouse messages are still hidden to me!

A local Windows hook for WH_MOUSE (SetWindowsHookEx) didn't work either. I can see my thread's mouse events but not the video window's. I think I could do this with a global hook (WH_MOUSE_LL) but that would require administrator access rights and I'd like to keep my app low profile.

As a final note, I do get WM_PARENTNOTIFY messages, but only for WM_LMOUSEDOWN; I'd like full mouse support, like WM_LMOUSEUP, WM_RMOUSEDOWN, WM_MOUSEWHEEL, WM_MOUSEMOVE, etc. which I don't receive. Also, I don't want to use mouse capture (SetCapture() function): mouse should remain free to come and go between windows.

I'm astonished there's no way to obtain the mouse input from this video frame. I think I must be missing something really obvious but I can't find it.

So, the question is: using .Net or Win32 API calls, how do I get mouse input from a window that refuses to cooperate, given that the window runs within my very own process and I have its handle. Or -if it can't be done- why can't I?


Solution

  • Perhaps you can try adding a transparent window over the VLC window and getting the mouse input from that window.