NO

Author Topic: Toolbar dropdown buttons  (Read 1086 times)

Offline CFred

  • Member
  • *
  • Posts: 36
Toolbar dropdown buttons
« on: July 20, 2023, 12:34:40 PM »
I am creating a toolbar with the TBSTYLE_EX_DRAWDDARROWS style so that I can use a drop down button.

I have a function AddButtonToToolbar() that adds a dropdown button to the toolbar.

Code: [Select]
void AddButtonToToolbar(HWND hToolbar, int bitmapId){
int btnIndex;
TBADDBITMAP tbab;
TBBUTTON tbButton;

tbab.hInst = NULL;
    tbab.nID = (UINT_PTR)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(bitmapId),
IMAGE_BITMAP, 0, 0,
LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT);

    btnIndex = (int)SendMessage(hToolbar, TB_ADDBITMAP, 8, (LPARAM)&tbab);

tbButton.iBitmap = btnIndex;
tbButton.idCommand = bitmapId;
tbButton.fsState = TBSTATE_ENABLED;
tbButton.fsStyle = BTNS_DROPDOWN;
tbButton.dwData = 0L;
tbButton.iString = (INT_PTR) ""; //Set empty string to prevent toolbar from expanding!

// Add the button to the end of the toolbar
SendMessage(hToolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbButton);

//Ensures toolbar recalculates its size based on its content
SendMessage(hToolbar, TB_AUTOSIZE, 0, 0);
}

If, after creating the toolbar, I do not include the statements:

Code: [Select]
DWORD exstyle = (int)SendMessage(hwndToolbar, TB_GETEXTENDEDSTYLE,0,0);
SendMessage(hwndToolbar, TB_SETEXTENDEDSTYLE, 0, exstyle | TBSTYLE_EX_DRAWDDARROWS);
   

then when I call the function AddButtonToToolbar(...) the drop down arrow is not shown although the button is displayed.

1. As I included the TBSTYLE_EX_DRAWDDARROWS style when I created the toolbar, why do I need to include these two lines of code?

2. If I change the button style to BTNS_WHOLEDROPDOWN in the function AddButtonToToolbar() then all the buttons become more widely spaced out. How can I prevent this from happening?

Offline John Z

  • Member
  • *
  • Posts: 796
Re: Toolbar dropdown buttons
« Reply #1 on: July 20, 2023, 10:44:49 PM »

1. As I included the TBSTYLE_EX_DRAWDDARROWS style when I created the toolbar, why do I need to include these two lines of code?

Since I don't see the code you used to create the toolbar I assume you used the control resource editor in Pelles C to add a toolbar control?  I think the resource control method does not support extended styles, even if you edit the resource file as text.  So the message must be sent directly, in my experience.

2. If I change the button style to BTNS_WHOLEDROPDOWN in the function AddButtonToToolbar() then all the buttons become more widely spaced out. How can I prevent this from happening?
Don't use it  :D :)  (well true, but otherwise I don't know)

[Not getting exactly what you want is often the result of using higher level abstractions, ultimately you can only get whatever control features (for example) that the developer thought were important, or thought of at all.The higher the abstraction the less work you have but also less uniqueness, less ability to make it look/work how you want and not the originator wanted it to look/work. ]

John Z

Offline CFred

  • Member
  • *
  • Posts: 36
Re: Toolbar dropdown buttons
« Reply #2 on: July 21, 2023, 12:27:09 PM »
@John Z: I used the following code to create the toolbar instead of the resource editor:

Code: [Select]
hwndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | TBSTYLE_EX_DRAWDDARROWS, 0, 0, 0, 0,
        hparent, (HMENU)IDC_MAIN_TOOL, GetModuleHandle(NULL), NULL);

This was shown in the file attached to the first post in this thread.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Toolbar dropdown buttons
« Reply #3 on: July 21, 2023, 02:35:29 PM »
If, after creating the toolbar, I do not include the statements:

Code: [Select]
DWORD exstyle = (int)SendMessage(hwndToolbar, TB_GETEXTENDEDSTYLE,0,0);
SendMessage(hwndToolbar, TB_SETEXTENDEDSTYLE, 0, exstyle | TBSTYLE_EX_DRAWDDARROWS);
   

then when I call the function AddButtonToToolbar(...) the drop down arrow is not shown although the button is displayed.

1. As I included the TBSTYLE_EX_DRAWDDARROWS style when I created the toolbar, why do I need to include these two lines of code?
Because you don't have to use TBSTYLE_EX_DRAWDDARROWS in CreateWindowEx().
TBSTYLE_EX_DRAWDDARROWS is an extended control style, not an extended window style.
In your code nothing bad happens because no window style is defined with same numerical value of TBSTYLE_EX_DRAWDDARROWS. If case of conflict you should see an undesired style of the window.
WINAPI include the 2 messages TB_GETEXTENDEDSTYLE and TB_SETEXTENDEDSTYLE to allow settings of toolbar extended styles, that could be set per each button in the toolbar.
In a CreateWindowEx() call, you are allowed to set only control ordinarily styles, not extended ones.

2. If I change the button style to BTNS_WHOLEDROPDOWN in the function AddButtonToToolbar() then all the buttons become more widely spaced out. How can I prevent this from happening?
Not clear what you mean.
All buttons get the associated drop-down arrow that enlarge the button, exactly as the TBSTYLE_EX_DRAWDDARROWS does.

Quote from: MS
BTNS_WHOLEDROPDOWN
Version 5.80. Specifies that the button will have a drop-down arrow, but not as a separate section. Buttons with this style behave the same, regardless of whether the TBSTYLE_EX_DRAWDDARROWS extended style is set.
« Last Edit: July 22, 2023, 03:28:02 PM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline CFred

  • Member
  • *
  • Posts: 36
Re: Toolbar dropdown buttons
« Reply #4 on: July 21, 2023, 08:02:19 PM »
@frankie:

Thanks for explaining that I don't have to use TBSTYLE_EX_DRAWDDARROWS in CreateWindowEx(). It's difficult to find this sort of information easily.

Quote
Quote from: CFred on Yesterday at 12:34:40 PM

    2. If I change the button style to BTNS_WHOLEDROPDOWN in the function AddButtonToToolbar() then all the buttons become more widely spaced out. How can I prevent this from happening?

Not clear what you mean.

What I meant is that the toolbar buttons are normally spaced a reasonable distance apart when they have the normal style applied to them. But when I use the style BTNS_WHOLEDROPDOWN for one dropdown button  all the buttons have a much larger space between them.


Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Toolbar dropdown buttons
« Reply #5 on: July 21, 2023, 11:55:46 PM »
What I meant is that the toolbar buttons are normally spaced a reasonable distance apart when they have the normal style applied to them. But when I use the style BTNS_WHOLEDROPDOWN for one dropdown button  all the buttons have a much larger space between them.
You use BTNS_WHOLEDROPDOWN when adding the dropdown button in the function AddButtonToToolbar().
If you use BTNS_WHOLEDROPDOWN in buttons array loading the problem is not present:
Code: [Select]
TBBUTTON tbButtons[] =        // Toolbar buttons.
    {
        {STD_FILENEW, mnuFileNew, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
        {STD_FILEOPEN, mnuFileOpen, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
        {STD_FILESAVE, mnuFileSave, TBSTATE_ENABLED, /*BTNS_BUTTON |*/ BTNS_WHOLEDROPDOWN, {0}, 0, 0}    //Adding here no problem happen
    };

SendMessage(hwndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
    SendMessage(hwndToolbar, TB_ADDBUTTONS, sizeof(tbButtons) / sizeof(TBBUTTON), (LPARAM)&tbButtons);

So the problem is what is different in the function AddButtonToToolbar().
The line:
Code: [Select]
tbButton.iString = (INT_PTR) "";  //Set empty string to prevent toolbar from expanding!
Changed in:
Code: [Select]
tbButton.iString = 0;Fix the problem.
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline CFred

  • Member
  • *
  • Posts: 36
Re: Toolbar dropdown buttons
« Reply #6 on: July 22, 2023, 10:23:16 AM »
@frankie:

Thanks for solving my problem.

Offline John Z

  • Member
  • *
  • Posts: 796
Re: Toolbar dropdown buttons
« Reply #7 on: July 25, 2023, 11:20:52 PM »
Hi CFred,

As alternative to the excellent advise from our super expert frankie here:

So the problem is what is different in the function AddButtonToToolbar().
The line:
Code: [Select]
tbButton.iString = (INT_PTR) "";  //Set empty string to prevent toolbar from expanding!
Changed in:
Code: [Select]
tbButton.iString = 0;Fix the problem.

You could also have used a not better but different method -
Code: [Select]
tbButton.iString = (INT_PTR) "\0"; //Set empty string to prevent toolbar from expanding!to fix the problem.

John Z

Offline CFred

  • Member
  • *
  • Posts: 36
Re: Toolbar dropdown buttons
« Reply #8 on: July 26, 2023, 12:48:18 PM »
@John Z: Thanks for this information. I now see that I should not have used an empty string in my code - I should have included the null terminator in it.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Toolbar dropdown buttons
« Reply #9 on: July 26, 2023, 02:16:52 PM »
You could also have used a not better but different method -
Code: [Select]
tbButton.iString = (INT_PTR) "\0"; //Set empty string to prevent toolbar from expanding!to fix the problem.
Don't work because assigning an empty string means to assign a pointer to a memory address containing only the ending '\0' character of the string (the empty string).
Assigning a string like "\0" will point to a memory containing the null character and the string ending null.
Nothing will change for the control.
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline John Z

  • Member
  • *
  • Posts: 796
Re: Toolbar dropdown buttons
« Reply #10 on: July 26, 2023, 10:48:59 PM »
Hi frankie,

Well I guess these (very) old eyes must be fooling me because it looks like it worked on my system.
Screen shot attached below showing both techniques......

As you are usually right, so maybe I'm misunderstanding what is supposed to change? 
My logic was all strings are NULL terminated so an empty string is just the NULL character.....
so I explicitly created it.

Both toolbars look the same to me.   If you have the time and inclination....

John Z


Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Toolbar dropdown buttons
« Reply #11 on: July 26, 2023, 11:05:06 PM »
Hi frankie,

Well I guess these (very) old eyes must be fooling me because it looks like it worked on my system.
Screen shot attached below showing both techniques......
Dear John, my eyes are old more or less like yours...  :)
Anyway the sample from CFred are always a little bit messy, and not configured ready to show the problem. I attach the project with proper flags for the tbButton.fsStyle in the function AddButtonToToolbar() so you can compile and test the different configurations.
Note that if you use:
Code: [Select]
tbButton.fsStyle = BTNS_DROPDOWN;It will work with any string setting (even "\0"), but if you use:
Code: [Select]
tbButton.fsStyle = BTNS_WHOLEDROPDOWN;You will see the difference.  ;)
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline John Z

  • Member
  • *
  • Posts: 796
Re: Toolbar dropdown buttons
« Reply #12 on: July 26, 2023, 11:20:27 PM »
 :)  Thanks frankie - I didn't look at the rest!

Appreciate the test file too!

John Z