winapi - 将一个窗口移动到第二个屏幕后,当我最小化同一个窗口并再次重新打开它时,它又回到了第一个监视器
问题描述
在使用MoveWindow功能后,标题几乎解释了这一切,窗口确实会转到第二个监视器,但在最小化应用程序并再次打开它之后,窗口会重新出现在第一个屏幕上。我猜有一个功能可以对 windows 说窗口现在在第二个屏幕而不是第一个屏幕上,但我似乎找不到它。
RECT applicationRect;
HWND applicationHWND;
applicationHWND = GetForegroundWindow();
GetWindowRect(applicationHWND, &applicationRect);
const int width = abs( abs(applicationRect.right) - abs(applicationRect.left) );
const int height = abs( abs(applicationRect.bottom) - abs(applicationRect.top) );
short screen = 0;
if(applicationRect.left < -8){//Posible left screen
if(abs(applicationRect.left) > abs(applicationRect.right))screen = 1;
else screen = 0;
}
const int newleft = (screen == 0)*(applicationRect.left - 1920) + (screen == 1)*(applicationRect.left + 1920);
MoveWindow(applicationHWND, newleft, applicationRect.top, width, height, false);
这是将窗口移动到另一个屏幕的功能。
解决方案
现在我可以重现它,当目标窗口最大化时会发生这种情况。在这种情况下MoveWindow
不能改变正常的位置值(即WINDOWPLACEMENT.rcNormalPosition
)。当窗口恢复到最大化时,会根据这个值恢复(检测在哪个显示器上)。你需要先检查窗口是否最大化,然后调用SetWindowPlacement
改变这个Position。除了最大化窗口,您还可以SetWindowPlacement
使用MoveWindow
.
#include <windows.h>
#include <iostream>
int main()
{
RECT applicationRect;
HWND applicationHWND;
BOOL ret = 0;
applicationHWND = GetForegroundWindow();
GetWindowRect(applicationHWND, &applicationRect);
const int width = abs(abs(applicationRect.right) - abs(applicationRect.left));
const int height = abs(abs(applicationRect.bottom) - abs(applicationRect.top));
short screen = 0;
if (applicationRect.left < -8) {//Posible left screen
if (abs(applicationRect.left) > abs(applicationRect.right))screen = 1;
else screen = 0;
}
const int newleft = (screen == 0) * (applicationRect.left - 1920) + (screen == 1) * (applicationRect.left + 1920);
WINDOWPLACEMENT place = {};
place.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(applicationHWND, &place);
if (place.showCmd == SW_SHOWMAXIMIZED)
{
MoveWindow(applicationHWND, newleft, applicationRect.top, width, height, false);
}
place.rcNormalPosition.left = (screen == 0) * (place.rcNormalPosition.left - 1920) + (screen == 1) * (place.rcNormalPosition.left + 1920);
place.rcNormalPosition.right = (screen == 0) * (place.rcNormalPosition.right - 1920) + (screen == 1) * (place.rcNormalPosition.right + 1920);
place.flags |= WPF_ASYNCWINDOWPLACEMENT;
ret = SetWindowPlacement(applicationHWND, &place);
}
推荐阅读
- jenkins - Jenkins:archiveArtifacts - 多个不同的文件
- java - 嵌套异常是 java.lang.NumberFormatException: For input string/ Multipart file and json data to spring boot
- javascript - Error in Microsoft Bot Emulator: connect ECONNREFUSED 127.0.0.1
- python - 我本地 Jupter 中 Numpy.sum() 的意外返回值
- java - 为每个请求新建 ThreadPoolExecutor,或者创建一个 ThreadPoolExecutor 的单例 spring bean
- php - Laravel 5.6 '/' 找到路由但未找到其他路由 AWS EC2
- algorithm - 使所有数组元素为零的最小 AND 操作数
- android - 在 Appium for Android 中以编程方式启用/禁用飞行模式
- c# - 起订量未在第二次验证时执行调用
- python - Selenium Python 条件搜索