`
ldb19890624
  • 浏览: 243825 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

创建有个性的对话框之MFC篇(一)

 
阅读更多

想使自己的软件与众不同就要给软件加点“色”,一个颜色搭配协调的窗口要比windows千篇一律的灰底黑字更能吸引别人的眼球。设想如果html浏览器显示的网页都是白底黑字,还会有那么多的mm喜欢上网吗?可能互联网的人气将下降一半。做个出色的界面对于老手来说可能不在话下,但是对于新手来说还是无从下手,使用BCGControlBar和Xtreme Toolkit是个很好的选择,不过对于一个小程序使用这么大的库未免有头重脚轻的感觉。其实不使用这些庞然大物一样可以做个很“色”的界面,本文就结合CSDN论坛上经常被问起的问题,介绍几个给对话框上色的方法。本文的方法都是针对MFC程序的,其他方法请参看“创建有个性的对话框之ATL/WTL篇”。

第一步:改变对话框的背景颜色

如何改变对话框的背景颜色这个问题常常出现在论坛上,可见大家对Windows默认的灰色对话框是多么不满。MFC程序修改对话框的背景和文字颜色最简单的方法就是调用SetDialogBkColor函数,SetDialogBkColor是CWinApp类的成员函数,以下是该函数的原型:

void CWinApp::SetDialogBkColor(COLORREF clrCtlBk, COLORREF clrCtlText);

请注意,SetDialogBkColor函数并不是对Windows的某个API的封装,他是MFC框架的一部分,所以不使用MFC的程序也就不能享受这种方便。这个函数的使用很简单,在程序的CWinApp派生类的InitInstance函数中添加一行代码就行了:

SetDialogBkColor(RGB(188,197,230),RGB(13,125,188));

图.1 就是运行效果:

图.1 SetDialogBkColor效果图

使用SetDialogBkColor也有局限的地方,那就是所有的控件文字颜色都一样,不能针对不同的控件设置不同的文字颜色,还有就是不能设置Edit控件的颜色。不使用SetDialogBkColor函数,直接编写代码控制对话框的背景颜色和控件文字颜色也不是很困难的事情,并且这种方法能够提供更灵活的颜色设置方案,比如对不同类型的控件使用不同的文字颜色,使用高亮度的背景颜色突出某个控件等等,最重要的是能够控制Edit控件的文字和背景颜色,下面就介绍这种方法。
首先是改变对话框的背景颜色。当Windows系统需要重画某个窗口客户区的背景的时候,就会向该窗口发送WM_ERASEBKGND 消息,窗口的处理过程响应这个消息重新画窗口的背景,这个过程称之为“自画”。改变对话框的背景颜色的原理很简单,就是响应这个消息,用自定义的颜色填充对话框的客户区背景,代替对话框窗口默认的背景填充动作。许多新手经常问:“为什么在class wizard中找不到对话框的WM_ERASEBKGND消息,是不是对话框没有这个消息”?其实对话框也是窗口,它也有WM_ERASEBKGND消息,只是MFC的class wizard使用的dialog过滤器将其过滤掉了(只是在message窗口的显示中过滤了,并不是真的不响应这个消息),为的是代码编写过程中突出对话框专有的消息和控件事件。如图.2 所示,只要在class wizard中的“class info” table标签下将消息过滤器改成Windows就可以在对话框的消息列表中看到WM_ERASEBKGND了。

图.2 修改消息过滤器

现在通过class wizard添加WM_ERASEBKGND的消息响应函数,并如下所示修改这个函数:

BOOL CCustDlgDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rcClient;
GetClientRect(&rcClient);
pDC->FillRect(&rcClient,&m_brBkgnd);

return TRUE;

//return CDialog::OnEraseBkgnd(pDC);
}

m_brBkgnd是个CBrush,在此之前已经初始化过了,关键代码是最后返回TRUE,而不是默认的调用基类函数,返回TRUE意在告诉Windows:“我已经画过背景了,你不要再画了”。现在来看看运行的效果:

图.3 重画背景的效果

使用位图作为对话框的背景也不难,就是在整个客户区画一个位图背景,

第二步:改变控件的颜色

看起来不如刚才效果好,控件文字的颜色和背景色都没有改变,这是因为我们还没有处理WM_CTLCOLOR消息。WM_CTLCOLOR是Windows的控件向其父窗口发送最频繁的通知消息之一,例如,许多控件发送WM_CTLCOLOR消息给父窗口,让父窗口提供画刷来画自己的背景。MFC的窗口类对这个通知消息特殊对待,如果父窗口没有处理这个通知消息,MFC的窗口类就根据WM_CTLCOLOR通知消息的来源将这个WM_CTLCOLOR消息发送回控件,让控件自己处理,这就是所谓的“消息反射”,不仅是WM_CTLCOLOR,MFC对很多通知消息都做了反射,不过我们今天的例子没有使用“消息反射”,我们在控件的父窗口,也就是对话框窗口处理这个通知消息。还有一点需要说明的是,WM_CTLCOLOR消息是16位的Windows平台的消息,在32位的Windows平台上取而代之的是一系列更明确的通知消息:

WM_CTLCOLORBTN 按钮控件
WM_CTLCOLORDLG 对话框
WM_CTLCOLOREDIT 编辑控件
WM_CTLCOLORLISTBOX 列表框控件
WM_CTLCOLORSCROLLBAR 滚动条控件
WM_CTLCOLORSTATIC 静态文本控件

MFC为了兼容性考虑,仍旧使用OnCtlColor响应这些消息,但是通过参数nCtlColor来具体的区分他们。在这个函数中,我们可以通过改变pDC参数的属性来改变控件的绘制,并返回相应的画刷句柄给控件,控件使用这个画刷画自己的背景。下面是我们修改后的OnCtlColor函数:

HBRUSH CCustDlgDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

pDC->SetTextColor(m_clrText);
pDC->SetBkMode(TRANSPARENT);

return (HBRUSH)m_brBkgnd; //因为CBrush类实现了HBRUSH类型转换操作符

//return hbr;
}

图.4 就是这段代码的效果,在这里我们不分“青红皂白”,向所有的控件返回我们自己的画刷,看起来不错,Edit控件的文字颜色也改了,但是好像多行Edit控件有了麻烦,看来需要对多行Edit控件特殊对待。

图.4 重载OnCtlColor之后的效果

对于多行Edit控件特殊处理,如下所示,上面的问题解决了:

HBRUSH CCustDlgDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

if(pWnd->GetDlgCtrlID() == IDC_EDIT_MULTI_LINE) //IDC_EDIT_MULTI_LINE是多行Edir控件的ID
{
pDC->SetTextColor(m_clrText);
return hbr;
}
else
{
pDC->SetTextColor(m_clrText);
pDC->SetBkMode(TRANSPARENT);

return (HBRUSH)m_brBkgnd;
}
}

上面的代码解决了IDC_EDIT_MULTI_LINE的问题,但是对每个多行Edit控件都要判断ID,下面的方法可以一劳永逸地解决多行编辑控件的问题:

HBRUSH CCustDlgDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
TCHAR szClassName[64];

::GetClassName(pWnd->GetSafeHwnd(),szClassName,64);
if(lstrcmpi(szClassName,_T("Edit")) == 0) //是Edit 控件
{
DWORD dwStyle = pWnd->GetStyle();
if((dwStyle & ES_MULTILINE) == ES_MULTILINE) //多行edit控件
{
pDC->SetTextColor(m_clrText);
return hbr;
}
else
{
pDC->SetTextColor(m_clrText);
pDC->SetBkMode(TRANSPARENT);

return (HBRUSH)m_brBkgnd;
}
}
else //不是编辑控件
{
pDC->SetTextColor(m_clrText);
pDC->SetBkMode(TRANSPARENT);

return (HBRUSH)m_brBkgnd;
}
}

下面我们针对每个控件设置特殊的颜色,区分控件可以通过控件的ID,修改控件背景也很简单,直接返回相应的画刷就可以了,下面就是颜色设置的完整代码:

分享到:
评论

相关推荐

    创建有个性的对话框之MFC篇.pdf

    创建有个性的对话框之MFC篇,个性MFC对话框

    MFC创建个性对话框

    ### MFC创建个性对话框 #### 一、建立MFC应用程序 **1.1 新建工程** 为了开始创建个性化的对话框,首先需要在Visual C++环境中新建一个MFC应用程序。打开VC应用程序后,在“文件”菜单中选择“新建”命令,接着在...

    MFC.rar_MFC_MFC 对话框_MFC框

    在本资料"学习MFC,创建有个性的对话框之MFC篇"中,我们将重点探讨如何使用MFC来设计和定制具有独特功能的对话框。 对话框在GUI应用中扮演着至关重要的角色,它是用户与程序进行交互的主要界面。MFC提供了多种类型...

    创建有个性的对话框之MFC篇

    想使自己的软件与众不同就要给软件加点“色”,一个颜色搭配协调的窗口要比windows千篇一律的灰底黑字更能吸引别人的眼球。设想如果html浏览器显示的网页都是...本文的方法都是针对MFC程序的,其他方法请参看“创建有个

    MFC创建不规则对话框

    在Microsoft Foundation Classes (MFC)库中,创建不规则对话框是一种高级的用户界面技术,它允许开发者构建形状独特、不遵循标准矩形边界的窗口。这种技术在一些需要个性化或者增强视觉效果的应用中非常有用。本文将...

    MFC自绘对话框风格

    此外,MFC中的CWnd类有一个OnEraseBkgnd()函数,该函数在背景需要清除时被调用。如果想要自定义对话框的背景,可以重写这个函数,而不是在OnPaint()中清除背景。这样可以避免不必要的重绘,提高性能。 自绘对话框还...

    个性MFC对话框界面

    例如,你可以设计一个带有动画效果的按钮,或者创建一个具有特殊形状的文本框。 2. **背景图片与BMP资源**:压缩包中的“BmpDialog23”可能是一个用于对话框背景的位图资源。在MFC中,可以通过设置对话框背景为位图...

    MFC对话框背景设置解决方案

    一个MFC对话框包含两个主要部分:对话框模板和对话框类。对话框模板定义了对话框的布局和控件,通常存储在.RC资源文件中;对话框类则负责处理对话框的逻辑和事件响应。 2. 对话框模板: 在资源编辑器中,开发者...

    MFC对话框界面美化

    "MFC对话框界面美化"是一个利用MFC库来设计更吸引人的用户界面的实践案例,特别是通过创建圆形按钮来提升视觉效果。这个程序的亮点在于其通用性,意味着它可以广泛应用于各种类型的软件项目,为用户提供更友好的交互...

    如何给MFC对话框添加背景图片

    然而,标准的MFC对话框通常只有单一的颜色作为背景,如果我们想要给对话框添加个性化的背景图片,就需要进行一些自定义工作。本教程将详细解释如何在MFC对话框中添加背景图片。 1. **添加背景图片资源** 首先,你...

    基于MFC的关于设置对话框背景颜色的设置

    在Windows应用程序开发中,Microsoft Foundation Class (MFC)库是一个强大的工具,它为开发者提供了创建桌面应用程序的便利。本文将详细讲解如何在基于MFC的对话框应用中设置自定义的背景颜色,以满足个性化需求。 ...

    MFC动态修改对话框背景颜色

    在本篇文章中,我们将深入探讨如何在MFC应用程序中实现这一功能。 首先,我们需要了解MFC中的对话框。对话框是Windows应用程序中一种常用的用户界面元素,用于显示信息、获取用户输入或执行特定任务。在MFC中,...

    MFC设置位图为对话框背景

    本篇文章将深入探讨如何在MFC对话框中设置位图作为背景,以及这一操作可能涉及的相关技术。 首先,我们需要了解对话框的基本概念。对话框是Windows应用程序中一种用于与用户交互的窗口,通常包含各种控件,如按钮、...

    MFC 美化对话框,各种样式的对话框。

    在Microsoft Foundation Class (MFC)库中,CDialog类是用于创建和管理对话框的核心类。MFC对话框不仅提供了一种与用户交互的方式,还允许开发者通过自定义外观和功能来实现各种样式的对话框。本文将深入探讨如何利用...

    MFC无规则对话框程序

    MFC无规则对话框程序是指使用MFC库创建的可以自由定义形状和大小的对话框,它突破了传统矩形对话框的限制,为用户提供了更个性化的界面设计。这种技术通常涉及Windows API中的窗口区域(Window Region)概念。 一、...

    字体对话框的创建

    在编程领域,创建一个字体对话框是用户界面(UI)设计中的一个重要环节,尤其是在开发桌面应用程序时。字体对话框允许用户选择不同的字体属性,如字体类型、大小、样式(粗体、斜体等),以便在文档或应用中个性化...

    基础个性化对话框代码

    本教程将通过“基础个性化对话框代码”这一主题,深入探讨如何创建和定制自己的对话框,以提升用户体验。对话框通常用来显示警告、询问用户信息或者执行特定任务。 首先,我们需要理解对话框的基本概念。对话框是一...

    MFC制作的屏幕右下角弹出窗口

    一、MFC弹出窗口基础 在MFC中,我们可以利用CWnd或CDialog类来创建窗口。为了实现屏幕右下角的弹出效果,我们需要自定义一个继承自CWnd或CDialog的类,比如命名为CMiniMsgBox。在这个类中,我们需要重写OnCreate()...

Global site tag (gtag.js) - Google Analytics