MFC修改视图CView的背景颜色

摘要:
问题视图的背景通常为白色。默认情况下,它与系统定义的颜色color_WINDOW一致。我们可以使用Windows函数SetSysColors重新指定COLOR_对应于WINDOW的实际颜色来更改视图的背景色。但是,这将同时更改其他应用程序的视图窗口的背景,导致整个Windows系统的颜色设置混乱。通过分析这个问题,我们知道CView的OnDraw函数用于在VC++的文档和视图结构中实现大部分图形渲染工作。

 

(1) 在CYournameView(就是你的视图类,以下以CDrawLineView为例)添加了一个背景颜色变量

 

COLORREF m_bgcolor;

 

(2)修改这个函数:

 

BOOL CDrawLineView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
    cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,0,(HBRUSH)::GetStockObject(m_bgcolor),0); / /这里默认为白色画刷 WHITE_BRUSH ,现在修改为m_bgcolor
return CScrollView::PreCreateWindow(cs);
}

 

(3) 在类V向导里的View添加WM_ERASEBKGND消息,在其函数OnEraseBkgnd(CDC* pDC)添加如下代码:

 

BOOL CDrawLineView::OnEraseBkgnd(CDC* pDC)

 

//这个函数的窗口刷新时自动调用,即可实时变换背景色了
{
// TODO: Add your message handler code here and/or call default
CRect   m_rt;  
GetClientRect(&m_rt);  
CBrush   brush;  
brush.CreateSolidBrush(m_bgcolor);  
pDC->FillRect(&m_rt,&brush);
  
return CScrollView::OnEraseBkgnd(pDC);
}

 

(4)添加一个“背景色”按钮,其相应的响应函数代码如下:

 

void CDrawLineView::OnBgcolor()
{
// TODO: Add your command handler code here
CColorDialog ColorDialog;
if(ColorDialog.DoModal()==IDOK)
   m_bgcolor=ColorDialog.GetColor();
Invalidate(); //这个函数为刷新窗口函数,别忘了啊~~

 

}

 

 

本文来自:http://hi.baidu.com/qi_xian/blog/item/2ca160ef1f6b3813fdfa3cba.html

 

 

 

设置视图背景颜色
对于VC++文档、视结构中的视图,从用户的角度来看,只是可以改变大小、位置的普通窗口,同其他基于Windows应 用程序的窗口是一样的;从程序员的角度来看,视图并不是普通的窗口,而是从MFC库中CView类派生的类对象。像任何VC++对象一样,视图对象的行为 由类的成员函数(数据成员)决定,包括派生类中应用程序定义的函数和从基类继承来的函数。
提出问题
视图的背景一般来说是白色的,在缺 省情况下,它和系统定义的颜色COLOR_WINDOW是一致的。设计者一般会希望自己的程序可以让用户轻松地改变窗口背景颜色,或是用漂亮的图片来充填 背景。我们可以用Windows函数SetSysColors来重新指定COLOR_WINDOW所对应的实际颜色,来达到改变视图背景颜色的目的。但这 样会同时改变其他应用程序的视图窗口背景,使得整个Windows系统的颜色设置产生混乱。另外,我们可能会用以下方法来设置视图的背景颜色,即在 CView的OnDraw函数中添写如下一段程序代码:
void CTestView::OnDraw(CDC* pDC)
{
CTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CRect rectClient;
CBrush brushBkColor;
GetClientRect(rectClient);
brushBkColor.CreateSolidBrush(RGB(255,0,0));
pDC->DPtoLP(rectClient);
pDC->FillRect(rectClient,&brushBkColor);

}
这样可以达到改变当前应用程序的视图背景的目的,但同时也产生了一些不良影响,使得程序运行效果不尽如人意。
分析问题
我 们知道,在VC++的文档、视结构中,CView的OnDraw函数用于实现绝大部分图形绘制的工作。如果用户改变窗口尺寸,或者显示隐藏的区 域,OnDraw函数都将被调用来重画窗口。并且,当程序文档中的数据发生改变时,一般必须通过调用视图的Invalidate(或 InvalidateRect)成员函数来通知Windows所发生的改变,对Invalidate的调用也会触发对OnDraw函数的调用。正因为 OnDraw函数被频繁调用,所以在其执行时,每次都刷新填充一次视图客户区域,便会使屏幕不稳定,产生闪烁现象。
笔者通过对VC++应用程序 框架结构和Windows消息映射系统的仔细研究,找到另外一种改变视图背景的方法,其执行效果比上述两种方法都好。其实在程序调用OnDraw函数之 前,会触发一个Windows消息:WM_ERASEBKGND,以擦除视图刷新区域。在缺省情况下,Windows系统使用视图窗口注册时窗口类中的成 员hbrBackground所描述的画刷来擦除屏幕,这一般会将屏幕刷新成COLOR_WINDOW所对应的颜色。因此,在OnDraw函数中设置背景 颜色的执行过程是这样的:先将屏幕刷新成COLOR_WINDOW所对应的颜色,接着又在OnDraw函数中填充其他颜色,这正是产生屏幕闪烁的根本原 因。
解决问题
通过上述分析,我们应将视图背景颜色填充移到Windows消息:WM_ERASEBKGND所对应的消息映射函数中, 而不是在OnDraw函数中。我们可以通过下列步骤实现这一过程:在文档类中增加一成员变量m_viewBkColor保存当前背景颜色,同时增加两个成 员函数GetViewBkColor和SetViewBkColor对其进行读写操作。这样做的好处是可以对m_viewBkColor成员进行序列化, 将其和文档联系在一起,打开某一文档时,其背景将和上一次程序操作该文档时的背景保持一致。在视图类中为视图的Windows消息 WM_ERASEBKGND增加消息映射函数OnEraseBkgnd,代码如下:
BOOL CTestView::OnEraseBkgnd(CDC* pDC) 
{
CRect rect;
CBrush brush;
brush.CreateSolidBrush(GetDocument()->GetViewBkColor());
pDC->GetClipBox(rect);
pDC->FillRect(rect,&brush);
return true;
}
在该函数中不需要对客户区域矩形进行设备坐标到逻辑坐标的转换,并且Windows在调用该函数时会自动进行裁剪区域的计算,使得需要刷新的屏幕面积达到最小。这样我们可以在程序中通过设计下列菜单函数轻松地改变视图背景的颜色,而且运行效果相当令人满意。
void CTestView::OnChangeViewBkcolor() 
{
CColorDialog cdlg;
if(cdlg.DoModal()==IDOK)
{
GetDocument()->SetViewBkColor
(cdlg.GetColor());
InvalidateRect(NULL);
}
}

 

免责声明:文章转载自《MFC修改视图CView的背景颜色》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇linux下mysql的大小写是否区分设置WebService客户端调用错误处理下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

window.open()不同源页面通信

父页面 运行端口:8080 <template> <div> <el-button @click="open()">发送消息给子页面</el-button> </div> </template> <script> export default{ na...

海康摄像头web观看操作rtmp/hls推流rtsp流转rtmp流

源码介绍:   海康摄像头web端无插件播放是指设置好摄像头参数后,即可在web浏览器不安装任何自定义插件即可实现流程播放。   系统通过拉取海康rtsp流,在用户点击观看时,自动将流转换为rtmp与hls流,推送到自定义流媒体服务器,实现web端 flash播放与html5原生播放。  如有需求,可在线留言或者发消息都可以,看到后会第一时间回复。  ...

SpringBoot在自定义类中调用service层等Spring其他层

背景: 做了一个TCP服务器来接入智能设备,然后需要将设备实时发送的定位等关键信息存储到数据库。为了考虑将来可能对外提供rest接口,采用将TCP服务器集成到SpringBoot框架,当然,也是为了能最快利用mybatis框架实现数据访问,然后依次解决了如何启动,如何注销等各种问题,然后在TCP服务器消息处理时,需要写数据库,直接调用DAO层,编译报错。改...

windows10 中微信(UWP)版本不显示通知消息

前言: 前段时间笔者更换了升级了WINDOWS10系统,从应用商店安装微信后,使用期间不会推送消息通知,右下角的通知栏也无法添加微信图标。搜索百度和Google后,发现很多人都是这样,这是微信(UWP)版本所存在的缺陷。 解决办法: 更换成:微信For Windows版本即可 总结: 下边是一些微信 (UWP)所没有的用户常用功能。 ◆ 缺乏最受用户关注...

第四课——MFC应用程序框架

一、MFC应用程序类型 上篇文章的彩蛋:可通过使用MFC应用程序向导(MFC AppWizard)的功能来创建所需要的应用程序,这意味着不需要输入任何代码。MFC除了应用程序向导,还对应用程序项目有着独特的管理方式。 1. MFC AppWizard   作用:能为用户生成一些常用的标准程序结构和编程风格,它们被称为应用程序框架结构。   提供的应用程序框...

JAX-WS HandlerChain使用详解

JAX-WS的Handler和Servlet的Filter相似,可以对所有WebServicer进行拦截,在Handler中可以记录日志、权限控制、对请求的SOAP消息进行加密,解密等。JAX-WS提供两个Handler接口,LogicalHandler和SOAPHandler。LogicalHandler处理的是Message Payload,只能够访...