Страницы

Поиск по вопросам

понедельник, 16 декабря 2019 г.

Как держать окно всегда поверх других окон? (WinAPI, C++)

#cpp #winapi


Приложение выводит видеоролик на весь экран, который должен быть всегда поверх всех
окон, чтобы его нельзя было свернуть или закрыть другими окнами, пока не выполнятся
определённые условия. Для этого каждая итерация в цикле вывода кадров начинается с
SetWindowPos(VideoWindow, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);,
но, к сожалению это не спасает - по alt+tab видео можно проигнорировать. Есть такие
окна, с которых невозможно перевести фокус на другие приложения - как это сделать с
окном данного видеоролика?

(ОБНОВЛЕНИЕ ВОПРОСА)

Ответ, который я дал сам, работает через раз...
В связи с комментариями по поводу двух TOPMOST окон добавляю следующий скриншот:

Два TOPMOST окна, предположительно со стилями WS_EX_TOPMOST, будут перекрывать друг
друга тем, которое из них активно. Такое поведение допустимо.

Вопрос открыт!

КАК сделать всегда в топе Z-порядка видеоролик в cvNamedWindow, так же, как это делает
портативный AIMP (который не имеет админских привелегий и не является частью ОС, как
тот же диспетчер задач? 
    


Ответы

Ответ 1



Как оказалось, это возможно! ActiveWindow = GetForegroundWindow(); if (ActiveWindow != VideoWindow){ SetWindowPos(ActiveWindow, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); SetForegroundWindow(VideoWindow); SetActiveWindow(VideoWindow); } Данный вариант работает, но через раз. Было найдено следующее решение: Заменить родителя для cvNamedWindow, в котором выводится видео, на главное окно программы, которое изначально скрыто (SW_HIDE), а при воспроизведении выводится. Главное окно создаётся с WS_EX_TOPMOST и WS_POPUPWINDOW. В результате поведение окна получается таким же как у диспетчера задач - окно по alt+tab появится сверху, но выбранное в нём приложение будет всегда под видео, если это приложение не имеет стиля WS_EX_TOPMOST. Если очень нужно прибивать другие окна с WS_EX_TOPMOST, можно в параллельном потоке их отлавливать и сравнивать с целевым окном - если не равны по каким-то критериям, то деактивировать или скрывать. Почему-то применение атрибута HWND_TOPMOST не отрабатывало на уже созданном cvNamedWindow.

Ответ 2



Это невозможно. Допустим, это было бы возможно — что если два приложения захотели бы одновременно так сделать? Юмористическое чтение по теме: How do I create a topmost window that is never covered by other topmost windows? @ The Old New thing (обязательно прочитайте комментарии).

Комментариев нет:

Отправить комментарий