5
votes

I'd like to highlight my toolbar icons when their associated action has it's "checked" property set to true. I'd like to do it in a manner similar to how Microsoft Office 2003 did it, e.g. see the Bold and Align Left icons in this image:

Toolbar example

The image is drawn with a box around it and the background has been changed to orange.

How could I implement this using Delphi 2009?

As a bonus, is there also a way to do the same thing with the icon in the menu for the associated item? e.g. as below with the Ruler and Markup entries:

Menu example


Followup:

Thank you Andreas, for what is a simple and correct answer to my question. As a Delphi 4 programmer converted to Delphi 2009, I was not familiar enough with the VCL additions of Delphi 5 to 7, so the TActionManager, TActionToolbar and their workings were not in my Delphi vocabulary. And this is based on Delphi's ability to use a style that is akin to a Microsoft O/S's theme.

However, with your answer, and a bit of research using it, I confirm that I do not want to do this in this manner. An illuminating Embarcadero thread re: Popup menus: "Checked" items with icon no longer shown as sunken? with Peter Below contributing his expertise, made me realize that I don't want to change to the XP theme at all, since that will do baaaaad things to Vista and Windows 7 users, taking them back to the Bronze Age.

The true culprit here is that there are certain things that the O/S themes want you to respect. Delphi tries to follow the rules. I can go back to XP, the XP style/theme, and the XP Color Map. In this mode, checked items will be hilighted. And this is really all I wanted - to highlight the checked items. I used Office 2003 as an example, because it was the sort of hilighting I wanted. But I really didn't want to entirely change themes and force an entire new look on my program. It would especially make things look unnatural for Vista and Windows 7 users.

What would be ideal is if I could have another set of Images that would apply when the object is Checked ... but there is not a "CheckedImages" property. Or a way of programmatically or automatically modifying the image if it is checked (e.g. like disabled images get a grayscale version of their enabled image).

I still wouldn't mind hearing from anyone if there are any ways to implement this or something else that might work equally well, without changing the entire look of my program.

3
Don't the standard TToolbar, TMainMenu and TPopupMenu do this already? And they are even better than the ones you have screenshots for because they do it in a native way!David Heffernan
I personally use Toolbar2000+SpTBX and prefer them to TToolbar, and TActionManager components.Warren P

3 Answers

13
votes

Add a TActionManager to the form, and create some actions (e.g., bold, italic, and underline). Make sure to set the AutoCheck property to true for each action. Then add a TActionToolbar. Double-click the action manager, and drag the three actions to the toolbar. Now add a TXPColorMap to the form, and assign it to the action manager. Also add a TImageList and add icons for bold, italic, and underline (from C:\Program Files (x86)\Common Files\CodeGear Shared\Images\GlyFX\Icons\BMP\16x16). Assign the image list to the action manager.

Set the toolbar icons to show only the glyph and not the caption. Finally, set the ActionManager's Style property to XP Style. The end result is what you seek.

Toolbar sample

2
votes

One can also use an ordinary TToolBar, with DrawingStyle set to dsGradient, I just found out.

Sample toolbar with dsGradient as DrawingStyle

0
votes

Without changing the entire theme, I think this is something that might work half decently:

  1. Add extra images to the ImageList, so that for a given action, there are two (or more) images to choose from.

  2. Instead of changing the "checked" property to true or false, change the ImageIndex to the alternative image, e.g.:

    if WS = 1 then begin
      ElTree.Align := alTop;
    //  TileTopBottomAction.Checked := true;  --- take this out
    //  TileLeftRightAction.Checked := false;  --- take this out
      TileTopBottomAction.ImageIndex := 47;  { hilighted image }
      TileLeftRightAction.ImageIndex := 14;  { regular image }
    end 
    else begin
      ElTree.Align := alLeft;
    //  TileTopBottomAction.Checked := false;  --- take this out
    //  TileLeftRightAction.Checked := true;  --- take this out
      TileTopBottomAction.ImageIndex := 13;  { regular image }
      TileLeftRightAction.ImageIndex := 48;  { hilighted image }
    end;
    

Now the images will look like this on the toolbar:

toolbar

and like this on the menu:

menu

The nice things about this method is that it also works on the menu, and you can have multiple images to represent what you want. Also, it will not wreck the theme (XP, Vista, Windows 7, etc) that the program has taken on.

The disadvantage of this method is: You are limited to 16x16 image area to play with and cannot draw a box around it that are outside those limits as happens when you set the "checked" property to true.