使用清单会导致窗口保持部分空白

时间:2010-09-23 23:35:48

标签: c++ mfc manifest visual-styles

我正在尝试制作一个应用程序,它的大部分开发都是在Visual C ++ 6.0中完成的,遵循Windows主题,或者准确地说是它的视觉样式方面。有问题的应用程序是带有MBCS字符集的MFC应用程序。首先要获得主流,需要将InitCommonControlsEx(...);技巧与Common Controls 6.0的正确清单相结合。到目前为止没什么特别的。

完成所有这些工作后,我有大量的窗户看起来有一些绘图故障 - 背景上的白色矩形,曾经是灰色,就像窗户的其他部分一样,但它们并没有阻碍。 / p>

最大的麻烦制造者是CDialog后代,它实现了一个(过时的)“你知道吗...”提示对话框。在清单到位的那一刻,它拒绝绘制按钮,复选框和装饰框以外的任何东西。但是,如果我使用清单OUT,一切正常。

Comparison images right after invoking the dialog

我已经逐步完成了OnPaint代码(它绘制了图标和'你知道吗'文本,并且所有函数都返回合理且成功的值。我也尝试删除整个自定义位(注释掉了WM_PAINTWM_CTLCOLOR消息的映射,但即使这样也没有显示任何内容或行为不同。

点击“下一个提示”按钮后,正确绘制列表中的下一个提示。但是,带有灯泡图标的自定义标题仍然缺失。

代码真的没什么特别的,我能发现,而且我很茫然。由于我怀疑对话框定义是最有帮助的,所以我会将其包括在内,但如果人们对问题隐藏的地方有所了解,我可以发布其他内容。

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

我正在测试的机器是运行VS2010的W7 64位机器。有问题的应用程序本身是32位。

编辑:

新的一天提供了新的见解。不知何故,问题在于处理WM_CTLCOLOR消息。当我将它设置为返回NULL_BRUSH时,我终于看到了正在绘制的东西(当然在初始绘制之后在另一个上面模糊)。进一步确定它,似乎在nCtlColor == CTLCOLOR_STATIC时,如果我返回NULL_BRUSH,则会显示内容。然而,当我把它变成WHITE_BRUSH的那一刻,没有什么东西会再被画出来。

原始代码:

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

问题解决了!以粗体显示的行是我为解决问题所做的更改,包括强制性评论。 :)

1 个答案:

答案 0 :(得分:1)

据我所知,Common Controls的第6版仅正式支持Unicode。

根据a blog entry by Raymond Chen,这些控件在一定程度上使用ANSI字符集,但仅出于向后兼容性原因。没有人应该故意使用它。

  

如果您是ANSI应用程序并且从公共控件库创建控件,则可能会遇到奇怪的行为。它主要起作用,但边缘的事情可能很奇怪。

     

...

     

这意味着所有使用通用控件版本6但尚未转换为Unicode的人都依赖于兼容性漏洞。 ANSI支持是针对那些认为他们正在与版本5通用控件进行通信的旧程序;它不适合你。

我从来没有尝试过这样的事情所以我不能肯定地说,但你可能会遇到一些这种“奇怪的行为”。如果是这种情况,那么唯一官方支持的选项是转换为Unicode或返回使用控件的版本5。否则你会试图找到你可能找到的任何奇怪行为的解决方法,这听起来不是一个好的情况。