【VS开发】VS2010 MFC中控件、对话框等背景颜色动态修改的方法

标签(空格分隔):【VS开发】


声明:引用请注明出处http://blog.csdn.net/lg1259156776/


说明:最近突发奇想想完成两件新的人机交互工程,一个是基于眼动仪的眼动控制,另一个是基于camera的手动控制,最直观的方法就是使用slider滑块,眼睛或手左右动,slider也左右动,眼睛或手上下动,slider也上下动,并配合着对话框的背景颜色的改变,来增强互动的效果,本文所记录的就是其中关于动态修改控件颜色的方法。


首先说基于眼动仪的眼动控制,由于提供的matlab接口开发起来比较方便,所以采用了matlab gui设计,而在matlab中关于dialog或者某个控件的颜色的修改简直太方便了,如下一行代码就可以搞定:

set(handles.axes1,'color',[0.5,0.5,0.5])

所以matlab gui设置各种事情是比较方便的。毕竟是解释性开发语言。

由于好久没有在VS2010下开发对话框的应用,以前都是在VC下开发dialog程序,在VS2010上开发的多是具有office风格的文档应用,但是曾经积累的经验是非常有帮助的。就不多说如何按照经验一步一步的尝试了,直接给出最终的较为简单的解决方案:

通过类向导,或者手动添加消息:WM_CTLCOLOR,其消息响应函数为:

afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

在每个控件开始绘制之前,都会向其父窗口发送WM_CTLCOLOR通告消息,在该消息的处理函数中,可以设置控件显示文本的前景色、背景色以及字体。该消息处理函数还要求返回一个画刷的句柄,用于在控件具体的绘制之前擦除其客户区。当窗口重绘时,也会重新绘制每个控件,从而分别调用该函数,这就给了动态修改控件相关颜色特性的机会。

比如在对应的控件下的OnCtrColor函数中写入:

pDC->SetTextColor(RGB(255, 0, 0));    //设置文本前景色
pDC->SetBkColor(RGB(255, 255, 255)); //设置文本背景色
pDC->SetBkMode(TRANSPARENT); //TRANSPARENT或OPAQUE
pDC->SelectObject(...)

就可以实现修改某个控件的绘制属性。具体的实现可以参考下面的一段代码:

//
//m_font1与m_font2为CTestDlg的成员,类型为CFont
//
BOOL CTestDlg::OnInitDialog()
{
......
// TODO: Add extra initialization here
m_font1.CreatePointFont(120, TEXT("Impact"));
m_font2.CreatePointFont(120, TEXT("Arial"));
......
} HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here
if (nCtlColor == CTLCOLOR_STATIC)
{
switch (pWnd->GetDlgCtrlID())
{
case IDC_STATIC_1:
pDC->SetTextColor(RGB(255, 0, 0));
pDC->SetBkColor(RGB(255, 255, 255));
pDC->SetBkMode(TRANSPARENT);
pDC->SelectObject(&m_font1);
return (HBRUSH)::GetStockObject(BLACK_BRUSH);
break;
case IDC_STATIC_2:
pDC->SetTextColor(RGB(255, 255, 0));
pDC->SetBkColor(RGB(255, 255, 255));
pDC->SelectObject(&m_font2);
return (HBRUSH)::GetStockObject(BLACK_BRUSH);
break;
default:
break;
}
} // TODO: Return a different brush if the default is not desired
return hbr;
}

当然如果是修改dialog的属性,可以直接在最后的return上返回一个画刷,填充dialog的背景颜色。

上面这种方法只是一种静态的修改,因为所有的属性都是一次性设定好了,似乎没有根据情况进行改变的可能。这个是时候就要用到上面所提到的一种方法:强迫窗口重绘,可用的函数有Invalidate()和UpdateWindow(),两者的区别如下:

Invalidate在消息队列中加入一条WM_PAINT消息,其无效区为整个客户区。而UpdateWindow直接发送一个WM_PAINT消息,其无效区范围就是消息队列中WM_PAINT消息(最多只有一条)的无效区。效果很明显,调用Invalidate之后,屏幕不一定马上更新,因为WM_PAINT消息不一定在队列头部,而调用UpdateWindow会使WM_PAINT消息马上执行的,绕过了消息队列。如果你调用Invalidate之后想马上更新屏幕,那就加上UpdateWindow()这条语句。

那么剩下的事情就比较简单了,可以通过设置一个COLORREF m_BrushColor;的成员变量,在调用窗口重绘的函数之前,修改m_BrushColor,然后在OnCtlColor函数中将画刷的颜色创建为该m_BrushColor:

m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(m_BrushColor); //创建一把黄色的背景刷子

下面是我所修改的函数:

HBRUSH ChandControllerDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: 在此更改 DC 的任何特性
if((CTLCOLOR_SCROLLBAR)&&(pWnd->GetDlgCtrlID()==IDC_SLIDER1 || pWnd->GetDlgCtrlID()==IDC_SLIDER2))
{ //此处设置背景的颜色
m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(RGB(0,255,0)); //创建一把黄色的背景刷子
return m_bkBrush;
} if((CTLCOLOR_BTN)&&(pWnd->GetDlgCtrlID()==IDOK))
{
m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(RGB(0,255,0)); //创建一把黄色的背景刷子
return m_bkBrush;
}
m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(m_BrushColor); //创建一把黄色的背景刷子 // TODO: 如果默认的不是所需画笔,则返回另一个画笔
return m_bkBrush;
}

通过上面的函数,可以实现对对话框中的控件或者对话框的背景颜色进行动态修改。


2015-10-31 调试记录 张朋艺

【VS开发】VS2010 MFC中控件、对话框等背景颜色动态修改的方法的更多相关文章

  1. VC编程中如何设置对话框的背景颜色和静态文本颜色

    晚上编一个小程序,涉及到如何设置对话框的背景颜色和静态文本颜色.这在VC6.0中本来是一句话就搞定的事.在应用程序类中的InitInstance()函数添加: //设置对话框背景和文本颜色 SetDi ...

  2. MFC中控件的TAB顺序 ----转载

    在MFC中添加控件后,按Ctrl+d可以改变控件TAB顺序,怕自己忘了,一个神奇的东西,记下. 关于改变Tab顺序的方法有以下几种: 方法一:在动态创建控件的时候STYLE设置成为WS_CHILD|W ...

  3. MFC中控件的TAB顺序

    本文来自: http://hi.baidu.com/qingcaichongch/item/47f7ae14de8cbef6ddeeca42 在MFC中添加控件后,按Ctrl+d可以改变控件TAB顺序 ...

  4. VS2010 MFC中 单独添加ODBC数据库记录集类(CRecordset)方法

    基于VS2010 MFC的项目是之前建好的,后来需要添加数据库. 方法分享于此. 1.  打开自己的项目,项目->添加类. 2. 选MFC ODBC使用者,点右下角的添加. 3. 点数据源. / ...

  5. VC 对话框设置背景颜色和图片

    改变背景颜色,有两种方法: 1.在app的初始化函数中调用:void SetDialogBkColor( COLORREF clrCtlBk = RGB(192, 192, 192), COLORRE ...

  6. VS2008给对话框添加背景颜色

    第一种方法如下: 在对话框OnPaint()函数中添加代码 //改变对话框背景颜色 CRect rect; CPaintDC dc(this); GetClientRect(rect); dc.Fil ...

  7. VS2010/MFC:模态对话框及其弹出过程

    模态对话框及其弹出过程 加法计算器对话框程序大家照着做一遍后,相信对基于对话框的程序有些了解了,有个好的开始对于以后的学习大有裨益.趁热打铁,这一节讲讲什么是模态对话框和非模态对话框,以及模态对话框怎 ...

  8. VS2010/MFC编程(对话框:模态对话框及其弹出过程)

    讲讲什么是模态对话框和非模态对话框,以及模态对话框怎样弹出. 一.模态对话框和非模态对话框 Windows对话框分为两类:模态对话框和非模态对话框. 模态对话框是这样的对话框,当它弹出后,本应用程序其 ...

  9. MFC 中控件的启用与禁用

    启用和禁用控件可以调用CWnd::EnableWindow 函数. BOOL EnableWindow(BOOL bEnable = TRUE); 判断控件是否可用可以调用 CWnd::IsWindo ...

随机推荐

  1. Android Studio 3.5.2添加依赖库

    因为要连接服务器的数据库,百度了一下经验,需要添加一些mysql库,看了一下经验,没有找到3.5.2版本的添加依赖库的教程. 因为新版本的androidstudio有一些不同,作以记录. 比如我们要添 ...

  2. Codeforces Round #554 (Div. 2) F2. Neko Rules the Catniverse (Large Version) (矩阵快速幂 状压DP)

    题意 有nnn个点,每个点只能走到编号在[1,min(n+m,1)][1,min(n+m,1)][1,min(n+m,1)]范围内的点.求路径长度恰好为kkk的简单路径(一个点最多走一次)数. 1≤n ...

  3. GitHub 基础搜索技巧

    一.GitHub基本信息栏 1.项目名称 2.项目简介 3.项目的README.md文档 ​ 项目的详细介绍 4.项目的最后更新时间 ​ 是否还有人维护等等... 二.搜索方式列举 1. 在name\ ...

  4. 1、python--第一天练习题

    #1.使用while循环输入 1 2 3 4 5 6 8 9 10 k = 0 while k < 10: k += 1 if k == 7: continue print(k) #2.求1-1 ...

  5. 独立看门狗 IWDG

    一,独立看门狗 二,独立看门狗的时钟源 独立看门狗拥有自己的时钟源,不依赖PLL时钟输出的分频信号,能够独立运行,这样子的好处就是PLL假如受到干扰, 导致运行异常,独立的看门狗还能正常地进行工作,如 ...

  6. HDU 1087 Super Jumping! Jumping! Jumping! ——(LIS变形)

    和之前那个长方体最大高度是换汤不换药的题目.每次找之前最大的一个能接的接上即可.代码如下: #include <stdio.h> #include <algorithm> #i ...

  7. slax linux的定制

    由于数据结构教学的需要,需要用到linux,要求就是小,启动快,可定制性强,恰好slax正好满足要求,以下就是定制slax linux的过程记录: 什么是Slax Slax是一个基于Linux的Liv ...

  8. [题解] [SDOI2015] 序列统计

    题面 题解 设 \(f[i][j]\) 代表长度为 \(i\) 的序列, 乘积模 \(m\) 为 \(j\) 的序列有多少个 转移方程如下 \[ f[i + j][C] = \sum_{A*B\equ ...

  9. tmux 入门踩坑记录

    软件安装 sudo apt-get install tmux 1. 分割左右窗口 ^b -> % 运行 tmux 新建一个 tmux 的会话(session),此时窗口唯一的变化是在底部会出现一 ...

  10. Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

    Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...