4

Recently I started learning GUI programming based on Win32 API. When I add tool bar control (from comctl32.lib) to my simple application I find it looks flat while the menu bar has more "Windows 7 friendly" 3D look and feel (white glow at the top and vertical gray gradient from top to bottom). The difference makes it look wired.

Default ToolBar style

However, I find many other applications have consistent look and feel for both menu bar and tool bar. Eg. Notepad++ and Notepad 2.

Notepad++ Notepad 2

I've read some official documents and tried the solution, such as Visual Styles Overview, Enabling Visual Styles, however, it only enables the flat button style (compared to the old Win98 solid button style). It made no difference with the style I got in the first picture.

I tried to read Notepad++'s source code. Found ToolBar.cpp and made some changes to my code accordingly, but nothing changed. I think I was lost in the code base.

Here is my code of calling InitCommonControlsEx and creation of the ToolBar.

// in WinMain
INITCOMMONCONTROLSEX icce;
icce.dwSize = sizeof(INITCOMMONCONTROLSEX);
icce.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES | ICC_USEREX_CLASSES;
InitCommonControlsEx(&icce);

// called in WM_CREATE handler, hwnd is the handle of the main window
VOID BuildToolBar(HWND hwnd)
{
    HWND hTool;
    TBBUTTON tbb[3];
    TBADDBITMAP tbab;

    hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS |TBSTYLE_FLAT | CCS_TOP | BTNS_AUTOSIZE, 0, 0, 0, 0, hwnd, (HMENU)IDC_MAIN_TOOL, GetModuleHandle(NULL), NULL);
    SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
    SendMessage(hTool, TB_SETEXTENDEDSTYLE, 0, (LPARAM)TBSTYLE_EX_HIDECLIPPEDBUTTONS);

    tbab.hInst = HINST_COMMCTRL;
    tbab.nID = IDB_STD_SMALL_COLOR;
    SendMessage(hTool, TB_ADDBITMAP, 0, (LPARAM)&tbab);

    ZeroMemory(tbb, sizeof(tbb));
    tbb[0].iBitmap = STD_FILENEW;
    tbb[0].fsState = TBSTATE_ENABLED;
    tbb[0].fsStyle = TBSTYLE_BUTTON;
    tbb[0].idCommand = ID_FILE_NEW;

    tbb[1].iBitmap = STD_FILEOPEN;
    tbb[1].fsState = TBSTATE_ENABLED;
    tbb[1].fsStyle = TBSTYLE_BUTTON;
    tbb[1].idCommand = ID_FILE_OPEN;

    tbb[2].iBitmap = STD_FILESAVE;
    tbb[2].fsState = TBSTATE_ENABLED;
    tbb[2].fsStyle = TBSTYLE_BUTTON;
    tbb[2].idCommand = ID_FILE_SAVEAS;

    SendMessage(hTool, TB_SETBUTTONSIZE, (WPARAM)0, (LPARAM)MAKELONG(16, 16));
    SendMessage(hTool, TB_ADDBUTTONS, sizeof(tbb) / sizeof(TBBUTTON), (LPARAM)&tbb);
    SendMessage(hTool, TB_AUTOSIZE, 0, 0);
}

So, The Question Is: Despite the bitmaps of the buttons, how can I get 3D look and feel for the tool bar, just like the Notepad++/Notepad2 example?

Thanks in advance.

Arie Xiao
  • 13,909
  • 3
  • 31
  • 30
  • 1
    There's never any lack of toolbar choices. Notepad++ uses a Rebar control, SDK page [is here](http://msdn.microsoft.com/en-us/library/windows/desktop/bb774373%28v=vs.85%29.aspx). It doesn't look like you got the visual styles manifest right. – Hans Passant Jun 16 '13 at 16:07
  • 1
    @HansPassant The Rebar example on the SDK page showed a flat tool bar embedded in Rebar rather than the Notepad++ style. And the example on the "manifest" solution page showed the flat style, too. I wonder how Nodepad++ managed to make that tool bar style out of ToolBar/Rebar. – Arie Xiao Jun 16 '13 at 16:31
  • Well, Notepad++ is 'flat' on my machine and the screenshot you linked. Watch out for an old version, taste and Windows versions change rapidly. – Hans Passant Jun 16 '13 at 16:43
  • I can confirm Arie Shaw is right, default Win32 toolbar is same like image #1. And notepad2 -> image #3. – dns Jan 18 '14 at 20:20

1 Answers1

2

Create Toolbar first and then Rebar.

the rbBand.hbmBack must be set to NULL to get modern look toolbar, or remove RBBIM_BACKGROUND flag from the code below.

Here's how to create rebar:

HWND WINAPI CreateRebar (HWND hwndOwner)
{
    REBARINFO     rbi;
    REBARBANDINFO rbBand;
    RECT          rc;
    HWND   hwndCB, hwndRB;
    DWORD  dwBtnSize;

    hwndRB = CreateWindowExW(WS_EX_TOOLWINDOW,
        REBARCLASSNAME,
        NULL,
        WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
        WS_CLIPCHILDREN | RBS_VARHEIGHT |
        CCS_NODIVIDER,
        0, 0, 0, 0,
        hwndOwner,
        NULL,
        GetModuleHandleW(NULL),
        NULL);
    if (!hwndRB)
        return NULL;
    // Initialize and send the REBARINFO structure.
    rbi.cbSize = sizeof(REBARINFO);  // Required when using this
    // structure.
    rbi.fMask = 0;
    rbi.himl = (HIMAGELIST)NULL;
    if (!SendMessage(hwndRB, RB_SETBARINFO, 0, (LPARAM)&rbi))
        return NULL;
    // Initialize structure members that both bands will share.
    rbBand.cbSize = sizeof(REBARBANDINFO);  // Required
    rbBand.fMask = RBBIM_COLORS | RBBIM_TEXT | RBBIM_BACKGROUND |
        RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE |
        RBBIM_SIZE;
    rbBand.fStyle = RBBS_CHILDEDGE | RBBS_FIXEDBMP;
    rbBand.hbmBack = NULL;  //
    // Create the combo box control to be added.
    hwndCB = CreateWindowW(TEXT("COMBOBOX"), NULL,
        WS_CHILD | WS_VISIBLE | CBS_HASSTRINGS | CBS_DROPDOWNLIST,
        410, 20, 120, 110, (HWND) NULL, NULL, NULL, NULL);;
    // Set values unique to the band with the combo box.
    GetWindowRect(hwndCB, &rc);
    rbBand.lpText = "Combo Box";
    rbBand.hwndChild = hwndCB;
    rbBand.cxMinChild = 0;
    rbBand.cyMinChild = rc.bottom - rc.top;
    rbBand.cx = 200;

    // Add the band that has the combo box.
    SendMessage(hwndRB, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);


    // Get the height of the toolbar.
    dwBtnSize = SendMessage(toolbar1, TB_GETBUTTONSIZE, 0, 0);

    // Set values unique to the band with the toolbar.
    rbBand.lpText = "Tool Bar";
    rbBand.hwndChild = toolbar1;
    rbBand.cxMinChild = 0;
    rbBand.cyMinChild = HIWORD(dwBtnSize);
    rbBand.cx = 250;

    // Add the band that has the toolbar.
    SendMessage(hwndRB, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
    return (hwndRB);
}
dns
  • 2,753
  • 1
  • 26
  • 33
  • Ah, it worked, thanks. It's been a long time since I last touched the WINAPI. I'm still having problem that the toolbar doesn't show up until you have put the mouse to the icons. I'll investigate that later. – Arie Xiao Apr 20 '14 at 16:37