Search code examples
c++user-interfacewinapixp-theme

Windows XP Style: Why do we get dark grey background on static text widgets?


We're writing Windows desktop apps using C++ and Win32. Our dialog boxes have an ugly appearance with "Windows XP style": the background to the static text is grey. Where the dialog box background is also grey, this is not a problem, but inside a tab control, where the background is white, the grey background to the text is very noticeable.

In the past we have done a lot of our own drawing of controls, but these days we are trying to use the standard look'n'feel as much as possible, and to avoid overriding standard behaviour as much as possible.

We are using the Win32 API, which is getting a bit dated, but I think the problem occurs even with ATL. We are creating a DIALOGTEMPLATE. The text is in a "static" control (0x0082). The only flag we set for the style is "SS_LEFT". The text control is inside a tab control: "SysTabControl32" with only one flag: WS_CLIPSIBLINGS set on it. I've experimented with SS_WHITERECT and WS_EX_TRANSPARENT and other settings, to no avail.

All of this gets drawn with the standard Windows dialog box message handler. My main question is "what are we doing wrong?" rather than "how can I work around it?", although I'll settle for the latter if no-one can help me with the first.

Any ideas?


Solution

  • We're not overriding the WM_CTLCOLORSTATIC message. There's no occurrence of this string in our source code and nothing like it in our message handlers.

    We've worked around this problem by overriding the WM_DRAWITEM message for tab controls to paint their contents with the grey background (standard for dialog boxes without tab controls) rather than the white background (standard for the contents of tab controls).

            brush = CreateSolidBrush(GetSysColor(COLOR_MENU));
            FillRect(lpdis->hDC, &lpdis->rcItem, brush);
            SetBkColor(lpdis->hDC, GetSysColor(COLOR_MENU));
            wtext = ToWideStrdup(c->u.tabcontrol.Tabs[lpdis->itemID].name);
            rect = lpdis->rcItem;
            rect.top += DlgMarginY - 1;
            rect.bottom += DlgMarginY;
            DrawTextW(lpdis->hDC, wtext, -1, &rect, DT_CENTER | DT_VCENTER);
            free(wtext);
            DeleteObject(brush);
    

    This is obviously a workaround, not a proper answer to my question.

    Incidentally, we initialise the "common controls", of which I believe the tab control is one, using code like this...I don't suppose this is related to the issue?

    #pragma comment(linker, "/manifestdependency:\"type='win32' " \
        "name='Microsoft.Windows.Common-Controls' " \
        "version='6.0.0.0' " \
        "processorArchitecture='*' " \
        "publicKeyToken='6595b64144ccf1df' " \
        "language='*'\"")
    ...
    
    hCommCtrl = GetModuleHandle("comctl32.dll");`
    if (hCommCtrl) {
            ptrInit = (TfcInit_fn) GetProcAddress(hCommCtrl, "InitCommonControlsEx");
            if (ptrInit) {
                data.dwSize = sizeof(INITCOMMONCONTROLSEX);
                data.dwICC  = ctrlClass;
                if (ptrInit(&data) )
                    gCommCtrlsInitialized |= ICC_TAB_CLASSES | ICC_BAR_CLASSES;
            }
    }