Получить дескриптор окна под указателем мыши, игнорируя полупрозрачное окно - PullRequest
3 голосов
/ 04 августа 2011

Я создал полупрозрачную форму (непрозрачность 60% с черным цветом фона), которую мое приложение запускает в развернутом виде по всему экрану. По сути, он окрашивает серый цвет на весь рабочий стол.

Когда пользователь наводит курсор на окно на рабочем столе, я хочу получить дескриптор этого окна (hWnd).

Простой способ сделать это, который работает для меня, это:

  1. Временно скрыть мою форму (ИЛИ временно установить непрозрачность моей формы на 0.0)
  2. Call [GetCursorPos] [1]
  3. Call [WindowFromPoint] [2]
  4. Показать мою форму еще раз

Проблема с этим подходом заключается в том, что моя форма / экран мигает, что мне не нравится.

Я пытался исправить это двумя способами:

  • Я полагаю, что должен быть способ получить hWnd окна непосредственно под моей формой, вызвав ChildWindowFromPointEx (передавая hWnd рабочего стола и CWP_SKIPTRANSPARENT), но это не похоже на работу. Я также играл с [ChildWindowFromPoint] [4] и [RealChildWindowFromPoint] [5], но безуспешно. (П.С. Раймонд Чен обсуждает различия между этими вызовами, здесь , и мне кажется, что ChildWindowFromPointEx разработан именно для того, что мне нужно)

  • Я попытался предотвратить обновление всего рабочего стола (на мгновение «заморозив» экран) с помощью (1) SendMessage(GetDesktopWindow(), WM_SETREDRAW, false, 0) перед тем, как скрыть свою форму, и (2) SendMessage(GetDesktopWindow(), WM_SETREDRAW, true, 0) после того, как я скрыл свою форму. Это не сработало совсем: некоторые области экрана зависли, появились странные черные блоки и т. Д. Однако я знаю, что (1) работает, потому что однажды я позвонил (1) и не сделал call (2), и мой рабочий стол оказался полностью замороженным (пришлось перезагрузить компьютер, даже TaskMgr не отображался правильно). Я также пытался использовать SuspendLayout и ResumeLayout в своей форме, но я не думаю, что они предназначены для моего случая.

Любая помощь будет принята с благодарностью.

1 Ответ

5 голосов
/ 04 августа 2011

Вы можете выполнить проверку самостоятельно, поскольку вам необходимо настроить сверх того, что предлагают стандартные функции.

  1. Позвоните EnumWindows(), чтобы получить список окон верхнего уровня.
  2. Удалите ваше полупрозрачное окно из этого списка.
  3. Для каждого окна в списке используйте PtInRegion(), чтобы определить, находится ли мышь над окном.Удалите все окна, которые не соответствуют требованиям.
  4. Используйте GetNextWindow(), начиная с одного из оставшихся окон, чтобы пройти z-порядок и выяснить, кто из кандидатов находится сверху.
...