Как держать дочернюю форму поверх всего, но не родительскую?

Я видел несколько сообщений, похожих на этот вопрос, но здесь есть небольшая разница. У меня есть программа, пользовательский интерфейс которой может находиться за другими программами, но у нее есть дочерняя форма, которая отображается в верхнем левом углу и отображает результаты, эта часть монитора дублируется и отображается для публики, это «табло». Я хочу, чтобы эта форма «результатов» располагалась поверх всего (Taskmanager в порядке, я могу с этим жить). Любые другие запущенные приложения не будут пытаться подняться наверх, например «Word», «IE», «Excel» и т. Д.

Если я установлю для родительского «SetWindowPos» значение «TopMost», а для дочернего элемента также значение «TopMost», оба моих окна будут наверху, однако форма пользовательского интерфейса также будет располагаться поверх всего. Если пользователю необходимо запустить другое приложение, наша форма будет располагаться над ним, делая другое приложение непригодным для использования, однако оно будет находиться под нашей формой результатов. Мы не можем использовать таймер, чтобы переместить его наверх, так как он будет закрыт, пока не сработает таймер, этого не должно происходить.

Если я установлю только форму результатов на самый верх, она не останется наверху всего. Получается, что родитель тоже должен быть наверху? Есть ли способ обойти это и сделать ребенка сверху, а его родитель может сидеть внизу? Или родитель должен быть наверху, чтобы потомки тоже были наверху? Родитель не может сидеть над ребенком, поскольку я захватываю событие перемещения и предотвращаю его перемещение над ребенком.

Я программирую в Delphi, поэтому любые ответы будут лучше всего в Delphi, но все более общее вполне нормально, я ожидаю, что в любом случае это будет вызов Windows.

Спасибо


person TrevorH    schedule 09.11.2015    source источник
comment
Любые другие запущенные приложения не будут пытаться подняться наверх - вы не можете надежно обеспечить это из-за Что, если бы это сделали две программы - правило   -  person Lieven Keersmaekers    schedule 09.11.2015
comment
Спасибо за вашу мысль, как я указал в сообщении Тома, это действительно так после некоторой проверки его предложения. Несмотря на то, что эти две программы на самом деле наши, координация их статуса потребует дополнительных размышлений.   -  person TrevorH    schedule 12.11.2015


Ответы (1)


Если я правильно вас понял, ваша программа имеет основную форму (MainForm) и форму результатов (ResultsForm) и, возможно, некоторые другие, но они должны «вести себя» нормально.

MainForm также должна вести себя нормально, то есть переходить в фоновый режим, если другие приложения активированы, но ResultsForm всегда должна оставаться поверх всех других форм, а также форм других приложений.

Следующее проверено только в Windows 7, поэтому может работать или не работать с другими ОС. Позже сегодня я протестирую Windows 10.

Сначала удалите комментарии из любых предыдущих попыток, которые могут помешать. Оставьте MainForm.FormStyle по умолчанию fsNormal. Установите ResultsForm.FormStyle на fsStayOnTop.

Затем добавьте TApplicationEvents в ResultsForm и добавьте обработчик событий для OnDeactivate:

procedure TResultsForm.ApplicationEvents1Deactivate(Sender: TObject);
begin
  SetForegroundWindow(Handle);
end;

ResultsForm теперь будет оставаться поверх других окон, а также других приложений.

Предостережение: если вы запустите второй экземпляр (или если какое-то другое приложение проделывает тот же трюк), вы попадете в цикл, в котором приложения будут бороться за свое лидерство.

person Tom Brunberg    schedule 09.11.2015
comment
Да, ваше понимание верное! Я попробовал это сегодня утром, но понял проблему, которую не осознавал, как в вашей оговорке. У нас ДЕЙСТВИТЕЛЬНО есть другие приложения, с которыми могут возникнуть проблемы. Когда выставлен счет, например. крикет 6 набран, мы показываем видео поверх формы результатов. Так что я бы позволил этой форме выйти на передний план! Но все же оставьте результаты поверх всего остального. Когда видео закончится, его форма закроется, и результаты должны будут снова быть наверху. Таким образом, управление сверху уже выглядит сложнее, чем я думал. - person TrevorH; 12.11.2015
comment
@Trevor Хех, я не удивлен;) Но хорошо то, что только ваши приложения могут бороться за экран, поэтому вы можете создать экранную полицию, которая отключает один 'onTop' и разрешает другой. Чтобы временно отключить, просто обнулите событие OnDeactivate и сбросьте его позже. - person Tom Brunberg; 12.11.2015