3
votes

I have inherited a large MFC application which contains a CComboBox subclass that overrides OnPaint. Currently it does all its drawing by hand (with lines and rectangles), and renders a combo box that looks decidedly Windows 98-style. However, it otherwise works great and provides a lot of useful custom functionality that we rely on, and rewriting the entire control is probably not an option.

I would like to modernize it so that the OnPaint draws in Aero style where available (falling back to the old code when modern theming is unavailable). I've done this with some other custom controls we have, like buttons, and it works great for our purposes. I know there are some tiny behaviors that it won't get right, like gentle highlights on mouse-hover, but that's not a big deal for this app.

I have access to the CVisualStylesXP ckass, so I've already got the infrastructure to make calls like OpenThemeData, GetThemeColor or DrawThemeBackground pretty easily (via LoadLibrary so we don't force Vista as a min-system). Unfortunately, I don't know the proper sequence of calls to get a nice looking combo box with the theme-appropriate border and drop-down button.

Anyone know what to do here?

3

3 Answers

0
votes

Honestly, I don't know why they originally tried to override OnPaint. Is there a good reason? I'm thinking that at least 99% of the time you are just going to want to override the drawing of the items in the ComboBox. For that, you can override DrawItem, MeasureItem, and CompareItem in a derived combo box to get the functionality you want. In that case, the OS will draw the non-user content specific to each OS correctly.

0
votes

I think you best shot without diving in the depth of xp theming and various system metrics is take a look at this project: http://www.codeproject.com/Articles/2584/AdvComboBox-Version-2-1

Check the OnPaint of the CAdvComboBox class - there is a full implementation of the control repainting including xp theme related issues.

0
votes

Not sure if it's the same situation - but when I faced this problem (in my case with subclassed CButtons), solving it only required changing the control declaration to a pointer and creating the control dynamically.

Let's assume that your subclassed control is called CComboBoxExt.
Where you had

CComboBoxExt m_cComboBoxExt;

You'll now have

CComboBoxExt* m_pcComboBoxExt; 

And on the OnInitDialog of the window where the control is placed, you create it using

m_pcComboBoxExt = new CComboBoxExt();  
m_pcComboBoxExt->Create(...)

Since this is now a pointer, don't forget to call DestroyWindow() and delete the pointer on termination.

This solved my particular problem - if your control is declared in the same way, consider giving it a try.