I am in the process of trying to make an app that has most of its development done in Visual C++ 6.0 adhere to Windows theming, or to be precise the visual styles aspect of it. The application in question is a MFC application with the MBCS characterset. Getting theming to kick in in the first place required the InitCommonControlsEx(...);
trick combined with the proper manifests for the Common Controls 6.0. Nothing special thus far.
With all that done, I have tons of windows which have some semblance of drawing glitches showing - white rectangles on the background where there used to be gray like there is in the rest of the window, but they do not hinder.
The biggest troublemaker is in a CDialog
descendant that implements an (archaic) 'did you know...' tip dialog. It refuses to draw anything other than the buttons, checkbox and decorative frame the moment the manifest is in place. However, if I take the manifest OUT, everything works fine.
Comparison images right after invoking the dialog
I have already stepped through the OnPaint
code (which draws the icon and the 'did you know' text, and all functions return sensible and successful values. I also tried removing the entire customdrawn bits (commented out the mappings for the WM_PAINT
and WM_CTLCOLOR
messages), but even that caused nothing to show or act different for that matter.
Once I click the 'Next Tip' button, it will properly paint the next tip in the list. However, the customdrawn header with the bulb icon remains missing.
The code really does nothing special that I can spot, and I'm at a loss. Since I suspect the dialog definition is of most help, I'll include that, although I can post other things if people have ideas on where the problems are hiding.
IDD_TIP DIALOG DISCARDABLE 0, 0, 231, 164
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Tip of the Day"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME,12,11,207,123
LTEXT "Some String",IDC_TIPSTRING,28,63,177,60
CONTROL "&Show Tips on StartUp",IDC_STARTUP,"Button",
BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,13,146,85,10
PUSHBUTTON "&Next Tip",IDC_NEXTTIP,109,143,50,14,WS_GROUP
DEFPUSHBUTTON "&Close",IDOK,168,143,50,14,WS_GROUP
CONTROL "",IDC_BULB,"Static",SS_BITMAP,20,17,190,111
END
The machine I am testing this on is a W7 64-bit machine running VS2010. The application in question itself is 32-bit.
Edit:
A new day provides new insights. Somehow, the issue is with the handling of the WM_CTLCOLOR
message. When I set it to return a NULL_BRUSH
, I finally saw things being drawn (that of course blurred on top of another after initial drawing). Nailing it down even further, it seems that when nCtlColor == CTLCOLOR_STATIC
, if I return a NULL_BRUSH
, stuff will display. The moment I make it a WHITE_BRUSH
nothing gets drawn again, however.
Original code:
HBRUSH CTipDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { if (pWnd->GetDlgCtrlID() == IDC_TIPSTRING) return (HBRUSH)GetStockObject(WHITE_BRUSH); else if (nCtlColor == CTLCOLOR_STATIC) /* Visual styles enabled causes the things we draw in our WM_PAINT * to get cleared (and not redrawn) if we do not use a hollow brush here. * Likely the default behaviour differs when using theming. */ return (HBRUSH)GetStockObject(HOLLOW_BRUSH); return CDialog::OnCtlColor(pDC, pWnd, nCtlColor); }
Problem solved! The lines that are in bold are what I changed to fix my problem, including the obligatory comments. :)