Get the window handle under the mouse, ignoring the translucent window

I created a translucent shape (opacity 60% with a black background), which my application runs, maximizes, across the screen. Basically, it highlights gray on the entire desktop.

When the mouse user is above the window on the desktop, I want to get this window handle (hWnd).

An easy way to do this, which works for me, is:

  • Temporarily hide my form (OR, temporarily set the opacity of the form to 0.0)
  • Call [GetCursorPos] [1]
  • Call [WindowFromPoint] [2]
  • Show my form again

The problem with this approach is that my form / screen is blinking, which I don't like.

I tried to fix this in two ways:

  • I believe that there should be a way to get hWnd windows directly under my form by calling ChildWindowFromPointEx (passing hWnd desktop and CWP_SKIPTRANSPARENT ), but it does not work. I also played with [ChildWindowFromPoint] [4] and [RealChildWindowFromPoint] [5] without success. (PS Raymond Chen discusses the differences between these calls here , and it seems to me that ChildWindowFromPointEx is designed to do exactly what I need)

  • I tried to prevent the entire desktop from updating (for example, freezing the screen momentarily) using (1) SendMessage(GetDesktopWindow(), WM_SETREDRAW, false, 0) before hiding my form and (2) SendMessage(GetDesktopWindow(), WM_SETREDRAW, true, 0) after I hide my form. This did not help: some areas of the screen froze, some strange black blocks appear, etc. However, I know that (1) really works, because once I called (1) and did not call (2), and my desktop turned out to be completely frozen (I had to restart, even TaskMgr did not display correctly). I also tried using SuspendLayout and ResumeLayout in my form, but I don’t think they are meant to handle my case.

Any help would be greatly appreciated.

+3
source share
1 answer

You can do the verification yourself, as you need to customize beyond what the standard features offer.

  • Call EnumWindows() to get a list of top-level windows.
  • Remove the translucent window from this list.
  • For each window in the list, use PtInRegion() to determine if the mouse is above the window. Remove all windows that do not match the score.
  • Use GetNextWindow() , starting with one of the remaining windows, to go through the z-order and find out which of the candidates is at the top.
+5
source

All Articles