博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
VS2010 MFC中控件、对话框等背景颜色动态修改的方法
阅读量:4303 次
发布时间:2019-05-27

本文共 2775 字,大约阅读时间需要 9 分钟。

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

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

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

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

 
  1. pDC->SetTextColor(RGB(255, 0, 0)); //设置文本前景色

  2. pDC->SetBkColor(RGB(255, 255, 255)); //设置文本背景色

  3. pDC->SetBkMode(TRANSPARENT); //TRANSPARENT或OPAQUE

  4. pDC->SelectObject(...)

  • 1
  • 2
  • 3
  • 4
  • 5

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

 
  1. //

  2. //m_font1与m_font2为CTestDlg的成员,类型为CFont

  3. //

  4. BOOL CTestDlg::OnInitDialog()

  5. {

  6. ......

  7. // TODO: Add extra initialization here

  8. m_font1.CreatePointFont(120, TEXT("Impact"));

  9. m_font2.CreatePointFont(120, TEXT("Arial"));

  10. ......

  11. }

  12.  
  13. HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

  14. {

  15. HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

  16.  
  17. // TODO: Change any attributes of the DC here

  18. if (nCtlColor == CTLCOLOR_STATIC)

  19. {

  20. switch (pWnd->GetDlgCtrlID())

  21. {

  22. case IDC_STATIC_1:

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

  24. pDC->SetBkColor(RGB(255, 255, 255));

  25. pDC->SetBkMode(TRANSPARENT);

  26. pDC->SelectObject(&m_font1);

  27. return (HBRUSH)::GetStockObject(BLACK_BRUSH);

  28. break;

  29. case IDC_STATIC_2:

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

  31. pDC->SetBkColor(RGB(255, 255, 255));

  32. pDC->SelectObject(&m_font2);

  33. return (HBRUSH)::GetStockObject(BLACK_BRUSH);

  34. break;

  35. default:

  36. break;

  37. }

  38. }

  39.  
  40. // TODO: Return a different brush if the default is not desired

  41. return hbr;

  42. }

 

当然如果是修改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:

 
  1. m_bkBrush.DeleteObject();

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

  3.  

    下面是我所修改的函数:

     
  4. HBRUSH ChandControllerDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

  5. {

  6. HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);

  7.  
  8. // TODO: 在此更改 DC 的任何特性

  9. if((CTLCOLOR_SCROLLBAR)&&(pWnd->GetDlgCtrlID()==IDC_SLIDER1 || pWnd->GetDlgCtrlID()==IDC_SLIDER2))

  10. {

  11.  
  12. //此处设置背景的颜色

  13. m_bkBrush.DeleteObject();

  14. m_bkBrush.CreateSolidBrush(RGB(0,255,0)); //创建一把黄色的背景刷子

  15. return m_bkBrush;

  16. }

  17.  
  18. if((CTLCOLOR_BTN)&&(pWnd->GetDlgCtrlID()==IDOK))

  19. {

  20. m_bkBrush.DeleteObject();

  21. m_bkBrush.CreateSolidBrush(RGB(0,255,0)); //创建一把黄色的背景刷子

  22. return m_bkBrush;

  23. }

  24. m_bkBrush.DeleteObject();

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

  26.  
  27. // TODO: 如果默认的不是所需画笔,则返回另一个画笔

  28. return m_bkBrush;

  29. }

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

转载地址:http://gjmws.baihongyu.com/

你可能感兴趣的文章
centos虚拟机设置共享文件夹并通过我的电脑访问[增加smbd端口修改]
查看>>
文件拷贝(IFileOperation::CopyItem)
查看>>
MapReduce的 Speculative Execution机制
查看>>
大数据学习之路------借助HDP SANDBOX开始学习
查看>>
Hadoop基础学习:基于Hortonworks HDP
查看>>
为什么linux安装程序 都要放到/usr/local目录下
查看>>
Hive安装前扫盲之Derby和Metastore
查看>>
永久修改PATH环境变量的几种办法
查看>>
大数据学习之HDP SANDBOX开始学习
查看>>
Hive Beeline使用
查看>>
Centos6安装图形界面(hdp不需要,hdp直接从github上下载数据即可)
查看>>
CentOS7 中把yum源更换成163源
查看>>
关于yum Error: Cannot retrieve repository metadata (repomd.xml) for repository:xxxxxx.
查看>>
linux下载github中的文件
查看>>
HDP Sandbox里面git clone不了数据(HTTP request failed)【目前还没解决,所以hive的练习先暂时搁置了】
查看>>
动态分区最佳实践(一定要注意实践场景)
查看>>
HIVE—索引、分区和分桶的区别
查看>>
Hive进阶总结(听课总结)
查看>>
大数据领域两大最主流集群管理工具Ambari和Cloudera Manger
查看>>
Sqoop往Hive导入数据实战
查看>>