tags:

views:

46

answers:

2

MSDN doc's for MoveWindow() says:

"If the bRepaint parameter is TRUE, the system sends the WM_PAINT message to the window procedure immediately after moving the window (that is, the MoveWindow function calls the UpdateWindow function)."

But when I call GetUpdateRect() after MoveWindow(), while processing the WM_LBUTTONDOWN message in the parent, I get a beep, which shows that the child is invalid. What is the explanation ???

#include <windows.h>
#include <windowsx.h>
#include <tchar.h>

HINSTANCE   ghInstance;

LRESULT CALLBACK WindowProc (HWND hwnd, UINT message, UINT wParam, LONG lParam);
LRESULT CALLBACK ChildProc (HWND hwnd, UINT message, UINT wParam, LONG lParam);

int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
    HWND        hWnd;
    MSG     msg;
    WNDCLASSEX  wndclassx;

    ghInstance = hInstance;

    wndclassx.cbSize        = sizeof(WNDCLASSEX);
    wndclassx.style         = 0;
    wndclassx.lpfnWndProc   = WindowProc;
    wndclassx.cbClsExtra    = 0;
    wndclassx.cbWndExtra    = 0;
    wndclassx.hInstance     = hInstance;
    wndclassx.hIcon         = 0;
    wndclassx.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wndclassx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclassx.lpszMenuName  = NULL;
    wndclassx.lpszClassName = _T("ParentWindow");
    wndclassx.hIconSm       = NULL;

    if( !RegisterClassEx(&wndclassx) ) return 0;

    wndclassx.cbSize        = sizeof(WNDCLASSEX);
    wndclassx.style         = 0;
    wndclassx.lpfnWndProc   = ChildProc;
    wndclassx.cbClsExtra    = 0;
    wndclassx.cbWndExtra    = 0;
    wndclassx.hInstance     = hInstance;
    wndclassx.hIcon         = 0;
    wndclassx.hCursor       = 0;
    wndclassx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclassx.lpszMenuName  = NULL;
    wndclassx.lpszClassName = _T("ChildWindow");
    wndclassx.hIconSm       = NULL;

    if( !RegisterClassEx(&wndclassx) ) return 0;

    if( !(hWnd = CreateWindow(_T("ParentWindow"), _T("Parent Window"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                              CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance,
                              NULL)) ) return 0;

    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);

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

    return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
    HWND    hWnd;

    switch ( message )
    {
        case WM_CREATE:

        CreateWindow(_T("ChildWindow"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 10, 10, 100, 100, hwnd, (HMENU)0,
                          ghInstance, NULL);
        break;

        case WM_LBUTTONDOWN:

        hWnd = GetWindow(hwnd, GW_CHILD);

        MoveWindow(hWnd, 10, 10, 200, 200, true);

        if( GetUpdateRect(hWnd, NULL, FALSE) ) MessageBeep(-1);
        break;

        case WM_DESTROY:
        PostQuitMessage(0);
        break;

        default:

        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

LRESULT CALLBACK ChildProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
    return DefWindowProc(hwnd, message, wParam, lParam);
}
A: 

I tried it myself and WM_PAINT is triggered before the if(GetUpdateRect()) is. Also, GetUpdateRect returns FALSE for me. I'm running Visual Studio 2008 on XP. I guess it could depend on what compiler you are using, what operating system that is used and whatnot. According to the code you passed everything is done in the same thread, but if it is a multithreaded program I think that this could inflict some issues as well.

Default
The MoveWindow() calls the UpdateWindow() function. This function clears the invalid region. But still, GetUpdateRect() returns TRUE, acknowledging an invalid rectangle for the child window, which is clearly a contradiction.There's no problem with the code. As I said before, the program is running normally, and I can hear a beep after clicking the parent window client area !
jaayrosa
I'm just wondering if this is a BUG in the MoveWindow() function, or just a mistatement in the docs.
jaayrosa
The MSDN doc's is wrong. MoveWindow() doesn't call UpdateWindow() as the documentation says. It just invalidates the window client area. If I call UpdateWindow() just after MoveWindow() the program runs as expected.
jaayrosa
A: 

The MSDN doc's is wrong. MoveWindow() with TRUE doesn't call UpdateWindow() as the documentation says. It just invalidates the window client area. If I call UpdateWindow() just after MoveWindow() the program runs as expected.

jaayrosa
Nice catch. This is beyond my knowledge, but it could have something to do with the threading and how Windows handles the different messages. Although, I guess that if you Sleep for a small period of time it will still br incorrect?
Default