使用TRUE调用MoveWindow()后,窗口客户端区域仍然无效

时间:2010-08-19 09:31:16

标签: winapi

MSDN doc's for MoveWindow() says

“如果bRepaint参数为TRUE,系统会在移动窗口后立即将WM_PAINT消息发送到窗口过程(即,MoveWindow函数调用UpdateWindow函数)。”

但是当我在MoveWindow()之后调用GetUpdateRect()时,在处理父级中的WM_LBUTTONDOWN消息时,我发出一声嘟嘟声,表明该子项无效。什么是解释???

#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 个答案:

答案 0 :(得分:0)

我自己尝试过,WM_PAINTif(GetUpdateRect())之前被触发。另外,GetUpdateRect会为我返回FALSE。 我在XP上运行Visual Studio 2008。 我想这可能取决于您使用的编译器,使用的操作系统和诸如此类的东西。根据您传递的代码,所有内容都在同一个线程中完成,但如果它是一个多线程程序,我认为这可能会造成一些问题。

答案 1 :(得分:0)

MSDN doc是错误的。如文档所述,带有TRUE的MoveWindow()不会调用UpdateWindow()。它只是使窗口客户区无效。如果我在MoveWindow()之后调用UpdateWindow(),程序将按预期运行。