Я пытаюсь отладить странную проблему с пользователями, у которых установлен LogMeIn. Через несколько дней некоторые из моих диалоговых окон, которые открывает мое приложение, могут оказаться за кадром. Если бы я мог надежно обнаружить это, я мог бы программно переместить диалоги обратно туда, где они снова стали видны.
Примечание: это должно работать для нескольких мониторов и использовать Win32 API. Однако, если вы знаете, как это сделать из .NET, я, вероятно, смогу экстраполировать оттуда ...
Обновлять: Для любопытных, упомянутая выше ошибка связана с wxWidgets. Если вы запустите приложение wxWidgets, затем уйдете и отпустите экранную заставку, затем войдите в систему удаленно с помощью LogMeIn, затем попытаетесь открыть диалоговое окно из своего приложения, у вас возникнут проблемы, если вы используете wxDisplay :: GetFromPoint (pos) или wxWindowBase :: Center () для размещения диалогового окна.
Если вы думаете, что это ошибка в wxWidgets, сообщали ли вы об этом?





Хм. Это может не помочь, но когда я работал с VB, вы могли использовать screen.width и screen.height, а затем window.x и window.y ...
Конечно, я не знаю, как это работает с несколькими мониторами.
В .NET вы используете структуру Screen.PrimaryScreen.WorkingArea, чтобы получить границы основного экрана (Screen.Screens [x] .WorkingArea для других мониторов, я думаю), а затем используйте свойства Left и Top окна для узнать, где находится окно (если оно находится за пределами экрана, значения Top и Left будут больше, чем [Screen] .Width и .Height.
В .NET я бы перебирал каждый экран в Screen.AllScreen, а затем либо вызывал screen.Bounds.Contains (), передавая прямоугольник вашей формы, если вы хотите убедиться, что все ваше окно находится в пределах границ (*), либо вызовите экран. Bounds.IntersectsWith (), если вы хотите убедиться, что хотя бы часть вашей формы видна.
(*) Неполное нахождение в пределах одного экрана не означает, что оно не находится в пределах общего числа экранов. Вы также можете вызвать Rectangle.Union для каждой границы экрана, чтобы создать один прямоугольник для проверки прямоугольника вашей формы, но тогда вы должны следить за тем, имеют ли границы экрана разные размеры, поскольку охватывающий прямоугольник также не полностью виден.
Это был более длинный ответ. Более короткий: я не знаю простого пути.
Похоже, что GetMonitorInfo () - это Win32-эквивалент предложения Дэнни. Я не уверен, как вы собираетесь получить HMONITOR для всех мониторов в системе, но похоже, что в примере, приведенном в документации, есть несколько способов сделать это.
Все основы поддержки нескольких мониторов из журнала Microsoft Systems Journal за июнь 1997 г .:
Размещение объектов на множестве дисплеев.
Просто используйте MonitorFromWindow с флагом MONITOR_DEFAULTTONULL. Если возвращаемое значение равно нулю, ваше окно не отображается. Впоследствии вы можете передать MONITOR_DEFAULTTONEAREST, чтобы иметь возможность изменить положение окна на ближайшем мониторе.
В итоге я использовал MonitorFromPoint, который работает аналогично MonitorFromWindow.
Что бы вы ни делали, учитывайте наличие нескольких мониторов, координаты которых могут находиться в тысячах пикселей от точки (0,0) в любом направлении. Я ненавижу, когда приложение заставляет себя вернуться на другой экран, часто портя любые полноэкранные игры, в которых я мог бы быть в то время.
См. Также Как я могу получить активные размеры экрана?
Это код, который я использовал в конструкторе формы, это быстрый способ переместить форму на видимый экран после того, как вы отстыкуете свой ноутбук или что-то еще, что вы сделали, чтобы избавиться от некоторой площади экрана. Уточните для собственного потребления.
if (!Screen.FromControl(this).Bounds.Contains(this.Location))
{
this.DesktopLocation = new Point(100,100);
}
Это было давно, но ответ Марина Планте дал мне то, что мне было нужно, поэтому я написал простой метод расширения:
public static class WindowLocation
{
public static Boolean VisibleOnScreen(this Form form)
{
foreach (Screen screen in Screen.AllScreens)
{
if (screen.Bounds.Contains(form.Bounds)) return true;
}
return false;
}
}
Может помочь кому-то другому!
К вашему сведению: щелкните правой кнопкой мыши внеэкранное окно на панели задач, выберите «Переместить» и нажмите клавишу со стрелкой (она должна перейти к мыши). Затем используйте мышь или клавиши, чтобы завершить ход.