77. Why do my tree control icons lose transparency?
I noticed this problem while I was developing a network configurator
application for our next-generation system. I was using alpha-blended
icons to indicate disabled hardware in a tree control, and testing under
Vista. Imagine my confusion when I noticed the icons losing their tranparency
as I moused over the tree control expander buttons.
I posted the issue to microsoft.public.vc.mfc (since there isn't a common
controls group on the Microsoft public Usenet server). Once I'd added a repro
application, people started seeing the issue not just on Vista, but on XP as
well - the only difference being that on XP you had to actually USE the buttons
to see the loss of transparency. It appears that the out-of-box paint behaviour
on the tree common control just doesn't play nice with alpha-blended icons. It'll
make a mess of your nice drop-shadows :-(
If you have Visual Studio 2008, you can download my repro project here
and have a play. Note that it's tricky to make your own version because the primitive
icon editor in Visual Studio can't create alpha-blended icons, even after
all these years. You need a third party tool like the excellent freeware IcoFx to
do that.
Fortunately there's a couple of ways to avoid this problem. Firstly, you
can use the theming functionality to fully theme the tree control. Theming makes
changes to the way the control paints which will silently fix the issue (at least
on Vista, I haven't tried this on XP). Time for some code. Assume the tree control
has a DDX variable declared, named m_ctrl_treeAdapters:
// Use this code for Vista's triangular tree buttons.
::SetWindowTheme(m_ctrl_treeAdapters, L"explorer", 0);
However, if you already use a third party themer, your corporate guidelines
mandate an XP style, or you just prefer the old tree button appearance
like me, you can set the tree control's double-buffering extended style bit:
// Use this code for old-style tree buttons, it fixes a bug in
// tree control painting when old-style buttons are in use.
DWORD dwStyleBits;
dwStyleBits = m_ctrl_treeAdapters.GetExtendedStyle();
dwStyleBits |= TVS_EX_DOUBLEBUFFER;
m_ctrl_treeAdapters.SetExtendedStyle (0, dwStyleBits);