子窗口中的工具栏表现得很奇怪

发布于 2024-11-27 06:48:07 字数 4214 浏览 0 评论 0原文

好的,所以我使用 win32,目前使用尽可能少的额外库。我的应用程序使用分隔条分为多个子窗口,并且我在主窗口中添加了工具栏和状态栏。现在,我尝试向其中一个子窗口添加一个工具栏,它可以工作,但是一旦发生 WM_SIZE,按钮就会消失。顺便说一下,这一切都是在主窗口的 WndProc 中完成的。这是创建子窗口工具栏的代码:

toolRender = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS,
                    0, 0, 0, 0, wndRender, NULL, gHinst, 0);

    SendMessage(toolRender, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
    SendMessage(toolRender, CCM_SETVERSION, (WPARAM)5, 0);

    himl = ImageList_LoadImage(NULL, L"buttons.bmp", 16, 2, RGB(0, 255, 255), IMAGE_BITMAP, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
    SendMessage(toolRender, TB_SETIMAGELIST, 0, (LPARAM)himl);

    TBBUTTON tbb2[2];

    memset(tbb2, 0, sizeof(tbb2));
    tbb2[0].iBitmap = 0;
    tbb2[0].fsState = TBSTATE_ENABLED;
    tbb2[0].fsStyle = TBSTYLE_BUTTON;
    tbb2[0].idCommand = TOOL_SAVEALL;
    tbb2[0].iString = (INT_PTR)L"Save All";

    tbb2[1].iBitmap = 1;
    tbb2[1].fsState = TBSTATE_ENABLED;
    tbb2[1].fsStyle = TBSTYLE_BUTTON;
    tbb2[1].idCommand = TOOL_HELP;
    tbb2[1].iString = (INT_PTR)L"Help";

    SendMessage(toolRender, TB_SETMAXTEXTROWS, 0, 0);
    SendMessage(toolRender, TB_ADDBUTTONS, sizeof(tbb2)/sizeof(TBBUTTON), (LPARAM)&tbb2);

这是我的整个 WM_SIZE 消息:

case WM_SIZE :
    {
    GetClientRect(hwnd, &rect);

    // Resize toolbar
    SendMessage(toolMain, TB_AUTOSIZE, 0, 0);
    SendMessage(toolRender, TB_AUTOSIZE, 0, 0);
    SendMessage(statusMain, WM_SIZE, 0, 0);

    GetWindowRect(toolMain, &toolrect);
    GetWindowRect(statusMain, &statusrect);

    toolHeight = toolrect.bottom - toolrect.top;
    statusHeight = statusrect.bottom - statusrect.top;
    windowHeight = rect.bottom - rect.top;

    GetWindowRect(toolRender, &toolrect);

    toolRendHeight = toolrect.bottom - toolrect.top;

    //Make sure window isn't too small
    if (rect.right < MINSIZE * 4)
    {
        rect.right = MINSIZE * 4;
        forceresize = true;
    }
    if (windowHeight < toolHeight + statusHeight + toolRendHeight + (MINSIZE * 2))
    {
        rect.bottom = toolHeight + statusHeight + toolRendHeight + (MINSIZE * 2);
        forceresize = true;
    }

    //resize splitters
    xDiv1 = rect.right * xDiv1p;
    xDiv2 = rect.right * xDiv2p;
    xDiv3 = rect.right * xDiv3p;
    yDiv = rect.bottom * yDivp;

    // Make sure splitters aren't beyond bounds
    if (xDiv3 > rect.right - MINSIZE)
        xDiv3 = rect.right - MINSIZE;
    else if(xDiv3 < xDiv2 + MINSIZE)
        xDiv3 = xDiv2 + MINSIZE;

    if (xDiv2 > xDiv3 - MINSIZE)
        xDiv2 = xDiv3 - MINSIZE;
    else if (xDiv3 < xDiv1 + MINSIZE)
        xDiv2 = xDiv1 + MINSIZE;

    if (xDiv1 > xDiv2 - MINSIZE)
        xDiv1 = xDiv2 - MINSIZE;
    else if (xDiv1 < MINSIZE)
        xDiv1 = MINSIZE;

    if (yDiv > rect.bottom - MINSIZE)
        yDiv = rect.bottom - MINSIZE;
    else if(yDiv < MINSIZE + toolrect.bottom)
        yDiv = MINSIZE + toolrect.bottom;

    // Resize windows
    MoveWindow(wndObjBrowser, 0, toolHeight, xDiv1 - SBS, windowHeight - toolHeight - statusHeight, FALSE);

    MoveWindow(wndObjList, xDiv1 + SBS, toolHeight, xDiv2 - xDiv1 - (SBS * 2), windowHeight - toolHeight - statusHeight, FALSE);

    if (!bDualMonitor)
    {
    MoveWindow(wndRender, xDiv2 + SBS, toolHeight, rect.right - xDiv2 - SBS, yDiv - toolHeight - SBS, FALSE);
    //SendMessage(toolRender, TB_AUTOSIZE, 0, 0);

    MoveWindow(wndAreaList, xDiv2 + SBS, yDiv + SBS, xDiv3 - xDiv2 - (SBS * 2), windowHeight - statusHeight - yDiv - SBS, FALSE);

    MoveWindow(wndAreaInfo, xDiv3 + SBS, yDiv + SBS, rect.right - xDiv3 - SBS, windowHeight - statusHeight - yDiv - SBS, FALSE);
    }
    else if (bDualMonitor)
    {
        MoveWindow(wndAreaList, xDiv2 + SBS, toolHeight, rect.right - xDiv2 - SBS, yDiv - toolHeight, FALSE);

        MoveWindow(wndAreaInfo, xDiv2 + SBS, yDiv + SBS, rect.right - xDiv2 - SBS, windowHeight - statusHeight - yDiv - SBS, FALSE);
    }

    if (forceresize)
        MoveWindow(hwnd, rect.left, rect.top, rect.right, rect.bottom, FALSE);

    InvalidateRect(hwnd, &rect, TRUE);
    }
  break; //WM_SIZE

有什么想法吗?

Okay, so I'm using win32, with as few extra libraries as possible for the moment. My application is divided into multiple child windows using splitterbars, and I've added a toolbar and status bar to the main window. Now, I'm trying to add a toolbar to one of the child windows, and it works, but as soon as WM_SIZE happens, the buttons dissapear. This is all done in the WndProc for the Main window, by the way. Here's the code that creates the child window's toolbar:

toolRender = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS,
                    0, 0, 0, 0, wndRender, NULL, gHinst, 0);

    SendMessage(toolRender, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
    SendMessage(toolRender, CCM_SETVERSION, (WPARAM)5, 0);

    himl = ImageList_LoadImage(NULL, L"buttons.bmp", 16, 2, RGB(0, 255, 255), IMAGE_BITMAP, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
    SendMessage(toolRender, TB_SETIMAGELIST, 0, (LPARAM)himl);

    TBBUTTON tbb2[2];

    memset(tbb2, 0, sizeof(tbb2));
    tbb2[0].iBitmap = 0;
    tbb2[0].fsState = TBSTATE_ENABLED;
    tbb2[0].fsStyle = TBSTYLE_BUTTON;
    tbb2[0].idCommand = TOOL_SAVEALL;
    tbb2[0].iString = (INT_PTR)L"Save All";

    tbb2[1].iBitmap = 1;
    tbb2[1].fsState = TBSTATE_ENABLED;
    tbb2[1].fsStyle = TBSTYLE_BUTTON;
    tbb2[1].idCommand = TOOL_HELP;
    tbb2[1].iString = (INT_PTR)L"Help";

    SendMessage(toolRender, TB_SETMAXTEXTROWS, 0, 0);
    SendMessage(toolRender, TB_ADDBUTTONS, sizeof(tbb2)/sizeof(TBBUTTON), (LPARAM)&tbb2);

And here's my entire WM_SIZE message:

case WM_SIZE :
    {
    GetClientRect(hwnd, &rect);

    // Resize toolbar
    SendMessage(toolMain, TB_AUTOSIZE, 0, 0);
    SendMessage(toolRender, TB_AUTOSIZE, 0, 0);
    SendMessage(statusMain, WM_SIZE, 0, 0);

    GetWindowRect(toolMain, &toolrect);
    GetWindowRect(statusMain, &statusrect);

    toolHeight = toolrect.bottom - toolrect.top;
    statusHeight = statusrect.bottom - statusrect.top;
    windowHeight = rect.bottom - rect.top;

    GetWindowRect(toolRender, &toolrect);

    toolRendHeight = toolrect.bottom - toolrect.top;

    //Make sure window isn't too small
    if (rect.right < MINSIZE * 4)
    {
        rect.right = MINSIZE * 4;
        forceresize = true;
    }
    if (windowHeight < toolHeight + statusHeight + toolRendHeight + (MINSIZE * 2))
    {
        rect.bottom = toolHeight + statusHeight + toolRendHeight + (MINSIZE * 2);
        forceresize = true;
    }

    //resize splitters
    xDiv1 = rect.right * xDiv1p;
    xDiv2 = rect.right * xDiv2p;
    xDiv3 = rect.right * xDiv3p;
    yDiv = rect.bottom * yDivp;

    // Make sure splitters aren't beyond bounds
    if (xDiv3 > rect.right - MINSIZE)
        xDiv3 = rect.right - MINSIZE;
    else if(xDiv3 < xDiv2 + MINSIZE)
        xDiv3 = xDiv2 + MINSIZE;

    if (xDiv2 > xDiv3 - MINSIZE)
        xDiv2 = xDiv3 - MINSIZE;
    else if (xDiv3 < xDiv1 + MINSIZE)
        xDiv2 = xDiv1 + MINSIZE;

    if (xDiv1 > xDiv2 - MINSIZE)
        xDiv1 = xDiv2 - MINSIZE;
    else if (xDiv1 < MINSIZE)
        xDiv1 = MINSIZE;

    if (yDiv > rect.bottom - MINSIZE)
        yDiv = rect.bottom - MINSIZE;
    else if(yDiv < MINSIZE + toolrect.bottom)
        yDiv = MINSIZE + toolrect.bottom;

    // Resize windows
    MoveWindow(wndObjBrowser, 0, toolHeight, xDiv1 - SBS, windowHeight - toolHeight - statusHeight, FALSE);

    MoveWindow(wndObjList, xDiv1 + SBS, toolHeight, xDiv2 - xDiv1 - (SBS * 2), windowHeight - toolHeight - statusHeight, FALSE);

    if (!bDualMonitor)
    {
    MoveWindow(wndRender, xDiv2 + SBS, toolHeight, rect.right - xDiv2 - SBS, yDiv - toolHeight - SBS, FALSE);
    //SendMessage(toolRender, TB_AUTOSIZE, 0, 0);

    MoveWindow(wndAreaList, xDiv2 + SBS, yDiv + SBS, xDiv3 - xDiv2 - (SBS * 2), windowHeight - statusHeight - yDiv - SBS, FALSE);

    MoveWindow(wndAreaInfo, xDiv3 + SBS, yDiv + SBS, rect.right - xDiv3 - SBS, windowHeight - statusHeight - yDiv - SBS, FALSE);
    }
    else if (bDualMonitor)
    {
        MoveWindow(wndAreaList, xDiv2 + SBS, toolHeight, rect.right - xDiv2 - SBS, yDiv - toolHeight, FALSE);

        MoveWindow(wndAreaInfo, xDiv2 + SBS, yDiv + SBS, rect.right - xDiv2 - SBS, windowHeight - statusHeight - yDiv - SBS, FALSE);
    }

    if (forceresize)
        MoveWindow(hwnd, rect.left, rect.top, rect.right, rect.bottom, FALSE);

    InvalidateRect(hwnd, &rect, TRUE);
    }
  break; //WM_SIZE

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

2024-12-04 06:48:07

为什么在大多数 MoveWindow 调用中为 bRepaint 参数传递 FALSE?最后的 InvalidateRect 仅使当前窗口无效,而不是其子窗口。

Why are you passing FALSE for the bRepaint parameter in most of the MoveWindow calls? The InvalidateRect at the end only invalidates the current window, not its children.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文