You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Win32应用中为Rebar添加Toolbar作为附加带的布局异常问题

Win32 Rebar控件添加Toolbar后布局异常的解决方法

问题根源分析

  1. Toolbar未设置可见性:创建Toolbar时未添加WS_VISIBLE样式,导致Rebar无法正确识别其尺寸。
  2. Rebar Band宽度设置错误:Toolbar对应的Rebar Band设置rbbi.cx = 0,未指定需求的40%主窗口宽度,导致Rebar自动计算尺寸出错。
  3. Toolbar样式冗余:TBSTYLE_WRAPABLE会让按钮自动换行,不符合当前固定3个按钮的布局需求,应移除。
  4. 尺寸参数不匹配:未正确传递主窗口宽度到Band的尺寸设置,同时缺少RBBIM_CY掩码来指定Band的高度。

修改后的核心代码

修正的CreateRebar1函数

HWND hWndRebar1 = NULL;
HWND hWndSelectorComboBox = NULL;
HWND hWndButton = NULL;
HWND hWndToolbarCutCopyPaste = NULL;

void CreateRebar1(HWND hWndParent) {
    // 获取主窗口尺寸
    RECT rectMainWindow;
    GetWindowRect(hWndParent, &rectMainWindow);
    int mainWidth = rectMainWindow.right - rectMainWindow.left;

    // 创建Rebar控件
    hWndRebar1 = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL, 
        WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS,
        0, 0, mainWidth, 50, hWndParent, NULL, GetModuleHandle(NULL), NULL);

    REBARBANDINFO  rbbi = { REBARBANDINFO_V3_SIZE };

    // 1. 添加组合框带(占主窗口50%宽度)
    CreateSelectorComboBox(hWndRebar1, 0.5 * mainWidth, 50);
    RECT rcComboBox;
    GetWindowRect(hWndSelectorComboBox, &rcComboBox);

    ZeroMemory(&rbbi, sizeof(rbbi));
    rbbi.cbSize = REBARBANDINFO_V3_SIZE;
    rbbi.fMask = RBBIM_SIZE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE;
    rbbi.cxMinChild = rcComboBox.right - rcComboBox.left;
    rbbi.cyMinChild = rcComboBox.bottom - rcComboBox.top;
    rbbi.cx = 0.5 * mainWidth; // 明确设置50%宽度
    rbbi.fStyle = RBBS_CHILDEDGE | RBBS_FIXEDBMP | RBBS_GRIPPERALWAYS;
    rbbi.hwndChild = hWndSelectorComboBox;
    SendMessage(hWndRebar1, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbbi);

    // 2. 添加Toolbar带(占主窗口40%宽度)
    CreateToolbarCutCopyPaste(hWndRebar1, 0.4 * mainWidth, 50);

    DWORD dwBtnSize = (DWORD)SendMessage(hWndToolbarCutCopyPaste, TB_GETBUTTONSIZE, 0, 0);
    int toolbarTotalWidth = 3 * HIWORD(dwBtnSize);

    ZeroMemory(&rbbi, sizeof(rbbi));
    rbbi.cbSize = REBARBANDINFO_V3_SIZE;
    rbbi.fMask = RBBIM_SIZE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_CY;
    rbbi.fStyle = RBBS_CHILDEDGE | RBBS_FIXEDBMP | RBBS_GRIPPERALWAYS;
    rbbi.hwndChild = hWndToolbarCutCopyPaste;
    rbbi.cy = LOWORD(dwBtnSize); // 指定Band高度为按钮高度
    rbbi.cyChild = LOWORD(dwBtnSize);
    rbbi.cxMinChild = toolbarTotalWidth; // 最小宽度为3个按钮总宽度
    rbbi.cyMinChild = LOWORD(dwBtnSize);
    rbbi.cx = 0.4 * mainWidth; // 明确设置40%主窗口宽度

    SendMessage(hWndRebar1, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbbi);
}

修正的CreateToolbarCutCopyPaste函数

void CreateToolbarCutCopyPaste(HWND hWndParent, int cx, int cy)
{
    const int ImageListID = 0;
    const int numButtons = 3;
    const int bitmapSize = 16;
    const DWORD buttonStyles = BTNS_AUTOSIZE;

    // 创建Toolbar,添加WS_VISIBLE样式,移除TBSTYLE_WRAPABLE
    hWndToolbarCutCopyPaste = CreateWindowEx(0, TOOLBARCLASSNAME,
             NULL, 
             WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT, 
             0, 0, cx, cy, hWndParent, 
             NULL, GetModuleHandle(NULL), NULL);

    TBBUTTON tbButtons[numButtons] = 
    {
        { MAKELONG(STD_CUT,  ImageListID), IDM_CUT,  TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Cut"},
        { MAKELONG(STD_COPY, ImageListID), IDM_COPY, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Copy"},
        { MAKELONG(STD_PASTE, ImageListID), IDM_PASTE, 0,               buttonStyles, {0}, 0, (INT_PTR)L"Paste"}
    };

    g_hImageList = ImageList_Create(bitmapSize, bitmapSize,
        ILC_COLOR16 | ILC_MASK,
        numButtons, 0);

    SendMessage(hWndToolbarCutCopyPaste, TB_SETIMAGELIST, (WPARAM)ImageListID, (LPARAM)g_hImageList);
    SendMessage(hWndToolbarCutCopyPaste, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR, (LPARAM)HINST_COMMCTRL);
    SendMessage(hWndToolbarCutCopyPaste, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
    SendMessage(hWndToolbarCutCopyPaste, TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)&tbButtons);
    
    // 让Toolbar自动调整到合适大小
    SendMessage(hWndToolbarCutCopyPaste, TB_AUTOSIZE, 0, 0);
}

关键修改点说明

  • 给Toolbar添加WS_VISIBLE样式,确保Rebar能正确获取其尺寸信息。
  • 移除TBSTYLE_WRAPABLE,避免按钮自动换行导致布局混乱。
  • 明确设置Rebar Band的rbbi.cx为需求的百分比宽度(50%和40%),而非依赖自动计算。
  • 在Rebar Band的fMask中添加RBBIM_CY,指定Band的高度,确保与Toolbar按钮高度匹配。
  • 给Toolbar发送TB_AUTOSIZE消息,让其自动调整到适配按钮的大小。

内容的提问来源于stack exchange,提问作者gene b.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 12:05:53