How do I display a transparent custom bitmap on a toolbar button in a Win32 C++ app?

DaveF 21 Reputation points
2022-02-26T01:00:40.19+00:00

I'm trying to add a button with a custom transparent bitmap to a toolbar in my Win32 C++ app. I'm using the following code to create and populate the toolbar.

toolBar = CreateWindowEx(0, TOOLBARCLASSNAME, nullptr, WS_CHILD, 0, 0, 0, 0, hwnd, nullptr, appInstance, nullptr);  
SendMessage(toolBar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);  
SendMessage(toolBar, TB_SETBITMAPSIZE, 0, MAKELPARAM(24, 24));  
const auto bgColor = GetSysColor(COLOR_BTNFACE);  
COLORMAP colorMap{};  
colorMap.from = RGB(255, 255, 255);  
colorMap.to = bgColor;  
mappedBitmap = CreateMappedBitmap(appInstance, IDB_NEW, 0, &colorMap, 1);  
TBADDBITMAP tbAddBitmap{ nullptr, reinterpret_cast<UINT_PTR>(mappedBitmap) };  
SendMessage(toolBar, TB_ADDBITMAP, 1, reinterpret_cast<LPARAM>(&tbAddBitmap));  
TBBUTTON buttons[1] =  
{  
	{0, 1000, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, 0}  
};  
SendMessage(toolBar, TB_ADDBUTTONS, 1, reinterpret_cast<LPARAM>(&buttons));  
SendMessage(toolBar, TB_AUTOSIZE, 0, 0);  
ShowWindow(toolBar, TRUE);  

When this code executes, the image appears, but without a transparent background as seen in the following screenshot.

177947-image.png

According to the resource editor, the bitmap I'm trying to map has 8-bit color, which means no more than 256 colors. According to the documentation for the "CreateMappedBitmap()" function, it will work on images with 256 or fewer colors. Why is it not working for me?

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,492 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,608 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Ruth Haephrati 10 Reputation points
    2024-06-03T00:16:13.9233333+00:00

    You can see an example of an MFC custom control for displaying a PNG image with transparency in this article by Michael Haephrati.

    2 people found this answer helpful.
    0 comments No comments

  2. Castorix31 82,751 Reputation points
    2022-02-26T07:42:55.337+00:00

    The usual way is with a masked ImageList

    For example with this bitmap with magenta for transparent color : 178009-toolbar.jpg

    by replacing TB_ADDBITMAP
    by :

     HIMAGELIST hImageList = ImageList_Create(32, 32, ILC_MASK | ILC_COLORDDB, 1, 1);  
     ImageList_AddMasked(hImageList, mappedBitmap, RGB(255, 0, 255));  
     SendMessage(toolBar, TB_SETIMAGELIST, 0, (LPARAM)hImageList);  
    

    I get, for 1 Button :

    178072-toolbar-1button.jpg

    1 person found this answer helpful.
    0 comments No comments

  3. RLWA32 42,366 Reputation points
    2022-02-26T10:02:07.537+00:00

    You may not be using the correct color to map the bitmap background. I created a bitmap with a black background that looked like this in the resource editor -
    178044-bitmap.png

    Then using your posted code -

    	const auto bgColor = GetSysColor(COLOR_BTNFACE);  
    	COLORMAP colorMap{};  
    	colorMap.from = RGB(0, 0, 0);  
    	colorMap.to = bgColor;  
      
    

    And the results -

    178081-win32tbar.png

    1 person found this answer helpful.
    0 comments No comments