Захват изображения из свернутого окна

Как следует из названия, я хотел бы сделать снимок из свернутого окна... возможно ли это? Я использую CaptureAnImage из msdn и работает, если только окно не свернуто.

Одно из решений, которое я пробовал, заключалось в том, чтобы максимизировать его, захватить изображение, а затем вернуть его в исходное состояние. Единственная проблема в том, что анимация выглядит уродливо, и я хотел бы найти альтернативу... Вот как я это пробовал:

WINDOWPLACEMENT wInfo;
UINT originalPlacement;

GetWindowPlacement(hWnd, &wInfo);
originalPlacement = wInfo.showCmd;

wInfo.showCmd = SW_MAXIMIZE;
SetWindowPlacement(hWnd, &wInfo);
wInfo.showCmd = originalPlacement;

CaptureAnImage(hWnd); // Capture the image while it's maximized

SetWindowPlacement(hWnd, &wInfo);

Итак, я ищу одно из этих решений:

Можно ли захватить изображение, даже если оно свернуто?

or

Можно ли развернуть его, захватить, а затем вернуть в исходное состояние без какой-либо анимации?

PS: я обнаружил, что ссылка ищу свою проблему, но она на С#, и я не могу заставить ее работать на С++...


person MyUsername112358    schedule 23.01.2014    source источник


Ответы (1)


Вы не можете захватить свернутое окно, вы ДОЛЖНЫ сначала восстановить его. Но вы можете при желании восстановить его за пределами экрана или с прозрачностью альфа-канала, равной 1, чтобы пользователь не видел его, но ОС видела. И обязательно временно отключите анимацию восстановления/свертывания, используя SystemParametersInfo(SPI_SETANIMATION) (делайте это только в том случае, если SPI_GETANIMATION включена анимация отчетов), чтобы сократить время, необходимое для отображения и повторного скрытия окна.

Например:

WINDOWPLACEMENT wp = {0};
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hWnd, &wp);

ANIMATIONINFO ai = {0};
bool restoreAnimated = false;

if (wp.showCmd == SW_SHOWMINIMIZED)
{
    ai.cbSize = sizeof(ANIMATIONINFO);
    SystemParametersInfo(SPI_GETANIMATION, sizeof(ANIMATIONINFO), &ai, 0);

    if (ai.iMinAnimate != 0)
    {
        ai.iMinAnimate = 0;
        SystemParametersInfo(SPI_SETANIMATION, sizeof(ANIMATIONINFO), &ai, 0);
        restoreAnimation = true;
    }

    // optionally move the window off-screen, or
    // apply alpha using SetLayeredWindowAttributes()...

    ShowWindow(hWnd, SW_SHOWNOACTIVATE);
}

// capture as needed ...

if (wp.showCmd == SW_SHOWMINIMIZED)
{
    SetWindowPlacement(hWnd, &wp);

    // optionally remove alpha using SetLayeredWindowAttributes()...

    if (restoreAnimation)
    {
        ai.iMinAnimate = 1;
        SystemParametersInfo(SPI_SETANIMATION, sizeof(ANIMATIONINFO), &ai, 0);
    }
}
person Remy Lebeau    schedule 23.01.2014
comment
Если окно свернуто, когда мы наводим курсор мыши на его значок на панели задач, ОС Windows отобразит небольшое окно поверх значка, показывающее экран окна, выполняет ли ОС Windows ваш код за кулисами? :) - person Shayan; 04.05.2020
comment
@ Шаян нет. Свернутое окно на самом деле не свернуто, оно перемещается за пределы экрана на уровне ОС. Windows все еще может отображать его, просто пользователь его не видит. Панель задач также позволяет приложению отображать свой собственный предварительный просмотр окна, если оно этого хочет. Таким образом, приложение может отображать свернутое окно в растровое изображение для отображения на панели задач. - person Remy Lebeau; 04.05.2020