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

。_饼干妹妹 提交于 2019-12-05 12:43:43
Chris Becke

The usual way of implementing pages in a tab control is required to access MS's solution to this problem :-

Instead of creating individual controls in the tab area, create a modeless child dialog for each page and have the controls on that. Create the page dialogs with the main dialog (not the tab) as their parent and as the user switches between tabs, simply show and hide the relevant page dialog.

In the WM_INITDIALOG handler for each page, call the uxtheme API EnableThemeDialogTexture

With the ETDT_ENABLETAB flag this automatically changes the background color of the dialog and all its child controls to paint appropriately on a tab.

If you have overridden WM_ERASEBKGND or WM_CTLCOLOR* in your pages DialogProc you will need to revert to default handling (return FALSE) as these methods are where the dialog code is going to do its heavy lifting. The style bits should simply be set as though the child page dialog page was going to be created on a normal windows 9X tabbed dialog.

The reason why the background is gray is because that is the default.

To override it, you can process the WM_CTLCOLORSTATIC message in the parent window and return a custom brush.

Your problem is not with ATL or WinAPI. In MFC there is the same problem. Set Tab control as parent window for Static controls. But I think that overriding WM_DRAWITEM is more flexible solution.

I've got Win32/MFC applications with labels inside tabs on dialogs, and the background colour looks fine on them (that is, it reflects the XP-look theme, rather than being flat grey) without any obvious special handling.

Under the hood what's supposed to happen is that the label posts a WM_CTLCOLOR message to its parent, which sets the device context up appropriately: the default handling in Windows should set the appropriate background colour, at least for dialogs and tab controls.

One possibility is that you're doing something non-standard in your handling of WM_CTLCOLOR: is it over-ridden somewhere in your application? Possibly you have some old code that is setting the label background colour in this way.

(Also, as Rob asks, are you using a manifest to get comctl32 6.0 into your application?)

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;
        }
}

Have spent an amazing amount of time to try to fix a problem so seemingly simple, tried almost every constant for hbrBackground without success.

As an amateur found that the most simple & time efficient fix was to simply create a "Static" class child window that envelops the entire window. Just another hack level fix though

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!