4

我们正在使用 C++ 和 Win32 编写 Windows 桌面应用程序。我们的对话框具有“Windows XP 风格”的丑陋外观:静态文本的背景是灰色的。对话框背景也是灰色的,这不是问题,但是在选项卡控件内部,背景是白色的,文本的灰色背景非常明显。

过去我们已经完成了很多自己的控件绘制,但现在我们正在尝试尽可能多地使用标准外观,并尽可能避免覆盖标准行为。

我们使用的是 Win32 API,它有点过时了,但我认为即使使用 ATL 也会出现问题。我们正在创建一个对话框模板。文本位于“静态”控件 (0x0082) 中。我们为样式设置的唯一标志是“SS_LEFT”。文本控件位于选项卡控件中:“SysTabControl32”,只有一个标志:WS_CLIPSIBLINGS 设置在其上。我尝试了 SS_WHITERECT 和 WS_EX_TRANSPARENT 等设置,但无济于事。

所有这些都是使用标准的 Windows 对话框消息处理程序绘制的。我的主要问题是“我们做错了什么?” 而不是“我该如何解决它?”,尽管如果没有人可以帮助我解决第一个问题,我会满足于后者。

有任何想法吗?

4

6 回答 6

6

需要在选项卡控件中实现页面的常用方法才能访问 MS 对此问题的解决方案:-

不要在选项卡区域中创建单独的控件,而是为每个页面创建一个无模式的子对话框并在其上设置控件。创建以主对话框(不是选项卡)为父级的页面对话框,当用户在选项卡之间切换时,只需显示和隐藏相关的页面对话框。

WM_INITDIALOG每个页面的处理程序中,调用 uxtheme APIEnableThemeDialogTexture

使用该ETDT_ENABLETAB标志,它会自动更改对话框及其所有子控件的背景颜色,以在选项卡上适当地绘制。

如果您已覆盖WM_ERASEBKGNDWM_CTLCOLOR*在您的页面 DialogProc 中,您将需要恢复为默认处理(返回 FALSE),因为这些方法是对话框代码将执行繁重工作的地方。样式位应该简单地设置,就好像子页面对话框页面将在普通的 Windows 9X 选项卡式对话框上创建一样。

于 2009-08-06T08:17:50.453 回答
4

背景是灰色的原因是因为这是默认设置。

要覆盖它,您可以在父窗口中处理 WM_CTLCOLORSTATIC 消息并返回自定义画笔。

于 2009-06-25T11:06:02.463 回答
1

您的问题不在于 ATL 或 WinAPI。在 MFC 中也存在同样的问题。将 Tab 控件设置为静态控件的父窗口。但我认为覆盖WM_DRAWITEM是更灵活的解决方案。

于 2009-07-01T20:13:38.807 回答
0

我有 Win32/MFC 应用程序,在对话框的选项卡中带有标签,它们的背景颜色看起来很好(也就是说,它反映了 XP 外观主题,而不是纯灰色),没有任何明显的特殊处理。

在引擎盖下应该发生的是标签向其父级发布 WM_CTLCOLOR 消息,这会适当地设置设备上下文:Windows 中的默认处理应该设置适当的背景颜色,至少对于对话框和选项卡控件。

一种可能性是您在处理 WM_CTLCOLOR 时正在做一些非标准的事情:它是否在您的应用程序中的某个地方被覆盖?可能您有一些旧代码以这种方式设置标签背景颜色。

(另外,正如 Rob 所问的,您是否使用清单将 comctl32 6.0 放入您的应用程序?)

于 2009-06-25T09:43:48.743 回答
0

我们没有覆盖 WM_CTLCOLORSTATIC 消息。在我们的源代码中没有出现这个字符串,在我们的消息处理程序中也没有类似的。

我们通过覆盖 WM_DRAWITEM 消息来解决此问题,以便选项卡控件使用灰色背景(没有选项卡控件的对话框的标准)而不是白色背景(选项卡控件的内容的标准)绘制其内容。

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

这显然是一种解决方法,而不是对我的问题的正确答案。

顺便说一句,我们使用这样的代码初始化“公共控件”,我相信选项卡控件就是其中之一......我不认为这与问题有关?

#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;
        }
}
于 2009-06-30T21:44:51.867 回答
0

花费了大量时间来尝试解决一个看似简单的问题,几乎尝试了 hbrBackground 的所有常量,但均未成功。

作为一个业余爱好者发现,最简单和最省时的解决方法是简单地创建一个包围整个窗口的“静态”类子窗口。只是另一个黑客级别的修复

于 2010-10-17T12:23:08.780 回答