MFC: how to create an Aero combo box for drawing owner?
I inherited a large MFC application that contains a subclass CComboBox
that overrides OnPaint
. It currently does all of its drawings by hand (with lines and rectangles) and displays a combo box that looks explicitly Windows 98 style. Otherwise, it works fine, and provides a lot of useful custom features that we rely on and rewriting the whole control is probably not an option.
I would like to modernize it to OnPaint
paint in the Aero style where it was available (going back to old code when modern theme is not available). I did it with some other custom controls like buttons and it works great for our purposes. I know there are a few tiny behaviors that won't get right, like subtle tints on hover, but that's not very important for this application.
I have access to the CVisualStylesXP
cascade, so I already have a framework to make calls like OpenThemeData
, GetThemeColor
or DrawThemeBackground
fairly easy (via LoadLibrary
, so we don't force Vista as a mini-system). Unfortunately I don't know the correct call sequence to get a nice combo box with a theme-appropriate border and a dropdown button.
Does anyone know what to do here?
source to share
To be honest, I don't know why they originally tried to override OnPaint. Is there a good reason? I think at least 99% of the time you just want to override the drawing of the items in the ComboBox. To do this, you can override DrawItem, MeasureItem, and CompareItem in a derived combo box to get the functionality you want. In this case, the OS correctly draws the non-user content specific to each OS.
source to share
I think it is best to shoot without diving deep into xp themed and various system metrics is to look at this project: http://www.codeproject.com/Articles/2584/AdvComboBox-Version-2-1
Check out the OnPaint of the CAdvComboBox class - there is a complete implementation of repainting controls, including issues related to the xp theme.
source to share
Not sure if in the same situation - but when I ran into this problem (in my case with subclass CButtons), solving it required only changing the declaration of the control to a pointer and dynamically creating the control.
Let's assume your subclass control is named CComboBoxExt.
Where are you
CComboBoxExt m_cComboBoxExt;
Now you will have
CComboBoxExt* m_pcComboBoxExt;
And in the OnInitDialog of the window that the control is in, you create it with
m_pcComboBoxExt = new CComboBoxExt(); m_pcComboBoxExt->Create(...)
Since this is now a pointer, remember to call DestroyWindow()
and delete the pointer on completion.
This solved my specific problem - if your control is declared in the same way, try giving it a try.
source to share