在MFC控件中更改背景和标题的颜色

时间:2014-04-04 13:08:21

标签: winapi mfc

我想更改MFC应用程序中的编辑控制,静态控制和按钮控制的文本颜色和背景颜色。该控件位于CDialogEx对话框中。

我尝试添加OnCtlColor(在visual studio中使用向导,在WM_CTLCOLR消息上)但我无法设置静态控件和按钮控件的颜色。

我在OnCtlColor函数中(在IF构造中)也设置了一个断点,但我没有收到任何东西。

我还尝试使用SetTextColor函数从GetDlgItem检索控件的句柄,但我无法根据需要更改颜色。

请帮助我。

1 个答案:

答案 0 :(得分:2)

我可以断言我尝试在OnCtlColor中使用CDialog,它适用于静态和编辑控件。

您所要做的就是:

  • 要更改背景颜色,您需要创建一个仍然存在于该函数外部的画笔,并使用

    返回其HBRUSH

    return (HBRUSH) m_brush.GetSafeHandle();

    所以你必须在成员中创建一个变量(m_brush成员或静态(我推荐第一个),并且在对话框初始化中你必须创建你想要的画笔。

    我想也许有些控件不能用于此,对于那些我也做过的

    pDC->SetBkColor(RGB(0,0,255));

    但似乎什么都不做;它在安全守则中。

  • 为了更改文字​​颜色,我做了

    pDC->SetTextColor(RGB(255,0,0));

这些体验适用于编辑和静态编辑,但对于groupbox不起作用!

Groupbox在MFC中是一个奇怪的实体,某种platyplus:它们是CButton BS_GROUPBOX,但在此函数中,nCtlColorCTLCOLOR_STATIC而不是CTLCOLOR_BTN!我为他们做了这个

UINT nStyle = (UINT)(pWnd->GetStyle() & 0x0F);

if(nStyle == BS_GROUPBOX)
{
    return (HBRUSH) m_brush2.GetSafeHandle();
}

被绘制的是组合框标题后面的小矩形!

我无法更改分组框的文字颜色!

如果您有分组框并且更改其标题的文字颜色非常重要,您可以从http://www.codeproject.com/Articles/29016/XGroupBox-an-MFC-groupbox-control-to-display-text获取其中的一个并获取其基本代码部分:来自CStatic,{ {1}}和OnPaint()方法。不要忘记消息地图上的DrawItem()。我不知道ON_WM_PAINT()及其OnEraseBkgnd()消息映射是否如此重要。 还需要将它们更改为资源中的静态文本控件,声明ON_WM_ERASEBKGND()变量并对其执行DDX _ XGroupBox。 我测试了它,它确实有效。

对于按钮,使用CButton它不起作用。但是,对于每个按钮,我只是在类中声明了一个Control变量,并且每个变量都有一个CMFCButton。之后,我有两个选择:

  • 在表单构造函数中将DDX_Control属性设置为m_bTransparent(在afxbutton.cpp文件中搜索此变量以供参考),以获取我想要与表单颜色相同的那些(我也画了表格;在我的情况下,我在应用程序上实现主题)

  • 使用TRUE设置背景颜色,并在表单初始化中将文本颜色设置为SetFaceColor()

SetTextColor()没有设置这些内容时,它会从当前所选CMFCButton的主题混合中获得颜色。

注意:我还将CMFCVisualManager实体替换为CSpinButton个实体,因为我想要所选主题中的颜色。

CMFCSpinButon中,OnCtlColor变量非常重要,因为它可以让您根据不同的类型个性化不同的颜色,而无需为每个控件测试nCtlColor成功或失败。

不要忘记在邮件地图中添加dynamic_cast

更新1: 按照http://social.msdn.microsoft.com/Forums/vstudio/en-US/53f47162-078a-418f-8067-ee61a81ceeac/checkbox-transparent-color-not-working-in-vs2008?forum=vcgeneral上接受的答案的建议,我做了自己的Groupbox课程,现在就像:

ON_WM_CTLCOLOR()

我刚刚声明其中一个,并使用其各自的控件ID执行class CMyGroupBox: public CButton { protected: virtual void PreSubclassWindow() { SetWindowTheme(*this, _T(""), _T("")); #pragma comment(lib, "UxTheme.lib") } }; ,现在我可以看到我提供给DDX_Control的颜色的文本。如果为此控件返回HBRUSH,绘制的是在组框标题周围绘制的非填充矩形。

更新2 我只是将SetTextColor概括为CMyGroupBox,不仅在群组中使用了CMyButton方法,而且还在复选框和按钮中使用PreSubClassWindow方法。在复选框中它很好用,在按钮中,我对结果不太满意。

更新3:我试图删除文本渲染上的一些奇怪效果,我只是评论了pDC->SetBkColor(RGB(0,0,255));行;结果是文本背后的一个丑陋的矩形:(。然后我用pDC->SetBkMode(TRANSPARENT);替换它,我也看到了奇怪的效果:(

更新4:为了避免必须将我的所有复选框,组框和按钮声明为包含PreSubClassWindow方法的类,我研究并发现不需要这样做。代码

SetThemeAppProperties(0);
#pragma comment(lib, "UxTheme.lib")
AfxGetMainWnd()->SendMessage(WM_THEMECHANGED, 0U, 0L);

禁用整个应用程序级别的所有控件的主题。