Спрашивающий
Как получить разрешение экрана в WPF?

Общие обсуждения
-
Казалось бы все просто:
double h = SystemParameters.PrimaryScreenHeight;
double w = SystemParameters.PrimaryScreenWidth;
У меня ноубук (Windows 8). При установленном в настройках разрешении экрана монитора 1920 на 1080 получаем h = 864.0, а w = 1536.0. То есть, в 1.25 раза меньше, чем ожидалось. Настольный ПК (WindowsXP) показывает h и w как в установленном разрешении. Возникает вопрос, как определить это отношение:
SystemParameters.PrimaryScreenHeight, SystemParameters.PrimaryScreenWidth и установленное в настройках разрешение экрана. Как точно узнать этот коэффициент (1.0 или 1.25).
- Изменен тип Maksim MarinovMicrosoft contingent staff, Moderator 26 сентября 2013 г. 6:40
28 августа 2013 г. 13:54
Все ответы
-
Вопрос снимаю. Ответ, кажется, найден. Это - SystemParameters.CaretWidth (ширина в точках курсора в элементах управления – так написано в справке ).
Установленное в настройках разрешение экрана равно
SystemParameters.PrimaryScreenWidth/SystemParameters.CaretWidth по ширине и SystemParameters.PrimaryScreenHeight/SystemParameters.CaretWidth по высоте.
У меня, по крайней мере, работает…
29 августа 2013 г. 9:57 -
Все-таки мне нужен ответ. Может быть, ширина каретки в некоторых случаях подойдет, но все же, как программно определить установленное пользователем разрешение экрана?
SystemParameters.PrimaryScreenWidth и SystemParameters.PrimaryScreenHeight показывают действительное (реальное) разрешение экрана. Например, пользователь на своем устройстве установил разрешение 1920 на 1080, а действительное разрешение устройства при этом будет 1536 на 864 (PrimaryScreenWidth и PrimaryScreenHeight). То есть, такое случается, если CaretWidth=0.8 на этом устройстве (экране). И 1920 * 0.8 = 1536, 1080 * 0.8 = 864. Все бы хорошо, но я не уверен, что ширина каретки (CaretWidth) всегда корректно покажет это соотношение. В приложении необходимо иногда перемещать один объект относительно другого, определяя координаты последнего с помощью метода Point PointToScreen(Point point) класса Visual. И не зная этой величины (0.8) на разных устройствах (настольный ПК, ноутбук, планшет) под Windows 8 не возможно корректно перемещать объекты по экрану. Прошу помочь мне решить эту проблему.
11 сентября 2013 г. 7:43 -
Добрый день.
Вот так:
SystemParameters.WorkArea.Width SystemParameters.WorkArea.Height
11 сентября 2013 г. 7:59Отвечающий -
Хотя, может быть и:
SystemParameters.VirtualScreenHeight
Предыдущее вроде выкидывает таскбар...11 сентября 2013 г. 8:01Отвечающий -
WorkArea... явно не разрешение экрана, которое установил пользователь на своем устройстве. А вот второй вариант (с VirtualScreenHeight) - похоже. Сейчас нет под рукой ноутбука, где ширина каретки 0.8. Через час смогу практически проверить.
11 сентября 2013 г. 13:50 -
Нет, не правильно. SystemParameters.VirtualScreenHeight и SystemParameters.VirtualScreenWidth показывают тоже самое, что и SystemParameters.PrimaryScreenHeight и SystemParameters.PrimaryScreenWidth. Может ли быть так, что ширина каретки всегда равна ширине точки экрана (например, у меня в ноутбуке 0.8 пикселя)? Уверенности нет. В MSDN ничего не нашел.
- Изменено yura_ 11 сентября 2013 г. 15:34
11 сентября 2013 г. 15:17 -
Решил все-таки продолжить тему. Так как не совсем уверен в найденном мной решении.
У меня в приложении WPF имеется проблема при работе на устройствах, где физическое разрешение экрана в пикселях не соответствует установленному пользователем разрешению. Например, на новых ноутбуках Asys N550J рекомендованное производителем разрешение экрана 1920 на 1080 (FulHD) на самом деле (физически) означает разрешение 1536 на 864. Соответственно и все остальные допустимые в настройках разрешения экрана физически в 0,8 раза меньше, чем указано в настройках. То есть точка разрешения экрана равна 0,8 пикселя?
В приложении WPF можно определить только разрешение экрана действительное, в пикселях. То есть, в моем случае, при установленном разрешении экрана 1920 на 1080:
SystemParameters.PrimaryScreenWidth = 1536
SystemParameters.PrimaryScreenHeight = 864;
Была большая надежда на VirtualScreenWidth и VirtualScreenHeight, но и эти свойства класса SystemParameters показывают то же самое.
Иногда в приложении WPF приходиться устанавливать размер картинки. Например, если предполагается, что пользователь использует для работы с приложением разрешение экрана 1024 на 768 и установить размер картинки в XAML Width="1024" или в коде C# Myimage.Width = 1024, то картинка не поместится на экране, так как этот размер устанавливается в пикселях. А приложение будет выведено в окне размером 819 пикселей на 614,4. Такие же проблемы появляются, если надо разместить в приложении одну картинку (или control) относительно другой в определенном месте. Положение на экране первой картинки (или контрола) myImage, размещенного в контейнере (например, Grid) определяю так:
Point p = MyWindow.myImage.PointToScreen(pt).
Точка p показывает смещение верхнего левого угла myimage в точках разрешения (на моем устройстве одна точка 0.8 пикселя). А когда вы хотите сместить в вычисленное положение другую картинку, myImage2.Left = p.X, то Left считается уже в пикселях. И на моем ноутбуке это выглядит совсем не так, как нужно.
Может следует делать так:
Сначала определить смещение картинки в текущих координатах (в точках разрешение экрана)
Point pt = new Point();
Point p = MyWindow.myimage.PointToScreen(pt);
А затем определить это смещение относительно окна (экрана) в пикселях
Point pf = app.acyWindow.PointFromScreen(p);
myImage2.Left = pf.X;
Не знаю. Но случайно я заметил, что свойство CaretWidth (ширина каретки) класса SystemParameters как раз равна размеру точки разрешения экрана в пикселях. В моем случает эта величина составляет 0,8. Это действительно «случайно» или и на других устройствах будет точно так же (и всегда в дальнейшем), мне не известно.
Но, в связи с этим случаем, можно смещать картинку 2 так:
Point p = MyWindow.myimage.PointToScreen(pt);
myImage2.Left = p.X * SystemParameters.CaretWidth;
Эти два способа не равнозначны и дают незначительную разницу в несколько пикселей. О причинах могу только догадываться…
В то же время, приложения, написанные 5-10 лет назад в Visual C++ 6.0 на Win32 работают отлично при любом разрешении экрана. Все масштабируется достаточно корректно и таких проблем не возникает.
Может нужно тогда воспользоваться функциями win32?
[DllImport("User32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern Boolean EnumDisplaySettings([param: MarshalAs(UnmanagedType.LPTStr)] string lpszDeviceName, [param: MarshalAs(UnmanagedType.U4)]int iModeNum,
[In, Out]ref DEVMODE lpDevMode);
DEVMODE mode = new DEVMODE();
mode.dmSize = (ushort)Marshal.SizeOf(mode);
EnumDisplaySettings(null, ENUM_CURRENT_SETTINGS, ref mode);
И тогда уже размеры точки разрешения экрана:
double widthPoint = SystemParameters.PrimaryScreenWidth / (double)mode.dmPelsWidth
double heighthPoint = SystemParameters.PrimaryScreenHeight/ (double)mode.dmPelsHeight;
Не считаю себя достаточно компетентным, поэтому прошу совета. Неужели без старого доброго Win32 не обойтись?
28 сентября 2013 г. 11:53 -
Я думаю Вы мудрите.
В том смысле, что Microsoft разработчики с этой проблемой должны были быть знакомы и я почти уверен они уже написали код под капотом для коррекции всего этого.
Только что проверил изменив разрешение.
SystemParameters.PrimaryScreenWidth и SystemParameters.PrimaryScreenHeight выдают правильные значения.
Несоответствия в вашем приложении могут быть связаны с понятиями ActualWidth & ActualHeight, которые дают реальные цифры в то время, как обычные Width & Height желаемые(установленные на этапе разработки) в которых сидят ещё значения заголовка окна и границ(Borders).
Надеюсь помог. Удачи!
16 июля 2018 г. 9:28