Hi Mario,
Unfortunately, TActionToolBar doesn't use the Win32 toolbar control
as its backend, so many of the features (including custom disabled
images) that we're used to using with TToolBars aren't available for
TActionToolBar. The TCustomActionControl::DrawGlyph() method is
actually responsible for drawing the toolbutton's glyph, and
unfortunately it uses the very primitive DrawState() Win32 function to
draw a disabled version of the glyph, which is why it looks so bad.
However, the good news is that the action-bar framework--though
definitely rough around the edges--is flexible enough for customization.
To use custom disabled images, you need to do two things:
(1) You need to create a TCustomButtonControl descendant class in which
you override the DrawGlyph() method to draw your own disabled glyphs.
(TCustomButtonControl is a TCustomActionControl descendant.)
(2) You need to provide handlers for the TActionToolBar's
OnGetControlClass and OnControlCreated events, in which you inform the
TActionToolBar to create instances of your TCustomButtonControl
descendant class (from Step 1) instead of the default
TCustomButtonControl class.
Here's an example. For the first step, I've called the descendant class
TMyButtonControl, which provides a DisabledImages property that you
can use to specify an extra image-list which contains the disabled glyphs...
class TMyButtonControl : public TCustomButtonControl
{
public:
__property TImageList* DisabledImages =
{read=DisabledImages_, write=DisabledImages_};
public:
__fastcall TMyButtonControl(TComponent* Owner) :
TCustomButtonControl(Owner) {}
protected:
virtual void __fastcall DrawGlyph(TPoint const& Location)
{
// if the action is enabled or there's no
// disabled image list specified...
if (Enabled || DisabledImages == NULL)
{
// have parent class do its default drawing
TCustomButtonControl::DrawGlyph(Location);
}
else // otherwise, draw custom disabled glyph...
{
TPoint GlyphPos(Location);
if (Down || IsChecked())
{
++GlyphPos.x;
++GlyphPos.x;
}
// disabled small icon should be drawn
if (SmallIcon)
{
HIMAGELIST const hImageList =
reinterpret_cast<HIMAGELIST>
(DisabledImages->Handle);
ImageList_DrawEx(
hImageList, ActionClient->ImageIndex,
Canvas->Handle, GlyphPos.x, GlyphPos.y,
0, 0, clNone, clNone, ILD_TRANSPARENT
);
}
else // disabled large icon should be drawn
{
// TODO: draw a large icon (e.g., from another
// image list, or stretch-to-fit 32x32 by using
// an intermediate bitmap)
}
}
}
virtual void __fastcall DrawText(TRect& ARect,
unsigned int& Flags, AnsiString Text)
{
Canvas->Brush->Style = bsClear;
if (Down || IsChecked())
{
OffsetRect(&ARect, 1, 1);
}
if (Enabled)
{
::DrawText(Canvas->Handle, Text.c_str(),
Text.Length(), &ARect, Flags);
}
else // disabled text
{
if (!Selected)
{
OffsetRect(&ARect, 1, 1);
Canvas->Font->Color = (Color == clBtnFace) ?
clBtnHighlight : GetHighLightColor(Color);
::DrawText(Canvas->Handle, Text.c_str(),
Text.Length(), &ARect, Flags);
OffsetRect(&ARect, -1, -1);
}
Canvas->Font->Color = (Color == clBtnFace) ?
clBtnShadow : GetShadowColor(Color);
::DrawText(Canvas->Handle, Text.c_str(),
Text.Length(), &ARect, Flags);
}
}
private:
TImageList* DisabledImages_;
};
Note that the DrawGlyph() method implemented here assumes that the
indices (into the image-lists) for the normal and disabled glyphs are
identical. Also notice that I had to provide an implementation of the
DrawText() method due to a BCB bug (I was getting unresolved external
errors).
For the second step, you use the action toolbar's OnGetControlClass
event to tell the toolbar to use the descendant class...
void __fastcall TForm1::ActionToolBar1GetControlClass(
TCustomActionBar *Sender, TActionClient *AnItem,
TCustomActionControlClass &ControlClass)
{
ControlClass = __classid(TMyButtonControl);
}
And then use the OnControlCreated event to perform any initial
modifications to each TMyButtonControl instance (here, to specify
ImageList2 as the DisabledImages property)...
void __fastcall TForm1::ActionToolBar1ControlCreated(
TObject *Sender, TCustomActionControl *&Control)
{
if (dynamic_cast<TMyButtonControl*>(Control) != NULL)
{
TMyButtonControl* MyButtonControl =
static_cast<TMyButtonControl*>(Control);
MyButtonControl->DisabledImages = ImageList2;
}
}
Good luck,
--
Damon (TeamB)
C++Builder Developer's Journal
http://bcbjournal.com
BCB Commonly Asked Questions
http://bcbjournal.com/bcbcaq