Как мне повторно показать окно с анимацией? - PullRequest
0 голосов
/ 14 июля 2020

При первом отображении окна верхнего уровня появляется короткая анимация плавного появления. Если окно скрыто, появляется короткая анимация затухания. Однако, если окно впоследствии отображается снова (с ShowWindow(SW_SHOW)), анимации нет!

Затухание анимации происходит каждый раз, когда окно скрыто, но затухающая анимация происходит только в первый раз отображается окно.

Как сделать так, чтобы анимация появлялась каждый раз при отображении окна?

Тестовая программа для демонстрации эффекта:

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK TestWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
}

HWND hwnd;

void CALLBACK TestTimerProc(HWND, UINT, UINT_PTR, DWORD) {
    static int state = 0;

    printf("Timer %d\n", state);

    if (state == 0) {
        state = 1;
        ShowWindow(hwnd, SW_SHOW); // or SW_SHOWNORMAL or SW_SHOWNA

    } else if (state == 1) {
        state = 0;
        ShowWindow(hwnd, SW_HIDE);
    }
}


int main() {
    HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
    WNDCLASSEX wcx = {0};
    wcx.cbSize = sizeof(wcx);
    wcx.hInstance = hInst;
    wcx.lpszClassName = TEXT("TestWindowClass");
    wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcx.lpfnWndProc = TestWndProc;
    RegisterClassEx(&wcx);
    hwnd = CreateWindow(TEXT("TestWindowClass"), TEXT("Test window"), WS_TILEDWINDOW, 200, 200, 500, 500, NULL, NULL, hInst, NULL);

    SetTimer(NULL, 0, 1000, TestTimerProc);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

1 Ответ

0 голосов
/ 15 июля 2020

Несмотря на то, что вы скрываете форму, положение формы не изменилось, поэтому, когда вы снова отобразите форму, она будет отображаться прямо в скрытой позиции, что заставляет нас выглядеть так, как будто она не имеет эффекта «исчезновения».

Но на самом деле это не настоящий эффект постепенного появления, это больше похоже на эффект, генерируемый при генерации формы, поэтому при повторном отображении такого эффекта не будет.

Если вы хотите добиться эффекта плавного появления, я также рекомендую использовать AnimateWindow для его достижения. Хотя это не очень похоже на постепенное появление сгенерированной формы, оно не будет таким внезапным, как скрытие и последующее отображение.

Вот пример:

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK TestWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
}

HWND hwnd;

void CALLBACK TestTimerProc(HWND, UINT, UINT_PTR, DWORD) {
    static int state = 0;
    printf("Timer %d\n", state);

    if (state == 0) {
        AnimateWindow(hwnd, 200, AW_BLEND);
        state = 1;
    }
    else if (state == 1) {
        ShowWindow(hwnd, SW_HIDE);
        state = 0;
    }
}


int main() {
    HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
    WNDCLASSEX wcx = { 0 };
    wcx.cbSize = sizeof(wcx);
    wcx.hInstance = hInst;
    wcx.lpszClassName = TEXT("TestWindowClass");
    wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcx.lpfnWndProc = TestWndProc;
    RegisterClassEx(&wcx);
    hwnd = CreateWindow(TEXT("TestWindowClass"), TEXT("Test window"), WS_TILEDWINDOW | WS_EX_LAYERED, 200, 200, 500, 500, NULL, NULL, hInst, NULL);

    SetTimer(NULL, 0, 1000, TestTimerProc);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
...