TToolBar’s TToolButton AutoSize Width Issues (Empty Captions)

tlbr5If you are using the TToolBar control with TToolButtons in your Delphi application (are you not?, in at least one :\) with “Enable runtime themes” enabled for your project, you might have noticed you cannot easily alter the width of an individual button. What’s worst, if you are using button images and for some of the buttons you want the Caption to be displayed and for some not – the empty-caption tool bar buttons will have a too long width.

Is there a way to fix the width of the no-caption buttons so they “match” the width of the bitmap/glyph/image? For a long time I thought there’s no way to fix this, as whatever property I would change, the display, at run time, simply did not look right. Until I’ve found (as you will see: a very) simple solution.

Typically I would have a TImageList filled with button images assigned to the Images property of the Toolbar – so that each button has a nice image – similar to what we have in the Delphi IDE. I would have a few tool buttons added to the toolbar. Leaving all the default properties as they are by default, the display will look like this:

tlbr1

Now, I would really love to have only some buttons display their caption. For this to happen I need to set the ShowCaptions property and also the List property:

  ToolBar2.ShowCaptions := true;
  ToolBar2.List := true;

And the display is as:

tlbr2

Note: the List property determines if the caption of the button appears below the button image or right to it.

Ok, so I now simply set an empty caption to all buttons except the “Insert” one (this is the one I want to have the Caption displayed – others not) – and case closed.

tlbr3

Uops, this is not what I want to be displayed – I would want all buttons to have much shorter width, enough to have only their image displayed (if their Caption is empty)!

Setting the AutoSize property of each TToolButton to True would probably do the trick, and the result is:

tlbr4

Hm, not good. All buttons have an empty Caption (except the “Insert” one) but there’s some extra space right to the image – buttons are too wide for no real purpose (my visual feeling).

At this moment you (and I) would start thinking “why not simply set the Width property of each button”? Ha! This would not work as Delphi’s internal implementation of this standard Windows control determines button width automagically – even if you try to change the Width property of a button – it will stick to its value. The “why” for this would require explaining how the Windows tool bar control works with its messaging and the rest – never mind at this point – you simply cannot set “by hand” the width of each button separately.

So, how to fix this? How to have smaller width for those buttons that are “captionless”? Here’s how:

  1. Set Autosize to False for all no-caption buttons.
  2. Set Autosize to True for the buttons you want the Caption to be displayed
  3. Call the following inside Form’s OnCreate event
//tbtnInsert3.AutoSize := true;
SendMessage(ToolBar3.Handle, TB_SETBUTTONWIDTH, 0, MAKELPARAM(0, 24));
  1. Make sure you do not alter the Visible property of any buttons before the above call – as it will fail for those buttons that are not visible.
  2. Also, ensure you have “CommCtrl” in the uses list for TB_SETBUTTONWIDTH message.

That’s it, now my toolbar displays correctly:

tlbr5

No extra space to the right of the button image for those buttons with no Caption.

Case closed.

p.s.
The weird “24”, for button width, in a call to TB_SETBUTTONWIDTH was a try-fail approach. In my real word application I’m setting this value to the value of the Width of another toolbar button (where all buttons do not have a caption). The actual required value depends on the Windows version, Windows theme, if themes are enabled and so on – so it’s best determined at run time by “looking” at other toolbar buttons.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.