Недавно я играл с WINAPI для получения настроек масштабирования и разрешения экрана, и я столкнулся с этим странным поведением.
У меня есть небольшая программа на C ++ (список доступен ниже), которая извлекает значения VERTRES, HORZRES, DESKTOPVERTRES и DESKTOPHORZRES. Моя программа также устанавливает режим осведомленности о DPI равным 1 (осведомленность на системном уровне). Я заметил, что значения, сообщаемые VERTRES, HORZRES, зависят от коэффициента масштабирования системы, используемого при запуске системы.
Итак, на моем ноутбуке я настроил коэффициент масштабирования системы на 150% и разрешение 1920x1080. Это конфигурация при запуске. Когда я извлекаю HORZRES и DESKTOPHORZRES, оба значения сообщаются как 1920.
Если я изменю настройку масштабирования на 100% и не перезагружу компьютер, в следующий раз, когда я получу эти значения, они будут представлены как 2880 (для HORZRES) и 1920 (для DESKTOPHORZRES).
После перезагрузки компьютера с настройками масштабирования, установленными на 100%, оба значения снова будут иметь значение 1920.
Если я снова изменю масштабирование на 150%, значения будут отображаться как 1280 (HORZRES) и 1920 (DESKTOPHORZRES).
Описанное поведение наблюдается только тогда, когда я устанавливаю осведомленность о точном разрешении на 1, если для него установлено значение 0 («не известно») или 2 («осведомленность о каждом экране»), значения всегда сообщаются как 1280 (HORZRES) и 1920 (DESKTOPHORZRES). независимо от того, как было настроено масштабирование при запуске.
Мне было интересно, почему значение, сообщаемое HORZRES (или VERTRES), зависит от коэффициента масштабирования, используемого при запуске системы? Это ожидаемое поведение?
Если выше уже было где-то описано, буду признателен за любые ссылки.
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <cerrno>
#include <string>
#include <sstream>
#include <math.h>
#include <Windows.h>
#include <shellscalingapi.h>
#include <winuser.h>
class Rectangular
{
public:
Rectangular(int height, int width) : height(height), width(width) {};
const int height;
const int width;
};
class MonitorInfo
{
public:
MonitorInfo(std::string device_name, Rectangular logical_resolution, Rectangular physical_resolution, Rectangular physical_size_mm) :
device_name(device_name), logical_resolution(logical_resolution), physical_resolution(physical_resolution),
physical_size_mm(physical_size_mm), scaling(static_cast<int>(std::round(100.0*(float)physical_resolution.height / (float)logical_resolution.height))) {};
void print_to_stdout() const;
const std::string device_name;
const Rectangular logical_resolution;
const Rectangular physical_resolution;
const Rectangular physical_size_mm;
const int scaling;
};
class MonitorsInformation
{
public:
MonitorsInformation();
const std::vector<MonitorInfo>& get_monitors_info() const { return monitors; }
std::string get_last_error_string() const { return last_error; }
Rectangular get_monitors_rectangular() const;
private:
RECT rectangular_combined;
std::vector<MonitorInfo> monitors;
std::string last_error;
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData);
};
void MonitorInfo::print_to_stdout() const
{
std::cout << "\nDevice: " << device_name << "\nLogical Screen resolution: " << logical_resolution.width << "x" << logical_resolution.height;
std::cout << "\nPhysical Screen resolution: " << physical_resolution.width << "x" << physical_resolution.height;
std::cout << "\nDPI ratio: " << scaling;
std::cout << "\nPhysical Size(mm): " << physical_size_mm.width << "x" << physical_size_mm.height << "\n";
}
MonitorsInformation::MonitorsInformation() : rectangular_combined(RECT()), last_error(std::string()), monitors(std::vector<MonitorInfo>())
{
EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this);
}
BOOL CALLBACK MonitorsInformation::MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
{
MonitorsInformation* pThis = reinterpret_cast<MonitorsInformation*>(pData);
MONITORINFOEXA monitor_info;
monitor_info.cbSize = sizeof(MONITORINFOEXA);
if (!GetMonitorInfoA(hMon, &monitor_info))
{
pThis->last_error = "GetMonitorInfoA failed with error: " + errno;
return FALSE;
}
UnionRect(&pThis->rectangular_combined, &pThis->rectangular_combined, lprcMonitor);
HDC device_context = CreateDCA(NULL, monitor_info.szDevice, NULL, NULL);
int LogicalScreenHeight = GetDeviceCaps(device_context, VERTRES);
int LogicalScreenWidth = GetDeviceCaps(device_context, HORZRES);
int PhysicalScreenHeight = GetDeviceCaps(device_context, DESKTOPVERTRES);
int PhysicalScreenWidth = GetDeviceCaps(device_context, DESKTOPHORZRES);
pThis->monitors.push_back(
MonitorInfo(
std::string(monitor_info.szDevice),
Rectangular(
LogicalScreenHeight,
LogicalScreenWidth),
Rectangular(
PhysicalScreenHeight,
PhysicalScreenWidth),
Rectangular(
GetDeviceCaps(device_context, VERTSIZE),
GetDeviceCaps(device_context, HORZSIZE))));
return TRUE;
}
Rectangular MonitorsInformation::get_monitors_rectangular() const
{
return Rectangular(
std::abs(rectangular_combined.top) + std::abs(rectangular_combined.bottom),
std::abs(rectangular_combined.left) + std::abs(rectangular_combined.right));
}
int main()
{
SetProcessDPIAware();
for (;;)
{
MonitorsInformation MonitorsInfo;
char exit_char = 'N';
std::cout << "You have " << MonitorsInfo.get_monitors_info().size() << " monitors connected.\n";
printf("Screen rectangular. %d x %d\n",
MonitorsInfo.get_monitors_rectangular().width, MonitorsInfo.get_monitors_rectangular().height);
for (auto &monitor : MonitorsInfo.get_monitors_info())
{
monitor.print_to_stdout();
}
std::cout << "Would you like to repeat? [Y]/[N]\n";
std::cin >> exit_char;
if (exit_char == 'N' || exit_char == 'n')
{
break;
}
}
return 0;
}
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
иSetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
, оба не могут воспроизвести ваши проблемы. Значение HORZRES всегда уменьшается при увеличении масштабного коэффициента. (100% -1920; 125% -1536; 150% -1280; 175% -1097) Я не перезагружаюсь. - person Rita Han   schedule 23.01.2019