缩放 non-client 区域 per-monitor high-DPI 支持应用程序支持 Windows 8.1
Scaling non-client area for per-monitor high-DPI support on application supporting Windows 8.1
我正在开发 运行 在 Windows 10 和 8.1 上运行的应用程序,运行 解决 non-client 区域(菜单栏,标题栏)在具有不同 DPI 的显示器之间移动时。客户区已处理,但 non-client 区域不成比例。 DPI 感知设置为 PerMonitorAware(v1,因为 v2 在 Windows 8.1 上不可用)。
EnableNonClientDpiScaling 函数完全满足我的需要(这是对所有类似问题的公认答案)- 唉,它只是 API 从 Windows 10 开始的一部分。
有没有办法在没有前面提到的功能的情况下手动处理此问题 - 以保持对 Windows 8.1 的支持?或者支持 Windows 8.1 是否意味着在具有不同 DPI 的屏幕之间移动时无法调整 non-client 区域的大小?
DPI 支持是一个不断变化的目标,您只需确定支持的最低平台是什么,并接受多显示器缩放在这些旧平台上并不完美。
在可用的版本上调用 EnableNonClientDpiScaling
(GetProcAddress
或您使用的任何语言的等效版本)。
新意识清单元素在 Windows10 中的工作方式意味着您可以在支持它的地方使用 Per-Monitor v2(1703 及更高版本),在旧版本中可以使用 PMv1、系统或 Unaware。 PMv2 使您可以自动缩放基于 DialogBox
的对话框。
多亏了安德斯,GetProcAddress
正是我要找的东西。虽然没有解决Win 8.1非客户区变大的问题(看来真的没办法,只能自己画了),但可以在Win 10上设置最新的DPI_AWARENESS_CONTEXT
:
// the following sets PROCESS_PER_MONITOR_AWARE_V2 on Win10 and
// reverts to PROCESS_PER_MONITOR_AWARE on Win 8.1
typedef BOOL(__stdcall *SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
SetProcessDpiAwarenessContext dpi_call = nullptr;
dpi_call = reinterpret_cast<SetProcessDpiAwarenessContext>(GetProcAddress(
GetModuleHandle(TEXT("User32.dll")),
"SetProcessDpiAwarenessContext"));
if (dpi_call != nullptr) {
if (!(*dpi_call)((DPI_AWARENESS_CONTEXT) - 4))
throw std::runtime_error("Unable to set DPI aware app.");
} else {
if (SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE) != S_OK)
throw std::runtime_error("Unable to set DPI aware app.");
}
我正在开发 运行 在 Windows 10 和 8.1 上运行的应用程序,运行 解决 non-client 区域(菜单栏,标题栏)在具有不同 DPI 的显示器之间移动时。客户区已处理,但 non-client 区域不成比例。 DPI 感知设置为 PerMonitorAware(v1,因为 v2 在 Windows 8.1 上不可用)。
EnableNonClientDpiScaling 函数完全满足我的需要(这是对所有类似问题的公认答案)- 唉,它只是 API 从 Windows 10 开始的一部分。
有没有办法在没有前面提到的功能的情况下手动处理此问题 - 以保持对 Windows 8.1 的支持?或者支持 Windows 8.1 是否意味着在具有不同 DPI 的屏幕之间移动时无法调整 non-client 区域的大小?
DPI 支持是一个不断变化的目标,您只需确定支持的最低平台是什么,并接受多显示器缩放在这些旧平台上并不完美。
在可用的版本上调用 EnableNonClientDpiScaling
(GetProcAddress
或您使用的任何语言的等效版本)。
新意识清单元素在 Windows10 中的工作方式意味着您可以在支持它的地方使用 Per-Monitor v2(1703 及更高版本),在旧版本中可以使用 PMv1、系统或 Unaware。 PMv2 使您可以自动缩放基于 DialogBox
的对话框。
多亏了安德斯,GetProcAddress
正是我要找的东西。虽然没有解决Win 8.1非客户区变大的问题(看来真的没办法,只能自己画了),但可以在Win 10上设置最新的DPI_AWARENESS_CONTEXT
:
// the following sets PROCESS_PER_MONITOR_AWARE_V2 on Win10 and
// reverts to PROCESS_PER_MONITOR_AWARE on Win 8.1
typedef BOOL(__stdcall *SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
SetProcessDpiAwarenessContext dpi_call = nullptr;
dpi_call = reinterpret_cast<SetProcessDpiAwarenessContext>(GetProcAddress(
GetModuleHandle(TEXT("User32.dll")),
"SetProcessDpiAwarenessContext"));
if (dpi_call != nullptr) {
if (!(*dpi_call)((DPI_AWARENESS_CONTEXT) - 4))
throw std::runtime_error("Unable to set DPI aware app.");
} else {
if (SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE) != S_OK)
throw std::runtime_error("Unable to set DPI aware app.");
}