Click here to Skip to main content
14,485,233 members

Guarantee Correct Spacing for toolbar Separators on Multiple TB_ADDBUTTONS Calls

Rate this:
5.00 (2 votes)
Please Sign up or sign in to vote.
5.00 (2 votes)
15 Jan 2020CPOL
A solution for: If the toolbar is created button by button with single TB_ADDBUTTONS calls, the width of the separators is not calculated correctly.


I create my toolbar by single TB_ADDBUTTONS message calls. I used TB_ADDBUTTONS message calls to create separators as well. But the width of the separators starts too small and then it increases with each separator.

Image 1


To get the right separator width (8px each), the TBSTYLE_SEP must not be added to the toolbar separately. To solve this problem, I changed my API and added the bPrependSeparator argument. This is the result:

Image 2

Using the Code

I know - it could be made shorter, but the code is readable and does what it should:

/// <summary>
/// Adds a new button to the tool bar.
/// </summary>
/// <param name="hBmpImage">The handler of the tool bar button image bitmap.
/// Can be <c>NULL</c>, if <c>byStyle</c> doesn't need an image.</param>
/// <param name="hBmpMask">The handler of the tool bar button mask bitmap.
/// Can be <c>NULL</c>, if transparency is not required.</param>
/// <param name="uiCommandID">The tool bar button command ID, that is in sync
/// with the menu item command ID.</param>
/// <param name="byState">The initial tool bar button state.</param>
/// <param name="byStyle">The tool bar button style.</param>
/// <param name="wszText">The optional text to display below the image.</param>
/// <param name="bPrependSeparator">The flag determining whether to prepend a separator.
/// </param>
/// <returns>The number of remaining image list slots for tool bar button images.</returns>
/// <remarks>Can still be called like this to create an not-prepended separator
/// (but the space isn't correct):
/// pToolBar->AddButton(NULL, NULL, (UINT)0, TBSTATE_ENABLED, TBSTYLE_SEP);</remarks>
UINT OgwwToolBar::AddButton(HBITMAP hBmpImage, HBITMAP hBmpMask, 
                            UINT uiCommandID, BYTE byState,
                            BYTE byStyle, LPCWSTR wszText, BOOL bPrependSeparator)
    if (hBmpImage != NULL)
        ::ImageList_Add(_hImageList, hBmpImage, hBmpMask);

    if (bPrependSeparator != FALSE)
        TBBUTTON tbb[2];
        ::ZeroMemory(tbb, sizeof(tbb));

        tbb[0].iBitmap   = 0;
        tbb[0].idCommand = 0;
        tbb[0].fsState   = TBSTATE_ENABLED;
        tbb[0].fsStyle   = TBSTYLE_SEP;
        tbb[0].iString   = 0;

        tbb[1].iBitmap   = (_hImageList != NULL) ? _wBitmapUsed - 1 : 0;
        tbb[1].idCommand = uiCommandID;
        tbb[1].fsState   = byState;
        tbb[1].fsStyle   = byStyle;
        tbb[1].iString   = 0; // SendMessageW(hToolBar, TB_ADDSTRING, 0, (LPARAM)wszText);

        // Try this if it doesn't work out right away:
        //::SendMessageW((HWND)_hHandle, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
        ::SendMessageW((HWND)_hHandle, TB_ADDBUTTONS, 2, (LPARAM)tbb);
        TBBUTTON tbb;
        ::ZeroMemory(&tbb, sizeof(tbb));

        tbb.iBitmap   = (_hImageList != NULL) ? _wBitmapUsed - 1 : 0;
        tbb.idCommand = uiCommandID;
        tbb.fsState   = byState;
        tbb.fsStyle   = byStyle;
        tbb.iString   = 0; // SendMessageW(hToolBar, TB_ADDSTRING, 0, (LPARAM)wszText);

        ::SendMessageW((HWND)_hHandle, TB_ADDBUTTONS, 1, (LPARAM)&tbb);

    return (_wBitmapCount - _wBitmapUsed);

Happy programming!

Points of Interest

Not everything that is allowed/compiles works.


  • 16th January, 2020: Initial version


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Steffen Ploetz
CEO Ploetz + Zeller GmbH
Germany Germany
No Biography provided

Comments and Discussions

-- There are no messages in this forum --
Posted 15 Jan 2020

Tagged as


3 bookmarked