Как сделать форму поверх всех окон c

Обновлено: 26.04.2024

Сообщество программистов
Общение, помощь, обмен опытом

Другие разделы портала

Переход к вопросу:

Статистика за сегодня:

Вопросы: 0
Ответы: 0
Мини-форумы: 0

Лучшие эксперты

Здравствуйте, IlluminatI!
Свойство формы FormStyle в fsStayOnTop

Ответ отправил: ANBsoft (статус: Студент)
Время отправки: 6 сентября 2008, 15:59

Мини-форум вопроса

возникает законный вопрос, а зачем? FormStyle в fsStayOnTop делает форму поверх остальных только для этого приложения.
А сделать форму поверх всех других - нельзя. Нельзя по одной простой и глупой причине. Приставьте себе, что появилось две такие формы (привильней всё таки говорить "окна приложения"). И обе хотят быть сверху, что же делать?
Но некоторые горе программисты решают эту задачу так. Они по таймеру проверяют, что их окно находиться под другим и с помощью BringWindowToFront подымают своё окно. Но где то в районе Win95-Win98 Майкрософт прикрыла эту возможность - теперь эта функция делает окно поверх других только в том случае, если приложение активно. А если оно свёрнуто/в фоне, то просто начинает мигать кнопктой на панели задач.
Это всё было сделано не случайно, а преднамерено - в то время практически каждая программа старалась вибросить своё окно на передний план. если было 3-4 таких программы, зрелище было незабываемое. Работать было нельзя.
Также не работают разные методики, которые вначале делают приложение активным, а потом выводят окно. Всё это присекается.
Но саму функцию, которая выводит окно на передний план, забывая о всех ограничениях, они сделали. Но эта функция не делает окно "всегда сверху".
По этому, учитывая всё вышесказанное, считаю, что окно, которое всегда стремиться вылезти на передний план - плохая затея, за исключением некоторых случаев, которые можно пересчитать по пальцам.

Я неслогласен. FormStyle в fsStayOnTop делает форму поверх остальных окон для всех приложений. Очень простой пример - "Диспечер задач", у которого стоит галочка Параметры - Поверх остальных окон.
Если интересно, что случится если таких форм будет несколько - запустить несколько Диспечеров задач непроблема.

Все окна распологаются в некоторой последовательности (Z-последовательнось), просто StayOnTop-окна имеют отдельную.

В Вин98 и раньше оно то может так и работало. Но в ХР - нет.
А диспетчер задач на то и диспетчер, что ему положенно так работать.

Если создать проект с формой FormStyle = fsStayOnTop и запустить несколько копий - результат будет тотже.
StayOnTop это не просто понятие делфи, например в функциях CreateWindow и SetWindowPos можно установить аттрибут окна (WS_EX_TOPMOST или HWND_TOPMOST) который и делает окно "поверх всех остальных". А Win98 здесь вообще непричом.

Цитата из хелпа к CreateWindow:
WS_EX_TOPMOST
Specifies that a window created with this style should be placed above all non-topmost windows and should stay above them, even when the window is deactivated. (Про Win98 Only ничего)

Цитата из хелпа к SetWindowPos:
HWND_TOPMOST
Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated. (Также про Win98 Only ни слова)

Я немного запутался сам и Вас запутал, и мы отошли от темы. Человек хотел "поверх всех окон". Вот это уже не реально.
Я понял почему я запутался. Я в свое время мучился с поднятием окна на передний план. А когда приложение свёрнуто, то это не всегда возмножно. А начальство требовало.

:)

(: В моём понимании "поверх всех окон" это абстрактное понятие. Конечно же не всегда оно будет поверх абсолютно всех окон, а только тогда когда оно активно, иначе "выше" него будет как минимум Меню Пуск
А поднятие окна на передний план я делал через SetForegroundWindow (по примеру из книги), нащёт свёрнутости непомню, но помоему не мешало

Добрый день, коллеги!
Столкнулся с таким нюансом (с некоторой спецификой) и стандартные способы, описанные в различных источниках, для такого моего "особого" случая не подошли. А примеры с похожей ситуацией мне найти не удалось.
Ситуация такова. Из начальной формы своего приложения, вызываем новую форму (назовём её "окно с анимацией", чтоб дальше меньше путаться), которая должна находиться поверх этой (начальной) формы, вызвавшей её. Что бы, во-первых, если щёлкнуть указателем мыши в окно уровнем ниже оно не переносилось на верх, во-вторых что бы, если в процессе работы с этим приложением, в этот момент, открыли какое-либо другое окно, другой программы (например Word во весь экран), после чего захотели вернуться обратно к нашему приложению, но не Alt+Tab'ом, а просто выбрав его иконку на панели задач, чтоб опять же "окно с анимацией" отображалось поверх главной формы, а не так, что главная форма активировалась "наверх", а вызванное ею "окно анимации" где-то затерялось за остальными окнами. Надеюсь не сильно запутал вступлением.
Так вот, всё бы ни чего, если бы не следующий нюанс. Вызываемая форма ("окно с анимацией") в моём случае не на прямую в главном потоке класса начальной формы вызывается. Т.е. не так:

ибо в таком случае, я бы передал в метод .Show(), вызываемой формы, this, и всё было бы как раз так, как мне надо. Т.е. оговорю сразу, что вариант с использованием TopMost формы WaitingRead мне не подходит, т.к. мне нужно, чтоб это окно не поверх всех окон рабочей среды в целом отображалось, а только по верх окон одного моего приложения.
Так вот, форма эта в моём обработчике вызывается в отдельном потоке, используя BackgroundWorker.
Приведу основную выжимку кода для наглядности:

Так вот, если я достаточно понятно изложил суть проблемы, подскажите, как вызывая окно в таком случае, заставив его корректно отображаться поверх главного, пока не выполнится bw.CancelAsync(); или выход по ESC, когда его нажатие отловится.

Мне нужно, чтобы форма появлялась поверх всех окон, при этом чтобы не перехватывала фокус (типа всплывашки). Но проблема в глючном шарпу в том, что если установить свойство формы TopMost в True, тогда форма перехватывает фокус, даже если переоверрайдить свойство ShowWithoutActivation в True. Приходится прибегать к API-шной функции SetWindowPos:

тогда форма будет поверх всех окон и фокус не будет перехватываться. Я добавил этот вызов в обработчик события FormLoad, но форма всеравно перехватывает фокус. Что я делаю не так?

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

Потом нагуглил, что эта штука не работает, если TopMost == True. Теперь вот с этой апишной функцией играюсь и ничего не получается.

Никогда не думал, что будет такой большой проблемой вывести форму поверх всех окон без активации.


Окно поверх всех без фокуса!
Задача такова, что нужно создать окно которое будет по верх всех окон(приложений) находящихся на.

Окно без фокуса, поверх других окон
Подскажите, как сделать что бы окно, будучи даже без фокуса, находилось поверх других окон.

Форма поверх всех окон (даже после потери фокуса).
К примеру есть две формы: form1 и form2. form2 запускается из form1, и должна всегда оставаться.


Две формы поверх всех окон. Вторая не хочет быть поверх
Ребят, поиск юзал, всё пробовал. Вторая форма не хочет быть наверху, первая нормально наверху.

при нажатии на текстбок - пишется true, при клике в ту же студию - форма остаётся на переднем плане, а текст - false

Добавлено через 1 минуту
никаких winAPI, просто topMost=true;

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

Вот я создал проект с формой с установленным TopMost=True и переписанным свойством ShowWithoutActivation

Компилируем и запускаем программу и быстро открываем блокнот и печатаем в нем текст. Когда через 3 секунды откроется форма, то она перехватит на себя фокус и текст станет печататься не в блокноте, а на форме! что жутко мне не нужно (я пытаюсь сделать всплывающее окно со своими кнопками)

Вот вторая форма для теста с WinAPI функцией:

Форма устанавливается поверх всех окон, но фокус также перехватывается. И я не могу понять почему! Наверное я не там, где надо вызываю эту функцию. Помогите разобраться! Я уже столько намучился с этим тошнотным перехватом фокуса.

Ниже этот проект с двумя формами. Попробуйте его у себя запустить.

обрати внимание что у тебя стоит
Form1 form2=new Form1();
что не есть хорошо

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

Добавлено через 2 минуты

Я проект создал просто для теста, чтобы сосредоточить внимание на безфокусной поверхоконности лишь только. Потому даный момент меня не волнует нисколько. Всплывашка, в которой я пытаюсь это проделать, будет располагаться вовсе в другом моем проекте, где такой проблемы нет.

Возникла вторая проблема. Форма не хочет быть поверх окон, если она создается в обработчике таймера System.Timers.Timer и я не знаю, чем это вызвано. Если вместо этого таймера использовать System.Windows.Forms.Timer, тогда форма ведет себя так, как от нее ожидается. Но в моей задаче нужно использовать первый таймер System.Timers.Timer. Почему в нем форма ведет себя непредсказуемо и не отображается поверх всех окон?

честно, не знаю почему вызывается настолько странная ошибка, но ты уверен что каждые 5 секунд хочешь создавать по новой форме?

Добавлено через 56 секунд
а хотя возможно из-за ShowDialog процесс не возвращается к таймерам и ждёт пока закроют приложения, да..

Это просто для тестов я задал такой интервал, чтобы хорошо было видно, что при каждом создании формы она почему-то не поверх всех окон.. В реальном приложении этот интервал будет произвольным в зависимости от предпочтений пользователя

в любом случае, попробуй:

Я забыл уточнить, что поместил на саму форму тоже один таймер, который автоматически закрывает форму через одну секунду, так что не в этом проблема.

Добавлено через 1 минуту

а где здесь в вашем коде вообще вызов формы? Тут не то что компилятор, здесь и невооруженным глазом видно, что теперь форма вообще не будет появляться.

В этом случае та же самая проблема - форма не поверх окон.

Добавлено через 7 минут
Я так полагаю, что проблема в том, что таймер System.Timers.Timer работает в другом потоке (в отличие от таймера System.Windows.Forms.Timer). Потому нужно как-то заставить создаться форме и показать ее не в потоке таймера, а в главном потоке. Может тогда проблема решится. Но как это сделать?

Еще, на msdn читал, что если этот таймер используется на UI-элементе, тогда его свойству SynchronizingObject нужно присвоить ссылку на сам UI-элемент, который содержит таймер. То есть, что-то типа:

Но в моем случае загвозда в том, что не таймер должен быть привязан к форме, а форма к таймеру, так как таймер генерирует события, создающие формы одну за другой. И я чисто физически не могу присвоить свойству SynchronizingObject ссылку на форму, так как тогда в тот отрезок времени форма еще не создана.

хм. ну, раз 1 таймер не работает как нужно а второй не подходит по каким-то причинам, предлагаю создать поток:

по идее тоже самое, только параметров меньше)

Добавлено через 1 минуту
а-а, опять забылся, в вечном цикле добавь сон:

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

Форма не хочет быть поверх окон, если она создается в обработчике таймера System.Timers.Timer и я не знаю, чем это вызвано. Если вместо этого таймера использовать System.Windows.Forms.Timer, тогда форма ведет себя так, как от нее ожидается. Но в моей задаче нужно использовать первый таймер System.Timers.Timer. Почему в нем форма ведет себя непредсказуемо и не отображается поверх всех окон?

Были у меня догадки по этому поводу, а вы их утвердили..) Получается, надо использовать Windows.Forms.Timer и от него никуда не убежишь.
Я вчера пробовал dotPeek-ом просмотреть реализацию этих двух таймеров, чтобы понять их различие в середине, но там оказалось не все так просто, как я думал. разбираться придется очень долго..))

А такой вопрос: как на счет производительности этих таймеров? Есть различия или нет? по этому вопросу что-то ничего не нагуглил, может плохо искал. Просто вот в чем суть, почему я сначала так упорно не хотел использовать Windows.Forms.Timer. Программа фоновая и в ней постоянно работает таймер, который генерирует через определенные промежутки некоторые действия(которые с UI вообще никак не связаны и пользователю вообще ничего не выводится). Но если пользователь поменяет в настройках одну вещь(это 1% из 100. ), тогда при каждой генерации события этого таймера должна выводиться всплывашка возле трея (типа напоминание - то есть эта неактивированная форма поверх всех окон). То есть, в большинстве случаев таймер вообще не имеет ничего общего с интерфейсом. А на мсдн говорится, что Windows.Forms.Timer должен использоваться на форме. А в моей программе это условие выполняется лишь может один раз из 100.

То ничего нет плохого в производительности, что я буду использовать таймер для форм в такой ситуации?

Я хочу, чтобы мое окно было поверх всех других окон в моем приложении только. Если я устанавливаю самое верхнее свойство окна, оно становится поверх всех окон всех приложений, и я этого не хочу.

необходимо задать свойство owner окна.

вы можете показать окно через showdialog, чтобы заблокировать главное окно, или вы можете показать его нормально и иметь его на вершине владельца без блокировки владельца.

вот пример codeexample части codebehind - я пропустил все очевидные вещи:

вместо этого вы можете использовать всплывающее окно, которое всегда будет самым верхним, украсить его подобно окну и прикрепить его полностью с помощью приложения обрабатывать событие LocationChanged вашего главного окна и установить свойство Isopen Popup в false.

Я надеюсь, что вы хотите, что-то вроде этого:

надеюсь, что это помогает.

используйте метод Activate (). Это попытка вывести окно на передний план и активировать его. например, окно wnd = new xyz(); wnd.Активировать ();

лучший способ-это установить эти два события для всех окон приложения:

  • и, конечно, все окна, которые вы хотели бы быть сверху, должны быть доступны из других окон вашего приложения. в моем случае у меня есть базовое окно и еще несколько окон, которые должны быть вверху моего базового окна, поэтому это было неплохо, чтобы мое базовое окно имело экземпляр каждого другого окна.

я столкнулся с очень похожей ситуацией, как и вы. Большая часть поиск я наткнулся на заявил, что все, что мне нужно сделать, это установить владельца окон, которые я хочу быть самым верхним к главному окну или любому окну, которое называется Шоу.

в любом случае, я пойду вперед и опубликую решение, которое хорошо сработало для меня.

Я создал обработчики событий для Window.Активировано и окно.Деактивирован в окне, которое должно было быть самым верхним по отношению к моему приложению.

Он отлично работает для меня. Надеюсь, это пригодится кому-то еще. : o)

во всплывающем окне перегружает метод Show () параметром:

затем в главном окне вызовите перегруженный метод Show ():

просто сделать это в XAML, и удивлен, что никто еще не опубликовал этот ответ. В следующем примере Window определена в ResourceLibrary (уведомление x:Key ), но вы также можете использовать эту привязку XAML для автономного Page -стиль ресурса WPF.

Я ОП. После некоторых исследований и тестирования ответ:

нет, нет никакого способа, чтобы сделать ровно что.

вы можете добавить это в свои теги windows

затем вы также можете отобразить его, если хотите, чтобы ваши пользователи признали его, чтобы продолжить

сначала попробуйте без верхних параметров и посмотрите результаты.

вот как это сделать: Сделайте ваше" верхнее " окно подписаться на другие события windows GotFocus и LostFocus и использовать следующие обработчики событий:

Как насчет htis:

Я тоже столкнулся с той же проблемой и последовал за Google на этот вопрос. Недавно я обнаружил, что для меня работает следующее.

Я только что столкнулся с этой же проблемой. У меня есть настольное приложение с несколькими окнами WPF, и мне нужно, чтобы мой пользовательский заставка была поверх других окон только в моем приложении. Никакие другие окна не открываются, когда появляется мой заставка, но я открываю главное окно из моего заставки после некоторой аутентификации. Поэтому я просто сделал что-то похожее на то, что сделал @GlenSlayden, но в коде позади, так как, как я сказал, MainWindow не для меня, чтобы привязаться к:

сейчас, пока мой программа загружает все остальные окна из главного окна, заставка находится сверху, но пока программа аутентифицирует пользователя, она не самая верхняя, поэтому вы можете щелкнуть по какой-то другой программе, и она спрячется за ней. Это самое близкое, что я мог найти для решения этой проблемы. Это не идеально, потому что он по-прежнему идет поверх всех других приложений, пока моя программа загружается после аутентификации, но это не очень долго в моем случае.

1) начать новый проект.

2) Перейдите в проект, затем в новую форму Windows, затем выберите Windows Form и Name Splash.

3) настроить размер, фон, текст и т. д. По желанию.

4) В разделе свойства всплеска.cs форма установить начальную позицию: Центральный экран и верхний: true

5) формы form1 добавить "с помощью системы.Нить;"

6) form1 в разделе класс добавить " Splash splashscreen = new Splash ();"

7) form1 добавить " splashscreen.Show (); "and" Application.DoEvents ();"

8) form1 в разделе События> > фокус> > активировано добавить " поток.Сон(4000); splashscreen.Close ();"

9) всплеск.cs добавить в разделе "Public Splash" добавить " это.Цвет Фона = Цвет.Aqua; " / может использовать любой цвет

10) это код для формы 1.cs

11) это код на Splash.cs

12) я обнаружил, что если вы не делаете что-то в заставке, то экран не будет оставаться на вершине в течение того времени, первая форма должна активировать. Количество потоков исчезнет всплеск через x секунд, так что ваша программа в норме.

Любой начинающий разработчик управляемого приложения 1С, который дошел до открытия управляемых форм заметил, что новая форма открывается всегда не поверх текущего окна, а в соседнем окне. Этот режим открытия называют Независимым. Но очень часто для удобства работы пользователей форму нужно открыть именно поверх всех имеющихся окон. Разберемся, как это работает.

Прежде чем изучать открытие формы программно, познакомимся с очень интересным свойством управляемой формы 1С, которое называется РежимОткрытияОкна. Именно это свойство отвечает, каким образом откроется новое окно. Это свойство принимает три значения: Независимый, Блокировать окно владельца и Блокировать весь интерфейс.

Свойство формы 1С режим открытия окна

Если у формы 1С установлен Независимый режим открытия окна, то форма откроется в отдельном окне, как на рисунке ниже.

Независимый режим открытия окна

Здесь и далее приведена конфигурация из книги «Основы разработки в 1С: Такси».

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

Форма 1С открыта по верх всех окон

Только в случае режима Блокировать окно владельца, будет заблокирована форма, в которой было инициализировано открытие новой формы. А в случае режима Блокировать весь интерфейс заблокируется весь интерфейс программы 1С. По сути, форма откроется в модальном режиме.

Со свойством формы разобрались, перейдем к открытию формы при помощи программного кода. Делать мы это будем при помощи уже знакомого нам метода ОткрытьФорму. Как работает этот метод, читайте в моей статье:

У этого метода есть последний седьмой параметр, который называется РежимОткрытияОкна, этот параметр имеет тип системное перечисление РежимОткрытияОкнаФормы, которое содержит в себе уже знакомые нам режимы: Независимый, Блокировать окно владельца и Блокировать весь интерфейс.

Если мы в методе ОткрытьФорму установим в седьмой параметр какое-либо значение, то форма откроется согласно этому значению.

Ниже приведены все три варианта открытия окна формы с использованием параметра РежимОткрытияОкна:

ОткрытьФорму ( «Документ.УстановкаЦен.Форма.ФормаДокумента» .
РежимОткрытияОкнаФормы . Независимый );

ОткрытьФорму ( «Документ.УстановкаЦен.Форма.ФормаДокумента» .
РежимОткрытияОкнаФормы . БлокироватьОкноВладельца );

ОткрытьФорму ( «Документ.УстановкаЦен.Форма.ФормаДокумента» .
РежимОткрытияОкнаФормы . БлокироватьВесьИнтерфейс );

Изучайте управляемые формы 1С с моими статьями:

Открытие управляемой формы существующего объекта

Открытие управляемой формы 1С на основании другого объекта

Открытие обычной формы в управляемом приложении 1С

Очень подробно вопросы по работе с управляемыми формами в частности и с управляемым приложением в целом рассмотрены в книге «Основы разработки в 1С: Такси. Разработка управляемого приложения за 12 шагов». Эта книга станет настоящим подспорьем для тех, кто только начал знакомится с разработкой управляемого приложения.


Книга «Основы разработки в 1С: Такси» отлично подойдёт тем, кто уже начал программировать и испытывает определенные сложности с этой темой и тем, кто уже давно программирует, но ни разу еще не работал с управляемыми формами 1С

  1. Без сложных технических терминов;
  2. Более 600 страниц практического материала;
  3. Каждый пример сопровождается рисунком (скриншот);
  4. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!

Промо-код на скидку в 15% — 48PVXHeYu

Многие начинающие думают, что изучить язык программирование в 1С сложно и трудно. В действительности программировать в 1С — легко. Помогут Вам легко и быстро освоить программирование в 1С мои книги: «Программировать в 1С за 9 шагов» и «Основы разработки в 1С: Такси»

Изучите программирование в 1С с помощью моей книги «Программировать в 1С за 9 шагов»

  1. Без сложных технических терминов.
  2. Более 500 страниц практического материала.
  3. Каждое задание сопровождается рисунком (скриншот).
  4. Сборник задач для домашней проработки.
  5. Книга написана понятным и простым языком — для новичка.
  6. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!

Промо-код на скидку в 16%: vCph8bW3rE


Если Вам помог этот урок решить какую-нибудь проблему, понравился или оказался полезен, то Вы можете поддержать мой проект, перечислив любую сумму:

Читайте также: