原文转自:http://www.cnblogs.com/Alberl/p/3344886.html

一、WindowImplBase的bug
在第8个教程【2013 duilib入门简明教程 -- 完整的自绘标题栏(8)】中,可以发现窗口最大化之后有两个问题,
1、最大化按钮的样式还是没变,正确的样式应该是这样的
2、再次点击最大化按钮,不能还原到正常大小。
这个是WindowImplBase的bug,已经提交给官方有一段时间了,但是貌似没有被合并到SVN上去,所以这里说明一下,
我们需要在WindowImplBase的OnSysCommand函数里,在if( ::IsZoomed(*this) != bZoomed )里面加上下面这段代码:
    if( ::IsZoomed(*this) != bZoomed ){CControlUI* pbtnMax     = static_cast<CControlUI*>(m_PaintManager.FindControl(_T("maxbtn"))); // 最大化按钮 CControlUI* pbtnRestore = static_cast<CControlUI*>(m_PaintManager.FindControl(_T("restorebtn"))); // 还原按钮 // 切换最大化按钮和还原按钮的状态 if (pbtnMax && pbtnRestore) { pbtnMax->SetVisible(TRUE == bZoomed); // 此处用表达式是为了避免编译器BOOL转换的警告 pbtnRestore->SetVisible(FALSE == bZoomed); } }

二、CDuiString的bug (重温了一下 Effective C++,发现这就是条款24所指出的问题,看来读书百遍不如写代码一遍啊)
在Notify处理消息时会有很多if语句,我通常喜欢把常量放在双等号前面,变量放在后面,比如:
if( _T("click") ==  msg.sType )
{
}
但是却发现并没有进到这个if里,调试发现,将常量调到前面时,并没有进入到CDuiString重载的 == 函数里面,所以这里必须将常量放到后面。

if( msg.sType == _T("click") )
{
}
这个bug的原因是因为将常量放在前面时,并没有调用CDuiString重载的 == 函数,而是调用了CDuiString重载的 ()函数,然后用系统自带的==函数做比较,而系统自己的==函数只是比较两个指针的首地址是否相等。_T("click") 的首地址指向的是一块临时变量,而msg.sType 是返回了CDuiString里面那个字符串的指针,很显然这两个指针地址是不相等的,所以我们只能把它放在前面,或者直接调用_tcscmp
if( ! _tcscmp( _T("click"), msg.sType) )
{
}

当然,如果要解决这个bug,就要重载多个==操作符,
由于CDuiString是将==函数作为成员函数重载的,所以只有CDuiString对象在操作符左边时,才会调用这个重载函数,如果想要CDuiString对象在右边时也能调用重载的==函数,那么必须将重载操作符放到外部。这里我们可以看一下MFC的CString是怎么重载的:
CString 重载了5个==操作符,都是友元函数,定义在#include<cstringt.h>里面。
再看下STL的std::string :
std::string重载了3个==操作符,都是全局函数,定义在#include<string>里面。
不过需要提醒的是,我稍微看了下CDuiString的代码,有很多漏洞,比如在清零字符串时,只是调用了 m_szBuffer[0] = '\0'; 并不是调用memset,那么就会有以下问题,我们随意现在用下面两种方式给CDuiString 附值,然后监视字符串数组的内容,可以发现虽然显示是正确的,但是在零值后面的值全部是乱码:
这样的话,虽然_tcslen、_tcscmp等函数能用,但是还有很多函数都会出问题的。
所以这个CDuiString能不用则不用,如果嫌MFC生成的exe体积大,可以用WTL的CString,如果WTL也不想用,那就只好用STL的string了。
当然,为了保证代码的兼容性,一些简单的处理还是用CDuiString比较好,比如 msg.sType。
而逻辑处理等复杂的场景,最好用久经考验的代码。  虽然微软的CString很强大,而用STL的string时可能不方便,但是我现在越来越喜欢STL的string啦,当然,我是定义了一个string_t,加上一个名字空间,以防和一些开源库冲突,
一些著名的开源库喜欢如下定义:
#ifdef _UNICODEtypedef std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > string_t; #else typedef std::basic_string<char, std::char_traits<char>, std::allocator<char> > string_t; #endif

不过我喜欢更简短的定义:

#ifdef _UNICODEtypedef std::wstring string_t;
#elsetypedef std::string  string_t;
#endif

下面是我常用的Unicode定义:

#include <string>
#include <sstream> namespace duilib { #ifdef _UNICODE typedef wchar_t char_t; typedef std::wstring string_t; typedef std::wstringstream stringstream_t; #else typedef char char_t; typedef std::string string_t; typedef std::stringstream stringstream_t; #endif }

转载于:https://www.cnblogs.com/happykoukou/p/7397456.html

duilib入门简明教程 -- 部分bug (11) (转)相关推荐

  1. DuiLib入门简明教程

           Duilib 是一款强大的界面开发工具,可以将用户界面和处理逻辑彻底分离,极大地提高用户界面的开发效率. 国内首个开源 的directui 界面库,开放,共享,惠众,共赢,遵循bsd协议 ...

  2. 2013 duilib入门简明教程 -- 总结 (20)

    原文地址为: 2013 duilib入门简明教程 -- 总结 (20) duilib的入门系列就到尾声了,再次提醒下,Alberl用的duilib版本是SVN上第 387个版本,时间是2013.08. ...

  3. duilib教程之duilib入门简明教程9.界面布局

    上一个教程实现的标题栏代码中,并没有看到处理自适应窗口大小的代码,但是窗口大小变化后,按钮的位置会跟着变化,这是因为我们将按钮放到了HorizontalLayout.VerticalLayout,这样 ...

  4. duilib教程之duilib入门简明教程 -- 界面布局(9)

    上一个教程实现的标题栏代码中,并没有看到处理自适应窗口大小的代码,但是窗口大小变化后,按钮的位置会跟着变化,这是因为我们将按钮放到了HorizontalLayout.VerticalLayout,这样 ...

  5. 2013 duilib入门简明教程 -- 界面布局(9)

    上一个教程实现的标题栏代码中,并没有看到处理自适应窗口大小的代码,但是窗口大小变化后,按钮的位置会跟着变化,这是因为我们将按钮放到了HorizontalLayout.VerticalLayout,这样 ...

  6. duilib入门简明教程 -- VS环境配置(2) (转)

    原文转自:http://www.cnblogs.com/Alberl/p/3342030.html     既然是入门教程,那当然得基础点,因为搜索duilib相关资料时,发现有些小伙伴到处都是编译错 ...

  7. duilib入门简明教程 -- 前言(1) (转)

    原文转自 :http://www.cnblogs.com/Alberl/p/3341956.html 关于duilib的介绍就不多讲了,一来不熟,二来小伙伴们想必已经对比了多个界面库,也无需赘述.下面 ...

  8. duilib入门简明教程 -- 前言(1)

    关于duilib的介绍就不多讲了,一来不熟,二来小伙伴们想必已经对比了多个界面库,也无需赘述.下面进入正题: 不看广告看疗效! 已有众多知名公司采用duilib做为界面库,如华为网盘.金山快盘.酷我音 ...

  9. 2013 duilib入门简明教程 -- 完整的自绘标题栏(8)

    看了前面那么多教程,相信对duilib已有基本映像了,我们就快马加鞭,做出一个完整的自绘标题栏吧~ 看到下面这个效果图,小伙伴们是不是有点惊呆了呢~O(∩_∩)O~ duilib实现以上效果非常简单, ...

最新文章

  1. 学习java 的30个目标
  2. HappyLeetcode50:Rotate Array
  3. placeholder如何实现换行
  4. 求1~100以内的素数,最简单的方式
  5. 包含对象的json格式_如何把JSON数据格式转换为Python的类对象?
  6. mysql在查询结果列表前添加一列递增的序号列(最简)
  7. VN2VN——中小企业的网络融合之道
  8. Atitit.软件硕士  博士课程 一览表 attilax 总结
  9. pycharm中配置Git教程
  10. QQ空间自动删除说说的js脚本(亲测有效)
  11. 软件测试做简历专业技能这样写,还怕没面试机会?
  12. 泛函分析笔记(七) 连续线性算子和连续多重线性映射
  13. 智协云店通+BitCOO扶持TEAx加入4WiN.io全球互贸链 | 翼次元空间+Fund++
  14. unity 引用 移动mm 支付sdk
  15. 用了这么久的消息队列,你知道为什么需要它吗?
  16. 犹太富翁是怎样培养小富翁的?(永远的经典)
  17. Connection Timeout 问题排查
  18. 微信群高效轻松拉人进群,轻松每日爆粉
  19. 计算机网络实践网线制作,网线怎么制作
  20. CSS3图片阴影效果解析

热门文章

  1. Mybatis框架(待完善)
  2. django连接mysql步骤_使用Django连接Mysql数据库步骤
  3. 2008r2配置 iis mysql php_Windows 2008 R2服务器配置文档iis+php+mysql
  4. api报错 javaee maven_maven test 换javaee6 无法加载spring的配置文件 ?报错-问答-阿里云开发者社区-阿里云...
  5. python3解释器执行not 1 and 1_编程语言的分类,python解释器多版本共存.执行python的两种方式,变量,用户与程序交互...
  6. docker $PWD路径_Docker安装Jenkins+Shell脚本自动化部署项目
  7. java考试安徽工业大学_2011~2012《Java语言程序设计》试卷A及答案(安徽工业大学)...
  8. python邮件发送哪个好_python发邮件(一)
  9. 外星人跑深度学习_上海港汇外星人店,51M2020开光追和DLSS2.0畅玩《赛博朋克2077》...
  10. java课程设计进程管理_Java课设总结(个人版)