首页 > 解决方案 > 将一个窗口移动到第二个屏幕后,当我最小化同一个窗口并再次重新打开它时,它又回到了第一个监视器

问题描述

在使用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);

这是将窗口移动到另一个屏幕的功能。

标签: winapipinvoke

解决方案


现在我可以重现它,当目标窗口最大化时会发生这种情况。在这种情况下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);

}

推荐阅读