Home > Software engineering >  AnimateWindow not calling WM_PAINT
AnimateWindow not calling WM_PAINT

Time:03-19

I need to animate the display of the rendered window, I have a WM_PRINTCLIENT and WM_PAINT event, but the window is not rendered during the animation, only if RedrawWindow is used after the animation is shown

WNDCLASSW Wcc;
MSG Msg;
Wcc.style = CS_HREDRAW | CS_VREDRAW;
Wcc.lpfnWndProc = &this->_ChildWndProc;
Wcc.cbClsExtra = 0;
Wcc.cbWndExtra = 0;
Wcc.hInstance = (HINSTANCE)GetWindowLong(hParent, GWL_HINSTANCE);
hInst_ = (HINSTANCE)GetWindowLong(hParent, GWL_HINSTANCE);
Wcc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
Wcc.hCursor = LoadCursor(NULL, IDC_ARROW);
Wcc.hbrBackground = reinterpret_cast<HBRUSH> (CreateSolidBrush(RGB( 255, 255, 255)));
Wcc.lpszMenuName = NULL;
Wcc.lpszClassName = className;
this->className = className;
this->hParent = hWnd;
this->text = text;
this->title = title;
//this->title = title;
windowW = 450;
windowH = 300;

hChild = CreateWindowExW(0, Wcc.lpszClassName, 0, WS_POPUP | WS_MINIMIZEBOX, x, y,
    windowW, windowH, hWnd, NULL, (HINSTANCE)GetWindowLong(hParent, GWL_HINSTANCE), NULL);
loadResources(hChild);
SetWindowLongPtrW(hChild, GWLP_USERDATA, (LONG)this);
//SetTransparency(hChild, 0x0f);
//ShowWindow(hChild, SW_SHOW);

AnimateWindow(hChild, 1000, AW_ACTIVATE | AW_BLEND);

PAINT:

case WM_PAINT:
{
    Paint(hDlg);
    break;
}
case WM_PRINTCLIENT:
{
    PaintA(hDlg);
    break;
}

Paint(HWND hwnd)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);
    Graphics graphics(hdc);

    Image image(L"g:\\_project\\image viewer\\ipcamera.jpg");
    graphics.DrawImage(&image, 0, 0);
    EndPaint(hwnd, &ps);
}
PaintA(HWND hwnd)
{
    
    HDC hdc = GetDC(hwnd);
    Graphics graphics(hdc);

    Image image(L"g:\\_project\\image viewer\\ipcamera.jpg");
    graphics.DrawImage(&image, 0, 0);
   
}

enter image description here

CodePudding user response:

I have adopted your code, so that I can run it in isolation. I do get debug output WM_PRINTCLIENT during animation.

void foo(HINSTANCE hInst, HWND hParent) {
    static const wchar_t* className = L"myClassName";
    WNDCLASSW Wcc = {};
    MSG Msg;
    Wcc.style = CS_HREDRAW | CS_VREDRAW;
    Wcc.lpfnWndProc = ChildWndProc;
    Wcc.cbClsExtra = 0;
    Wcc.cbWndExtra = 0;
    Wcc.hInstance = hInst;
    Wcc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    Wcc.hCursor = LoadCursor(NULL, IDC_ARROW);
    Wcc.hbrBackground = CreateSolidBrush(RGB(255, 0, 255));
    Wcc.lpszMenuName = NULL;
    Wcc.lpszClassName = className;

    RegisterClassW(&Wcc);

    HWND hChild = CreateWindowW(className, nullptr, WS_POPUP | WS_MINIMIZEBOX, 100, 200, 300, 400, nullptr, nullptr, hInst, nullptr);

    AnimateWindow(hChild, 2000, AW_ACTIVATE | AW_BLEND);
}

And here is the window proc I used:

LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_PAINT:
    {
        ::OutputDebugString(L"WM_PAINT\n");
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
    }
    case WM_PRINTCLIENT:
    {
        ::OutputDebugString(L"WM_PRINTCLIENT\n");
        HDC hdc = (HDC)wParam;
        ::MoveToEx(hdc, 10, 10, nullptr);
        ::LineTo(hdc, 100, 100);
    }
    case WM_ERASEBKGND:
    {
        ::OutputDebugString(L"WM_ERASEBKGND\n");
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

NOTE:

For details, please see WM_PRINTCLIENT message

A window can process this message in much the same manner as WM_PAINT, except that BeginPaint and EndPaint need not be called (a device context is provided), and the window should draw its entire client area rather than just the invalid region.

  • Related