1
votes

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);
}
2
needs some formatting. Try editing this post; mark all your code and; press the "code" icon in the editing menudefault
Have you checked the return values of CreateWindow and GetWindow and made sure that you do not get NULL?default
The program is running normally. The CreateWindow() creates the child and GetWindow() returns the child handle. What do you mean by "mark all your code " ?Ayrosa
as you can see, some of your code is in a grey box. if you click the edit button, select/mark all the text that is supposed to be code, and then click the "Code Sample" button (the 101010 button) it will be easier to readdefault

2 Answers

0
votes

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.

0
votes

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.