Действительно раздражающая ошибка со свойством TopMost в Windows Forms - PullRequest
5 голосов
/ 06 мая 2010

У меня есть это приложение Windows Forms, где оно находится в области уведомлений. Щелчок по значку выводит его вперед, повторное нажатие (или нажатие на значок приложения X) возвращает его обратно. Это тип приложения, для которого важно, чтобы окно всегда было сверху, когда оно отображается при нажатии на значок (хотя это необязательно).

Если щелкнуть правой кнопкой мыши значок, откроется контекстное меню, в котором можно включить или отключить параметр «всегда сверху». Когда приложение запускается впервые, настройки приложения считываются из файла XML, и я на 99% уверен, что все работает как надо, свойство TopMost правильно прочитано (и записано).

Через некоторое время (минуты, часы, дни и т. Д .; я обычно сплю и редко выключаюсь) TopMost перестает работать . Я не изменяю параметр, я не думаю, что что-то меняет значение параметра, но я щелкаю значок области уведомлений, и приложение не отображается. Он отображается, но он на заднем плане (он отображается на Alt + Tab), он не «всегда сверху», как должен. Я поднимаю контекстное меню, отключаю опцию (потому что она включена) и снова включаю ее, и после этого она начинает работать. Приложение теперь «всегда на высоте». Однако через некоторое время он может потерять эту способность.

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

EDIT:
Я добавил фрагмент кода, чтобы показать MessageBox, когда свойство TopMost было изменено, чтобы увидеть, могу ли я заметить какое-либо странное поведение, но это было бесполезно. Это не помогло, потому что форма была с TopMost = true, но она все еще была на заднем плане ...

Ответы [ 2 ]

5 голосов
/ 11 мая 2010

Существует более одного "самого верхнего" окна. Topmost просто говорит «Перед всеми не верхними окнами».

Я почти уверен, что для повторной инициализации рабочего стола (например, в режиме гибернации) требуется еще один SetWindowPos(hwnd, HWND_TOPMOST, ...) (который является базовым вызовом Win32 API).

В качестве обходного пути вы можете сбросить и снова установить свойство при отображении окна.

Другая возможность состоит в том, что скрытие окна также изменяет порядок Z - либо косвенно, как это реализует Win32, либо явно в том, как WinForms вызывает окно скрытия / показа.

1 голос
/ 12 мая 2010

Как и Петерчен, я также не знаю, как выяснить причину. Но почему бы не сделать это немного проще?

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

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

...