电信主站 网通分站
购买流程 付款方式 常见问题 在线提问 续租服务 购物车
用户名: 密 码: 忘记密码?
首 页
域名注册
虚拟主机
双线主机
服务器租用
VPS主机
企业邮局
代理专区
客服中心
虚拟主机行业资讯 虚拟主机评测对比 互联网最新动态 技术学院 站长资讯 在线教程 网站运营
搜索优化 服务器 网络编程 图形图象 站长之家 网页制作 操作系统
冲浪宝典 软件教学 视频通信 办公软件 邮件系统 网络安全 认证考试
您当前位置:西部数码->资讯中心-> 在线教程-> ASP
创建有个性的对话框之MFC篇(一)
作者:网友供稿 点击:90
  西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!虚拟主机可在线rar解压,自动数据恢复设置虚拟目录等.虚拟主机免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金!
文章页数:[1] 
想使自己的软件与众不同就要给软件加点“色”,一个颜色搭配协调的窗口要比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;
  }
}

 


文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!
相关主题
文章页数:[1] 
Google
热门文章
·如何使XP的目录属性出现"安全"选项-ASP教程,系统相关
·创建有个性的对话框之MFC篇(二)-ASP教程,系统相关
·用InstallShield打包ASP程序-ASP教程,ASP应用
·windows server 2003 中 SQL Server 2000 分布式事务 错误解决方法-ASP教程,系统相关
·创建有个性的对话框之MFC篇(一)-ASP教程,系统相关
·DevExpress打印相关代码-ASP教程,打印相关
·File文件控件,选中文件(图片,flash,视频)即立即预览显示-ASP教程,组件开发
·用Windows的文件映射机制,实现大批量数据的快速存储-ASP教程,系统相关
·ADO如何取得数据库中表的字段信息之一
·使用DEVEXPRESS部件打印时标题的处理-ASP教程,打印相关

最新文章
· SQL注入天书 - ASP注入漏洞全接触
·用.net 处理xmlHttp发送异步请求
·asp.net创建文件夹的IO类的问题
·如何实现ASP.NET网站个性化
·关于ASP.NET调用JavaScript的实现
·ASP利用Google实现在线翻译功能
·Asp无组件生成缩略图
·由HTTP 500 Internal server error想到的...
·实例讲解asp抓取网上房产信息
·改mdb为asp所带来的灾难




版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
  打印  刷新  关闭
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 虚拟主机 | 资讯中心 | 友情链接 | 网站地图

版权所有 西部数码(www.west263.com)
CopyRight (c) 2002~2006 west263.com all right reserved.
公司地址:四川成都市万和路90号天象大厦4楼 邮编:610031
电话总机:028-86262244 86263048 86263408 86263960 86264018 86267838
售前咨询:总机转201 202 203 204 206 208
售后服务:总机转211 212 213 214
财务咨询:总机转224 223 传真:028-86264041 财务QQ:点击发送消息给对方635483282
售前咨询QQ:点击发送消息给对方2182518 点击发送消息给对方241975952 点击发送消息给对方275026793 点击发送消息给对方408235859
售后服务QQ:点击发送消息给对方17708515 点击发送消息给对方307742704 点击发送消息给对方287976517 点击发送消息给对方363783715
《中华人民共和国增值电信业务经营许可证》编号:川B2-20030065号