Menu

toolbars with individual bitmap buttons

Help
2014-09-03
2014-09-08
  • Robert Tausworthe

    I cannot figure out how to develop a toolbar in Win32++ comprised of individual bitmap buttons that are defined by individual bitmap files, all of the same dimensions, say 24 x 24. I can do it using the WinApi directly, but I can't do it in Win32++. No IDW_MAIN toolbar.bmp is to be used. Any help would be appreciated. I just need to know the CFrame and/or CToolBar functions to use and in what order. I can probably figure out the rest.

    My WinApi version is attached, below for reference.

    /============================================================================/
    void MyFrame::
    CreateToolBar(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) /*

         Create the main window's toolbar.
    

    /----------------------------------------------------------------------------/
    {
    // Clear any error code
    SetLastError(ERROR_SUCCESS);

        m_toolbar_hwnd = CreateWindowEx
            (
                0,
                TOOLBARCLASSNAME,
                NULL,
                WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
                    | WS_CLIPSIBLINGS | WS_DLGFRAME
                    | TBSTYLE_TOOLTIPS,
                0,
                0,
                0,
                0,
                hWnd,
                (HMENU)IDC_MAIN_TOOLBAR,
                m_hInstance, // i.e., GetModuleHandle(NULL),
                NULL
            );
        if(m_toolbar_hwnd == NULL)
            ErrorMsgBox(TEXT("Could not create tool bar."));
    
          // Send the TB_BUTTONSTRUCTSIZE message, which is required for
          // backward compatibility.
        SendMessage(m_toolbar_hwnd, TB_BUTTONSTRUCTSIZE,
            (WPARAM)sizeof(TBBUTTON), 0);
    
          // Load font selection bitmap into image list from resource setting
          // top-left pixel as transparent colour
        HIMAGELIST hImageList = ::ImageList_LoadImage(m_hInstance,
            MAKEINTRESOURCE(IDB_FONT_BMP), 24, 20, CLR_DEFAULT, IMAGE_BITMAP,
            LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_SHARED |
            LR_LOADTRANSPARENT);
        if(NULL == hImageList)
            ErrorMsgBox(TEXT("Could not add image to tool bar."));
    
          // add the color selection bitmap to the image list
        ImageList_Add(hImageList, LoadBitmap(m_hInstance,
            MAKEINTRESOURCE(IDB_COLOR_BMP)), NULL);
        if(NULL == hImageList)
            ErrorMsgBox(TEXT("Could not add image to tool bar."));
    
          // register this image list with the toolbar
        HIMAGELIST hOld = (HIMAGELIST)SendMessage(m_toolbar_hwnd,
            TB_SETIMAGELIST, 0, (LPARAM)hImageList);
    
          // the deprecated CreateToolbar function automatically sends the
          // following, but CreateWindowEx, as used above, does not
        SendMessage(m_toolbar_hwnd, TB_BUTTONSTRUCTSIZE,
            (WPARAM)sizeof(TBBUTTON), 0);
    
          // sending the following ensures the iString's of TBBUTTON structs
          // become tooltips rather than button text
        int iMaxRows = 0;
        SendMessage(m_toolbar_hwnd, TB_SETMAXTEXTROWS, iMaxRows, 0);
    
          // now load the common controls images after the others above into
          // the registered image list
        DWORD dwCountImages = SendMessage(m_toolbar_hwnd, TB_LOADIMAGES,
            (WPARAM)IDB_STD_LARGE_COLOR,(LPARAM)HINST_COMMCTRL);
        if(0 == dwCountImages)
            ErrorMsgBox(TEXT("Could not load common toolbar image list."));
    
          // populate the array of buttons structures defining bitmap,
          // initial state, button type, command ID, and tooltip
        TBBUTTON tbb[nButtons];
        ZeroMemory(tbb, nButtons * sizeof(TBBUTTON));
    
        int btn = 0;  // button index (counter)
        ZeroMemory(tbb, sizeof(tbb));
    
           // start out with a separator just to give some space at the
           // left of the toolbar
        tbb[btn].iBitmap = 0;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = BTNS_SEP;
        tbb[btn].idCommand = 0;      // Sent in WM_COMMAND when pressed 
        tbb[btn++].iString = 0;
    
          // here are all the common control buttons and their images
        tbb[btn].iBitmap = dwCountImages + STD_FILENEW; // standard bitmap
        tbb[btn].fsState = TBSTATE_ENABLED;  // accept user activation
        tbb[btn].fsStyle = BTNS_BUTTON;   // standard pushbutton
        tbb[btn].idCommand = ID_FILE_NEW;    // message sent on click
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("New file\0"));  // tool tip or button text
    
        tbb[btn].iBitmap = dwCountImages + STD_FILEOPEN;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_FILE_OPEN;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd,
            TB_ADDSTRING, 0, (LPARAM)TEXT("Open file\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_FILESAVE;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_FILE_SAVEAS;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Save file\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_PROPERTIES;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_PROPERTIES;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Properties\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_CUT;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_CUT;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0,
            (LPARAM)TEXT("Cut\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_COPY;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_COPY;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Copy\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_PASTE;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_PASTE;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Paste\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_DELETE;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_DELETE;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Delete\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_UNDO;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_UNDO;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Undo\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_REDOW;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_REDO;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Redo\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_FIND;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_FIND;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Find\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_REPLACE;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_REPLACE;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Replace\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_PRINTPRE;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_PRINT_PREVIEW;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Preview\0"));
    
        tbb[btn].iBitmap = dwCountImages + STD_PRINT;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_PRINT;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0,(LPARAM)TEXT("Print\0"));
    
          // here are the specially added buttons and their images, set
          // apart by using a little separation
        tbb[btn].iBitmap = 0;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = BTNS_SEP;
        tbb[btn].idCommand = 0;      // Sent in WM_COMMAND when pressed 
        tbb[btn++].iString = 0;
    
        tbb[btn].iBitmap = 0;
        tbb[btn].fsState = TBSTATE_ENABLED;  // accept user activation
        tbb[btn].fsStyle = BTNS_BUTTON;   // standard pushbutton
        tbb[btn].idCommand = ID_FONT_CHOICE;    // message sent on click
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
            0, (LPARAM)TEXT("Choose font\0"));  // tool tip or button text
    
        tbb[btn].iBitmap = 1;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = BTNS_BUTTON;
        tbb[btn].idCommand = ID_COLOR_CHOICE;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd,
            TB_ADDSTRING, 0, (LPARAM)TEXT("Choose background color\0"));
    
        tbb[btn].iBitmap = 0;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = BTNS_SEP;
        tbb[btn].idCommand = 0;       // Sent in WM_COMMAND when pressed
        tbb[btn++].iString = 0;
    
          // finally, add in the HELP button
        tbb[btn].iBitmap = dwCountImages + STD_HELP;
        tbb[btn].fsState = TBSTATE_ENABLED;
        tbb[btn].fsStyle = TBSTYLE_BUTTON;
        tbb[btn].idCommand = ID_HELP;
        tbb[btn++].iString = SendMessage(m_toolbar_hwnd, TB_ADDSTRING,
           0, (LPARAM)TEXT("Help\0"));
    
          // add all the buttons to the toolbar
        SendMessage(m_toolbar_hwnd, TB_ADDBUTTONS, btn, (LPARAM)&tbb);
    

    }

     
  • David

    David - 2014-09-08

    Hi Robert,

    Toolbars use image lists for the images displayed on Toolbar buttons. If you have a set of individual bitmaps for your toolbar buttons, you can build an image list from those and then assign it to the toolbar before adding the buttons. Toolbars can have up to 3 image list assigned, one for normal buttons, one for hot buttons and one for disabled buttons.

    Steps:
    - Add a CImageList member variable to CMainFrame
    - Create the image list with the desired width, height (with CImageList::Create)
    - Add the individual bitmaps to the image list (with CImageList.Add)
    - Assign the image list to your toolbar (with CToolbar::SetImageList)
    - Add the toolbar buttons.

    When we add a toolbar button to the toolbar we specify the image's index. An index of 0 is the first image in the image list.

    Note that we can build the image list from icons or bitmaps. Icons can be simpler to work with as we don't need to concern ourselves with bitmap masks.

    Please get back to me if you need an example on how to code this.

    Best regards,
    David

     

Log in to post a comment.