gpt4 book ai didi

c++ - SetWindowPos() 跨进程处理多个监视器和不同的显示比例

转载 作者:可可西里 更新时间:2023-11-01 09:39:06 26 4
gpt4 key购买 nike

我已经问过类似的问题here , 但现在问题似乎有点不同,所以我想我会为它创建一个新问题。

我正在使用 SetWindowPos() 从另一个进程移动/调整窗口大小。只要所有屏幕都使用相同的显示比例,这就可以正常工作,但在以下情况下它不会按预期工作:

  • 主屏幕位于 (0,0),分辨率为 3440x1440,缩放比例为 150%。
  • 辅助屏幕位于 (3440, 0),分辨率为 900x1440,缩放比例为 100%。
  • 我的应用程序是 PROCESS_PER_MONITOR_DPI_AWARE_V2,目标应用程序是 PROCESS_DPI_UNAWARE(由 Windows 缩放)。

现在,如果我移动一个窗口,使左上角在主屏幕上,而中心仍在副屏幕上,例如移动到 (3400, 0)。

  SetWindowPos(hwnd, HWND_BOTTOM, 3300, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);

然后是这样的:

  • 窗口根据第二个屏幕的 100% 显示缩放比例进行缩放。
  • 窗口没有移动到 (3300, 0)。相反,它在 WM_WINDOWPOSCHANGING 消息中接收到的坐标是 (2200, 0)。坐标似乎按比例缩小到逻辑坐标。

因此我无法将窗口移动到该位置。我尝试在传递给 SetWindowPos() 的坐标上使用 PhysicalToLogicalPointForPerMonitorDPI(),但没有成功(它甚至没有更改坐标)。

现在似乎我无法将窗口移动到左上角在主屏幕上的任何位置,但窗口的中心仍在辅助屏幕上,因为 Windows 会缩小坐标,如果我手动放大它们,然后我已经将窗口定位在第二个屏幕上并且 Windows 不再应用缩放。即使我能够解决这个问题,也可以通过双屏幕设置手动计算缩放比例,但随着屏幕的增加,它很快就会变得过于复杂。那么,我该如何让它发挥作用呢?

EDIT1:我尝试按照建议使用 SetThreadDpiAwarenessContext(),但它仍然不起作用。现在,当我将窗口移动到 (3000,0) 时,它会移动到 (4500,0)。似乎我需要以某种方式缩放传递给 SetWindowPos() 的坐标,但我不知道该怎么做。

m_previousContext = SetThreadDpiAwarenessContext(GetWindowDpiAwarenessContext(hwnd));
if(m_previousContext == NULL)
Log::out<Log::Level::Error>("Failed to set thread dpi awareness context.");
SetWindowPos(hwnd, HWND_BOTTOM, 3000, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);

此外,如果我经常调整窗口大小和移动窗口,这不是真的很低效吗?

EDIT2: 我附上了一个最小工作二进制文件的链接。你可以download it from Google Drive here .它需要 Windows 10 版本 1607 才能运行。当我在上述设置中使用 SetWindowPos.exe 002108B6 3000 0 运行它时,窗口将移至 (4500,0)。

代码如下:

int main(int argc, char** argv)
{
if(argc < 4)
{
std::cerr << "Usage: SetWindowPos.exe <HWND> <x> <y>" << std::endl;
return 1;
}
HWND hwnd;
int x, y;
try
{
hwnd = (HWND)hexStrToInt(argv[1]); // I've omitted the implementation of hexStrToInt
x = atoi(argv[2]);
y = atoi(argv[3]);
}
catch(...)
{
std::cerr << "Invalid arguments." << std::endl;
return 1;
}
if(IsWindow(hwnd) == FALSE)
{
std::cerr << "Invalid window handle " << argv[1] << "." << std::endl;
return 1;
}
auto context = SetThreadDpiAwarenessContext(GetWindowDpiAwarenessContext(hwnd));
SetWindowPos(hwnd, HWND_BOTTOM, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
SetThreadDpiAwarenessContext(context);
return 0;
}

最佳答案

关于c++ - SetWindowPos() 跨进程处理多个监视器和不同的显示比例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54751195/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com