Из того, что я могу сказать, вызов SetWindowPos
не возвращается до тех пор, пока процесс, владеющий процессом целевого окна, не отправит сообщение WM_WindowPosChanging
и WM_WindowPosChanged
.
Во время WM_WindowPosChanging не представляется возможным узнать, станет ли форма самой верхней, тем более предотвратить ее (hwndInsertAfter больше не является HWND_TOPMOST и даже не ссылается на окно TOPMOST). Так что мы мало что можем сделать здесь, так как не знаем, попадаем ли мы в беду.
Однако при обработке WM_WindowPosChanged стиль WS_EX_TOPMOST был применен к стилю окна. Таким образом, к этому моменту вы знаете, что вы были наивысшим.
Так что теперь ... Как мы можем заставить "процесс обвинения" выделиться из толпы? Ну, я упоминал, что SetWindowPos
не возвращается, пока WM_WindowPosChanged не завершит обработку. Так что, если бы мы, скажем, поспали 10 секунд во время обработки WM_WindowPosChanged, вызывающий процесс стал бы не отвечающим!
В этот момент мы можем EnumWindows
и проверить, являются ли они IsHungAppWindow
, и получить названия приложений, которым они принадлежат.
Ох ... и мы все равно будем собирать стек вызовов, если это на самом деле результат какого-то дикого побочного эффекта в нашем коде, а не "мошенническое приложение".
Ограничения
Очевидно, что если SetWindowPos
вызывается из потока без окон, эта техника не будет работать. Это может также иметь несколько ложных срабатываний.
Часть этого, скорее всего, работает "по реализации", а не "по замыслу".