The MASM Forum

General => The Workshop => Windows API => Topic started by: NoCforMe on March 26, 2025, 11:23:55 AM

Title: Dynamically changing toolbar button images
Post by: NoCforMe on March 26, 2025, 11:23:55 AM
I just figured out how to do this: change a toolbar button image dynamically.
Not too hard to do, using the standard TB_xxxx messages.

Here's the recipe:

1. Set up the toolbar as usual (see the sub-recipe below).
2. Load the bitmap for the alternate button image.
3. Use TB_ADDBITMAP to add the alternate image to the image list (be sure to store its image index).
4. Get the image index for the button in the toolbar whose image you want to change, using TB_GETBUTTONINFO. Be sure to store its image index as well.

In this demo the third button changes when you click on it.
To change a button's image, send the TB_CHANGEBITMAP message with the image index of the image you want to show. It's that simple!

Notes:
There are two numbers associated with each button in a toolbar:
o The command ID is the ID you associate with a button (using the TB_ADDBUTTONS message, where the command IDs are in the TBBUTTON structure passed in the message);
o The image index of the button's image, which is the zero-based index into the image list that Windows creates for the toolbar. The index #s don't change; new images are added to the end of the list. And when you create a toolbar from a bitmap that contains multiple buttons (as the 5 here), each button image becomes a separate image in the image list, identified by its image index. So the toolbar bitmap contains images 0 through 4.

You need both of these numbers to change the image. The image index doesn't change: in my demo program, there are 5 toolbar buttons, plus the "new" button image (the alternate image), so the image indices are

0, 1, 2, 3, 4, 5

with 5 being the "new" (alternate) one.

What the demo does is swap images 2 and 5 for the 3rd button, using TB_CHANGEBITMAP. In other words, for command ID 2, it shows either image index 2 or 5. Or to put it another way, this message assigns a different image (using its image index) to a certain button using its command ID.

Here's my recipe for setting up the toolbar in the first place:

1. Create the toolbar window using CreateWindowEx().
2. Set the size of the TBUTTON structure using TB_BUTTONSTRUCTSIZE.
3. Set the size of the bitmap (width & height) using TB_SETBITMAPSIZE.
4. Add the bitmap to the toolbar using TB_ADDBITMAP. (But see note below.)
5. Create the buttons in the toolbar using TB_ADDBUTTONS, passing an array of TBBUTTON structures which contain the button command IDs and other info.
6. Set the button size using TB_SETBUTTONSIZE.
7. Set up tooltips using TB_SETEXTENDEDSTYLE. NOTE: You should do this even if you don't use tooltips (the little text cues that pop up when you mouse over the toolbar buttons), since the toolbar will be slightly malformed if you don't. You can simply omit the tooltip text (in the TBBUTTON structure as I've done in this demo) and it'll work fine.

Note on loading bitmaps:
There are at least 3 ways to load bitmaps into a toolbar:
1. Create separate BMPs and load each separately in your code.
2. Load all the BMPs using a resource file with the resource editor, accessing them by their resource ID.

I've chosen to use a third method which I prefer. I don't deal with BMP files at all, at least not directly. What I do is convert all my bitmaps to data (DB statements) in include files, using Hutch's handy-dandy bin2db utility that's part of the MASM package. (See the two files in the .zip.)

Then I use a little routine in my code, GetBMPdata(), to "load" the bitmap from that data and give me a handle to the bitmap. (Thanks again to "fearless" of this forum for providing that trick.) I do this because I'm not a big fan of using resource files and the resource compiler.

Of course, you can load the bitmaps however you choose, and all this will work just fine.
Title: Re: Dynamically changing toolbar button images
Post by: zedd151 on March 26, 2025, 03:16:46 PM
Seems to work as expected, and  without any issues.  :thumbsup:

But why would anyone need to change toolbar buttons dynamically? That part I don't understand. At least I cannot think of any reasons to do that.
Title: Re: Dynamically changing toolbar button images
Post by: NoCforMe on March 26, 2025, 03:50:19 PM
Quote from: zedd151 on March 26, 2025, 03:16:46 PMSeems to work as expected, and  without any issues.  :thumbsup:

But why would anyone need to change toolbar buttons dynamically? That part I don't understand. At least I cannot think of any reasons to do that.

My reason for doing this is to have a toolbar button that acts as a toggle between two states, enabled and disabled.
This eliminates the need for a separate indicator of what state the button is in.
Try the attached demo to see what I mean; click the 3rd button.
You can see the two images are the same except for the "X" over the "disabled" one.
Title: Re: Dynamically changing toolbar button images
Post by: zedd151 on March 26, 2025, 03:57:37 PM
Ok. That makes sense, I hadn't thought about that.  :biggrin:
I'll look at that last attachment when I get back inside.
Title: Re: Dynamically changing toolbar button images
Post by: guga on March 26, 2025, 04:11:51 PM
Tks, NoCForme.

Good work.  :thumbsup:  :thumbsup:

The simplified version of GetBMPdata from fearless is really good.
Title: Re: Dynamically changing toolbar button images
Post by: guga on March 26, 2025, 04:23:41 PM
Quote from: zedd151 on March 26, 2025, 03:16:46 PMSeems to work as expected, and  without any issues.  :thumbsup:

But why would anyone need to change toolbar buttons dynamically? That part I don't understand. At least I cannot think of any reasons to do that.

It´s needed to change the state of the buttons. I gave a try with something similar years ago when i was trying to fix old bugs in RosAsm. His version of loading the image to the buttons seems easier and way less complicated. I´ll give a try on his technique once i succeed to fix a couple of more things in RosAsm before starting to change the appearance of the interface as i did here:

(https://i.postimg.cc/p9bMzQ5v/Clipboard-03-26-2025-01.png) (https://postimg.cc/p9bMzQ5v)
Title: Re: Dynamically changing toolbar button images
Post by: zedd151 on March 26, 2025, 04:33:37 PM
Quote from: NoCforMe on March 26, 2025, 03:50:19 PMTry the attached demo to see what I mean; click the 3rd button.
You can see the two images are the same except for the "X" over the "disabled" one.
Works as advertised... Now I C.
Title: Re: Dynamically changing toolbar button images
Post by: TimoVJL on March 26, 2025, 08:32:22 PM
So more visible than with TB_ENABLEBUTTON message ?
Title: Re: Dynamically changing toolbar button images
Post by: jj2007 on March 26, 2025, 10:16:23 PM
Quote from: NoCforMe on March 26, 2025, 03:50:19 PMTry the attached demo

Works fine :thumbsup:
Title: Re: Dynamically changing toolbar button images
Post by: zedd151 on March 26, 2025, 11:17:33 PM
Quote from: TimoVJL on March 26, 2025, 08:32:22 PMSo more visible than with TB_ENABLEBUTTON message ?
Just as visible I would imagine.  :biggrin:

Do you not like NoCforMe's approach? It works...

Quite possible that he did not know about TB_ENABLEBUTTON (I didn't, or if I had known, I had forgotten),  or he simply wanted to experiment with the 'dynamic button image' approach?

That's the fun of experimenting. There are frequently several different ways to achieve the same desired outcome.
We don't always have to follow the prescribed 'norms'.  :cool:

I prefer 'outside the box' thinking in certain instances.

Title: Re: Dynamically changing toolbar button images
Post by: TimoVJL on March 27, 2025, 02:36:11 AM
OK, there is different idea for button bitmaps, that can change bitmap during usage.
Like operational cycles / phases, when button purpose varies.
Title: Re: Dynamically changing toolbar button images
Post by: NoCforMe on March 27, 2025, 11:27:36 AM
Quote from: TimoVJL on March 26, 2025, 08:32:22 PMSo more visible than with TB_ENABLEBUTTON message ?
That message has a completely different purpose from mine:
It simply enables or disables an existing button, without changing the button's bitmap image. (Well, it'll gray the button out if it's disabled.)
Mine actually substitutes a different bitmap image.
So not the same thing at all.
Title: Re: Dynamically changing toolbar button images
Post by: NoCforMe on March 27, 2025, 11:29:50 AM
Quote from: TimoVJL on March 27, 2025, 02:36:11 AMOK, there is different idea for button bitmaps, that can change bitmap during usage.
Like operational cycles / phases, when button purpose varies.

Yes, exactly.
Which brings up a caveat for this usage:
When you start changing button images, you now have a "modal" application, meaning that the appearance or functionality changes depending on which "mode" it's in.
Which can be a really bad thing (for the user), so it needs to be carefully considered before implementing it.
Title: Re: Dynamically changing toolbar button images
Post by: zedd151 on March 27, 2025, 12:04:43 PM
Quote from: NoCforMe on March 27, 2025, 11:27:36 AM
Quote from: TimoVJL on March 26, 2025, 08:32:22 PMSo more visible than with TB_ENABLEBUTTON message ?
That message has a completely different purpose from mine:
It simply enables or disables an existing button, without changing the button's bitmap image. (Well, it'll gray the button out if it's disabled.)
Mine actually substitutes a different bitmap image.
So not the same thing at all.
Lol.
I missed the point entirely.  :biggrin:

You want a certain function disabled or changed, and use the button image to display the state of the function. Enabled or disabled, (or other?)

Now if the button itself was disabled once used, along with disabling the function...
How would one re-enable the function.  :joking:

That is what I get for making a reply before my morning coffee.  :mrgreen:
Title: Re: Dynamically changing toolbar button images
Post by: NoCforMe on March 27, 2025, 12:13:40 PM
Quote from: zedd151 on March 27, 2025, 12:04:43 PMYou want a certain function disabled or changed, and use the button image to display the state of the function. Enabled or disabled, (or other?)

Now if the button itself was disabled once used, along with disabling the function...
How would one re-enable the function.  :joking:

Wellll, in that case you'd be navigating that proverbial body of water known as Schitt's Creek ...

So of course you'd never use TB_ENABLEBUTTON here. Unless you really wanted to mess with the poor user.
Title: Re: Dynamically changing toolbar button images
Post by: zedd151 on March 27, 2025, 12:25:57 PM
Sounded reasonable at the time. (No coffee yet for me, at that point)