Can Delphi themed toolbars be shared between tool centers?

I noticed a rather annoying weirdness with the Delphi toolbars. I have a TToolbar that has logical icon groups. To highlight a group, I would like to use the separator buttons with the tbsDivider style.

When I do this, it looks like this:

enter image description here

Note the double vertical lines between each icon. The right hand is in the middle of the separator tool button. The left hand is on the left edge of the separator tool button.

So, I can switch to tbsSeparator , which removes the middle row:

enter image description here

But I'm not interested in this, as I would like the separator to be in the middle.

I looked at the old version of my real application and found that it centered the delimiters. This seems to be possible when Windows themes are disabled. Here's what it looks like with tbsDivider and the application manifest is removed:

enter image description here

This is the layout I'm looking for. Is this possible when topics are active?

I found a discussion of the problem on the Embarcadero forums, but there was no useful information: https://forums.embarcadero.com/message.jspa?messageID=467842

For completeness, here is the corresponding extract from the .dfm file

 object ToolButton1: TToolButton Left = 0 Top = 0 ImageIndex = 0 end object ToolButton2: TToolButton Left = 23 Top = 0 Width = 16 ImageIndex = 1 Style = tbsDivider end object ToolButton3: TToolButton Left = 39 Top = 0 ImageIndex = 1 end object ToolButton4: TToolButton Left = 62 Top = 0 Width = 16 ImageIndex = 2 Style = tbsDivider end object ToolButton5: TToolButton Left = 78 Top = 0 ImageIndex = 2 end 
+7
source share
3 answers

The native control draws a vertical line for the separator button when the toolbar has a flat style. Therefore, if you delete the flat style, you will be left alone with the VCL dividing line. You can safely remove the style when the application is thematic, the thematic toolbar buttons do not take into account the flat style (why the toolbar dividers, I have no idea). However, when the topics are disabled, there will again be two lines. In this case, keeping separators instead of separators seems to be the best option.

It could be assumed that disabling the Flat property would have some effect, as indicated in the documentation . However, TToolBar.CreateParams unconditionally enables it when StyleServices enabled. Therefore, an API call is needed;

 procedure TForm1.FormCreate(Sender: TObject); var TbStyle: DWORD; begin if StyleServices.Enabled then begin TbStyle := SendMessage(ToolBar1.Handle, TB_GETSTYLE, 0, 0); SendMessage(Toolbar1.Handle, TB_SETSTYLE, 0, TbStyle and not TBSTYLE_FLAT); end; end; 


This fixes part of the problem, and the rest, the dividing line, is not exactly in the center between the two buttons. The VCL problem here is that it does not want to draw a line. Therefore, it invokes the api theme, which draws a dividing line to the left of the separator. To get around, VCL goes around the right half of the separator rectangle to api, and the line drops in the middle. I don’t know if there is a way to say exactly where the topic api draws, and I doubt that there is.

+3
source

It looks like a VCL flaw for me. The tbsDivider style tbsDivider not map to an equivalent style in Win32. A tool button with this style is implemented in VCL in the same way as the tbsSeparator style, but with a custom drawing method. This is extracted from TToolButton.Paint :

 if Style = tbsDivider then with Canvas do begin R := Rect(Width div 2 - 1, 0, Width, Height); if StyleServices.Enabled then begin Details := StyleServices.GetElementDetails(ttbSeparatorNormal); StyleServices.DrawElement(Handle, Details, R); end else DrawEdge(Handle, R, EDGE_ETCHED, BF_LEFT) end; 

In the old days of pre-v6 comctl32, the tbsSeparator style tbsSeparator mapped to the Win32 style button TBSTYLE_SEP . And in pre-v6 comctl32, which displays just like space without vertical lines. VCL developers clearly wanted to do more and added tbsDivider with a custom picture above.

Go to v6 comctl32. The common control now draws a vertical line on the left edge of all TBSTYLE_SEP . So the code above just adds an extra vertical line in the middle of the separator.

We can try to get rid of the left vertical line from a tbsDivider by changing the code as follows:

 if Style = tbsDivider then with Canvas do begin if StyleServices.Enabled then begin //re-paint the background to remove the vertical line drawn //for the standard separator button R := Rect(0, 0, Width, Height); StyleServices.DrawParentBackground(FToolBar.Handle, Handle, nil, False, R); end; R := Rect(Width div 2 - 1, 0, Width, Height); if StyleServices.Enabled then begin Details := StyleServices.GetElementDetails(ttbSeparatorNormal); StyleServices.DrawElement(Handle, Details, R); end else DrawEdge(Handle, R, EDGE_ETCHED, BF_LEFT) end; 

However, this will not work because it flickers a lot when the left line is drawn and then drawn over.

I suspect that VCL designers simply overlooked this secret detail when switching to v6 comctl32.

I will send a quality control report in due time.

+4
source

As already explained, you cannot do this with TToolBar due to changes in the operating system.

However, using ActionToolBars, you can achieve what you want to achieve - even with the current version of Delphi (XE6) and Windows 8.1 / 2012 R2. Here are the steps:

  • Create Action Manager
  • Add as many actions as you intend to have
  • Add an ImageList (and one more extra for menu items)
  • Link each of your actions to an image
  • Add ActionToolBar to the form
  • Drag and drop each action you want to display on the toolbar to the toolbar
  • Set individual actions on the ShowCaption toolbar: = False (optional)
  • Drag and Drop to create delimiters (from the ActionManager) to add delimiters
  • Drag ActionClientItems (created by dragging and dropping actions onto an ActionTooLBar) to where you want.

The end result is a nice app with delimiters between your icons.

enter image description here

+3
source

All Articles