Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Letting the mouse pass through Windows C++

I am working on an Win32 C++ application where I want to ignore the mouse events and let is pass through to the window beneath my window. Basically the window below mine will handle the mouse event. I would prefer not to send the mouse message using SendMessage to the window beneath mine or use SetCapture. Is there a way basically to ignore the mouse event and let it pass through with Windows APIs or with styles? Note that my window is not transparent.

Thanks in advance for the help.

like image 763
JoderCoder Avatar asked Oct 25 '12 13:10

JoderCoder


1 Answers

So I found this question, and others, while attempting to create a music player that overlays a graphical display over the screen without impacting any other interaction, including e.g. dragging windows.

I've tried both the WM_NCHITTEST approach, as well as simply adding WS_EX_TRANSPARENT to my window. Neither of these approaches work -- they both seem to capture mouse click events, which is something I don't want.

However, by pure coincidence, I did manage to find a combination of flags I can pass to SetWindowLong(..., GWL_EXSTYLE, ...) that seem to do the trick, leading to the following code:

LONG cur_style = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, cur_style | WS_EX_TRANSPARENT | WS_EX_LAYERED);

It appears that this behavior is documented here:

Hit testing of a layered window is based on the shape and transparency of the window. This means that the areas of the window that are color-keyed or whose alpha value is zero will let the mouse messages through. However, if the layered window has the WS_EX_TRANSPARENT extended window style, the shape of the layered window will be ignored and the mouse events will be passed to other windows underneath the layered window.

The extended window style documentation is also very useful. For applications such as mine, where a window is not meant to be interacted with, WS_EX_NOACTIVATE may also be useful, as it prevents some user interactions.

For posterity's sake, I will note that the code I am using to ensure my window is always on top is the following:

SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
like image 116
TheMonsterFromTheDeep Avatar answered Sep 21 '22 07:09

TheMonsterFromTheDeep