Страницы

Поиск по вопросам

среда, 27 ноября 2019 г.

Возможно ли узнать, находится ли окно в состоянии “сворачивание”, “разворачивание”?

#winapi #windows_7 #windows_10


Существует ли какой-либо способ узнать, является ли данное окно в Windows 7/10 в
состоянии "разворачивания" или "сворачивания"?

Суть в том, что если включены эффекты рабочего стола (Aero в Windows 7), у окон при
сворачивании и разворачивании есть определённая анимация. Однако если нажать по свёрнутому
окну в task bar, и сразу же вызвать IsWindowVisible() на этом окне, Win32API скажет
нам, что окно уже открыто, но по факту оно будет видимым лишь через N миллисекунд (когда
анимация разворачивания закончится).

Я пробовал найти API, который позволит узнавать о таких вещах, но, к сожалению, не
нашёл решений.

P.S.: Я знаю, что можно поставить global hooks (и написать DLL-ку, в которые поставить
handlers) на подобные actions, но это слишком тяжёлый и неэлегантный хак получится.

UPD.
Полноценного решения исходной проблемы, к сожалению, так и не нашёл. Так что на текущий
момент просто использую workaround -- на необходимое время отключаю эффекты анимации
(и только их), создавая временный объект, который на деструкторе восстанавливает анимации
(если они были до этого включены пользователем).

pub struct AnimationDisabler {
    info: ANIMATIONINFO,
}

pub fn disable_animation() -> Option {
    let mut animation_info = ANIMATIONINFO {
        cbSize: mem::size_of::() as UINT,
        iMinAnimate: 0
    };
    unsafe { SystemParametersInfoW(SPI_GETANIMATION,
                                                mem::size_of::() as UINT,
                                                &mut animation_info as LPANIMATIONINFO
as LPVOID,
                                                0) };


    // Animation is disabled already
    if animation_info.iMinAnimate == 0 {
        return None
    }

    let mut animation_disabled = ANIMATIONINFO {
        cbSize: mem::size_of::() as UINT,
        iMinAnimate: 0
    };

    unsafe { SystemParametersInfoW(SPI_SETANIMATION,
                                                    mem::size_of::()
as UINT,
                                                    &mut animation_disabled as LPANIMATIONINFO
as LPVOID,
                                                    SPIF_UPDATEINIFILE | SPIF_SENDCHANGE) };

    return Some(AnimationDisabler { info: animation_info });
}

impl Drop for AnimationDisabler {
    fn drop(&mut self) {
        unsafe { SystemParametersInfoW(SPI_SETANIMATION,
                                                    mem::size_of::()
as UINT,
                                                    &mut self.info as LPANIMATIONINFO
as LPVOID,
                                                    SPIF_UPDATEINIFILE | SPIF_SENDCHANGE) };
    }
}

    


Ответы

Ответ 1



По всей видимости, Вам нужно использовать WM_SIZING message или WM_SIZE message. WM_SIZING Sent to a window that the user is resizing. By processing this message, an application can monitor the size and position of the drag rectangle and, if needed, change its size or position. WM_SIZE Sent to a window after its size has changed. Пример использования LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { // ... case WM_SIZE: { //... } case WM_SIZING: { //... } break; } }

Ответ 2



Как на счет GetWindowRect ? Вернет ноль - значит окно свернуто )

Комментариев нет:

Отправить комментарий