将子窗口停靠到父窗口

时间:2011-02-21 16:59:06

标签: c++ winapi resize parent-child docking

当主窗口被用户调整大小(拖动角落)时,我需要6个控件(主窗口的子窗口)变大。我想我可以通过使用MoveWindow函数来改变主窗口的WM_SIZE或WM_SIZING函数中每个子节点的比例来实现这一点。这样做使得Debug构建变​​得奇怪(多个窗口,退出后窗口的图像等)。 Release版本运行正常,但是当我调整主窗口大小时,子窗口没有改变。

我发现http://msdn.microsoft.com/en-us/library/ms632598%28v=VS.85%29.aspx#creating_enumerating_etc使用了另一种方法:通过枚举所有子窗口,以及处理窗口的枚举回调函数,通过分配给每个子节点的唯一ID来调整大小。在自己尝试这个时,当主窗口调整大小时,它对控件没有任何影响。

为什么这不起作用?

在主窗口切换语句中:

case WM_SIZING:
        GetClientRect(hwnd, &hwndRect);
        EnumChildWindows(hwnd, EnumChildProc, (LPARAM)&hwndRect);
        break;

子枚举器回调函数:

BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
    LPRECT hwndRect = (LPRECT)lParam;
    switch(GetWindowLong(hwndChild, GWL_ID))
    {
        case ID_CHILD_LLABEL:
            MoveWindow(hwndChild, 0, 0, (hwndRect->right - hwndRect->left) - 30, 20,     false);
            break;
        case ID_CHILD_LDIR:
            MoveWindow(hwndChild, 12, 20, (hwndRect->right - hwndRect->left) - 40, 20,     false);
            break;
        case ID_CHILD_LLIST:
            MoveWindow(hwndChild, 12, 40, (hwndRect->right - hwndRect->left) - 40,         (hwndRect->bottom - hwndRect->top) - 238, false);
            break;
    }
}

1 个答案:

答案 0 :(得分:4)

MSDN's article on WM_SIZE:“如果由于WM_SIZE消息而为子窗口调用了SetScrollPos或MoveWindow函数,则bRedraw或bRepaint参数应该非零以使窗口重新绘制。” 我怀疑儿童控制器正在移动,它们根本就没有被重新粉刷。

可能还需要验证您的开关案例是否真的被击中了。

编辑: 我错过了显而易见的事您正在响应WM_SIZING,这表示窗口的大小即将(但尚未)更改。 WM_SIZE表示大小已更改。如果要使用WM_SIZING,则需要使用lParam中携带的rect,而不是GetClientRect的结果。不幸的是,WM_SIZING rect是窗口的矩形,而不是客户区域,并且是屏幕坐标。除非您确实需要在用户仍在执行调整大小时显示已调整大小的控件,否则只需处理WM_SIZE消息就会容易得多。