http://blog.csdn.net/wangchyz/article/details/6795419   简单的dui例子实现
http://bbs.csdn.net/topics/340239295  dui的简单帖子总结
http://bbs.pediy.com/showthread.php?t=124957 dui的例子实现
http://www.buguw.com/%e8%bd%ac-directui%e7%9a%84%e5%88%9d%e6%ad%a5%e5%88%86%e6%9e%90.html dui的函数总结
http://sogoodlife.blog.163.com/blog/static/45850260201261154229868/   dui对xml文件的解析过程
http://sogoodlife.blog.163.com/blog/static/458502602012610508332/ dui的消息处理过程
http://blog.csdn.net/jofranks/article/details/11853507  dui的处理流程
http://blog.sina.com.cn/s/blog_4c3b2dc20100s8w6.html dui的处理流程

以viksoe的duilib为例总结下。
分两步分析direct ui的原理,dui程序的启动和对xml布局文件的解析
一。dui程序的启动
窗口create之后,进入CPaintManagerUI::MessageLoop.这个消息类似mfc的消息循环机制。
先在 CPaintManagerUI::TranslateMessage中取出本窗口的消息,然后进入所有的CPaintManagerUI::PreMessageHandler函数,过滤出快捷按键,alt键
的消息.接着进入大窗口注册的CWindowWnd::__WndProc窗口过程,处理WM_NCCREATE消息。在这个窗口过程中进入每个窗口注册的MessageHandler函数消息,即每个类重载的HandleMessage函数,比如duilib的例子
  LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        if( uMsg == WM_CREATE ) {
            m_pm.Init(m_hWnd);
            CDialogBuilder builder;
            CControlUI* pRoot = builder.Create(_T("test1.xml"), (UINT)0, NULL, &m_pm);
            ASSERT(pRoot && "Failed to parse XML");
            m_pm.AttachDialog(pRoot);
            m_pm.AddNotifier(this);
            Init();
            return 0;
        }
xxxx
    }
可以看到这里调用CDialogBuilder::Create用来加载解析xml布局文件。
在这个HandleMessage最后调用CPaintManagerUI::MessageHandler来处理各种WM_CLOSE,WM_PAINT,WM_SIZE,
WM_MOUSEMOVE,WM_LBUTTONDOWN等各种按键和鼠标消息。比如处理WM_LBUTTONDOWN,
先获取鼠标坐标位置,根据这个坐标通过FindControl找到拥有鼠标位置的控件。找到后,给找到的控件设置焦点,
然后通过 pControl->Event,给控件发一个消息,类似mfc的msg,包含type、ptMouse、wParam、chKey、lParam等。
接着进入控件的CButtonUI::DoEvent函数,
void CButtonUI::DoEvent(TEventUI& event)
{
    if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
        if( m_pParent != NULL ) m_pParent->DoEvent(event);
        else CLabelUI::DoEvent(event);
        return;
    }
    xxxx
    if( event.Type == UIEVENT_BUTTONUP )
    {
        if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
            if( ::PtInRect(&m_rcItem, event.ptMouse) ) Activate();
            m_uButtonState &= ~(UISTATE_PUSHED | UISTATE_CAPTURED);
            Invalidate();
        }
        return;
    }
    if( event.Type == UIEVENT_KILLFOCUS ) 
    xxxxxx
}
Invalidate是触发一次重绘,在重绘前先通过SendNotify去注册的控件中通知消息的发生。
void CPaintManagerUI::SendNotify(TNotifyUI& Msg, bool bAsync /*= false*/)
{
xxx
 for( int i = 0; i < m_aNotifiers.GetSize(); i++ ) {
            static_cast<INotifyUI*>(m_aNotifiers[i])->Notify(Msg);
        }  
xxx
}
可以看出系统向所有注册INotifyUI接口的发送消息。所以如果我们想处理这种鼠标,按键消息的话,需要实现
INotifyUI接口,然后注册。比如
void CSearchPageWnd::Notify(TNotifyUI& msg)
{
   if( msg.sType == _T("click") ) 
   {
      if( msg.pSender->GetName() == _T("ok") ) {
         CStandardPageWnd* pWindow = new CEditPageWnd;
         pWindow->Create(m_hWnd, NULL, UI_WNDSTYLE_FRAME, 0L);
      }
      if( msg.pSender->GetName() == _T("cancel") ) Close();
   }
   CStandardPageWnd::Notify(msg);
}
处理单击消息,消息来源是ok按键,
从上看出,自己实现注册消息处理函数主要从Notify和HandleMessage函数中。

二。对xml布局文件的解析
上面跟踪到调用CDialogBuilder::Create用来加载解析xml布局文件.展示窗口。进入该函数,
CControlUI* CDialogBuilder::Create(xxx)
{
  CMarkupNode root = m_xml.GetRoot();
  for( CMarkupNode node = root.GetChild() ; node.IsValid(); node = node.GetSibling() ) {
    pstrClass = node.GetName();
         if( _tcscmp(pstrClass, _T("Image")) == 0 ) {
                    pstrName = root.GetAttributeName(i);
                    pstrValue = root.GetAttributeValue(i);
                    if( _tcscmp(pstrName, _T("size")) == 0 ) {
                         pManager->SetInitSize(cx, cy);
  xxxxxxxx
可以看出是解析xml文件,取出节点,然后看节点的名字pstrClass,匹配时image,Font,Default,Window等各种控件。
取出控件名字后,取出pstrName属性名,根据属性名字调用对应的函数,比如上面进入SetInitSize函数后
  ::SetWindowPos(m_hWndPaint, NULL, 0, 0, cx, cy, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
设置窗口大小。
最后递归的调用 CDialogBuilder::_Parse函数解析子节点,在这个函数中,根据节点名称的字符个数,在堆中new 出对应的控件,
没有新的窗口句柄,如下所示。
   SIZE_T cchLen = _tcslen(pstrClass);
            switch( cchLen ) {
            case 4:
                if( _tcscmp(pstrClass, _T("Edit")) == 0 )                   pControl = new CEditUI;
                else if( _tcscmp(pstrClass, _T("List")) == 0 )              pControl = new CListUI;
                else if( _tcscmp(pstrClass, _T("Text")) == 0 )              pControl = new CTextUI;
                break;
            case 5:
                if( _tcscmp(pstrClass, _T("Combo")) == 0 )    
子控件创建出来后通过pContainer->Add(pControl) 添加到父容器控件中,然后处理子控件的属性信息,如下
if( node.HasAttributes() ) {
            xxxx
            for( int i = 0; i < nAttributes; i++ ) {
                pControl->SetAttribute(node.GetAttributeName(i), node.GetAttributeValue(i));
            }
解析完xml文件后,对应的窗口就创建出来了,然后注册notify接口,ShowWindow就可以响应消息了。

通过分析,自己实现dui的例子时,三步做。先包含dui的库,然后实现notify和HandleMessage响应各种消息函数。
最后编写xml布局文件,在程序入口处create然后ShowWindow.

wtl的界面实现,类似direct ui,需要继承CFrameWindowImpl,CMessageFilter等类。
在CFrameWindowImpl中实现了消息循环的过程,只需要create和showWindow就可以展现窗口。
通过DECLARE_FRAME_WND_CLASS实现窗口资源和窗口类的绑定,然后通过继承覆盖,父类调用自己的实现类的窗口处理函数。

---写于2013.11.17

direct UI总结相关推荐

  1. Direct UI 思想阐述

    在界面开发中,目前DirectUI是个热门的技术名称,因为众多的知名公司都是用DirectUI方式作出了很炫丽的界面.而对于大多数熟悉Win32控件,熟悉MFC开发的开发人员来说,我们应该做何选择? ...

  2. MFC和QT等UI框架的特点

    UI设计的3大原则: 面向对象: MVC: 消息队列驱动: 直到现在各个UI系统,包括题主所提到的MFC.WPF.Qt,也包括其它,诸如Android SDK.Cocoa的构建仍旧建立在这3大原则的基 ...

  3. 关于UI开发(总结一些技术和一些论坛牛人讨论)

    1,MFC 基于VC6.0的微软基础库 2,WPF 做绚丽界面一律用WPF,做一般绚丽界面用WinForm,做windows标准界面用MFC WPF也有个致命缺点,就是要.net framework支 ...

  4. 转: 关于UI开发(总结一些技术和一些论坛牛人讨论)

    1,MFC 基于VC6.0的微软基础库 2,WPF 做绚丽界面一律用WPF,做一般绚丽界面用WinForm,做windows标准界面用MFC WPF也有个致命缺点,就是要.net framework支 ...

  5. 以 DirectUI 方式实现的ImageButton

    [文章归类] C++,Windows 应用程序开发. 这是一篇比较简单的文章,主要讲解的是用 DirectUI 方式实现的对话框上的按钮.例如,QQ界面上的按钮.我在前一篇文章中讲解的 PS 油画滤镜 ...

  6. FireMonkey 平台初探

    最为第一个本地化跨平台的框架:FireMonkey需要处理以及融合不同平台的技术非常之多,所以目前的测试仅仅在于表面现象,至于效率问题还不得而知. 从一个程序员的角度来看这个框架,我觉得有以下这些方面 ...

  7. 几个年薪百万的下属,爆了~

    阅读本文大概需要7分钟. 请原谅有点标题党,今天重点谈谈曾经带过的几名优秀下属,至于是不是年薪百万倒没那么重要. 最近读者增速飞快,尤其是大学生和刚工作一两年的朋友,不少读者朋友加了我微信的第一个问题 ...

  8. delphi 龙年窗体 恭喜发财

    单窗体实现的功能,火珠点击关闭窗体 具说direct UI的实现也是这个原理,但是输入框怎么实现,有了解的可以讨论下,窗体叠加就不是谈了. 不要只看不评论啊. 点击下载

  9. 客户端开发GUI框架对比与技术选型总结

    客户端开发GUI框架对比与技术选型总结 客户端开发技术日新月易,目前客户端开发的GUI框架选型大致会从以下几个技术路线中进行选择: 纯系统原生GUI库 第三方库 基于Chromium + Node.j ...

最新文章

  1. R语言distMeeus函数计算大圆距离实战(Great Circle Distance)
  2. Ubuntu中安装Pycharm
  3. 前端project师养成记:开发环境搭建(Sublime Text必备插件推荐)
  4. Linux学习-仅执行一次的工作排程
  5. python 下标越界_Python中异常处理
  6. linux mysql主从配置_linux下mysql主从配置
  7. 网站漏洞扫描工具_如何实现免费网站漏洞扫描?推荐一款神器给你
  8. mysql、sqlserver、oracle各数据类型与java类型对应
  9. openGauss 分区表索引
  10. react 父子传值_React父子组件传值
  11. 台电t30_数码:台电发布T30平板电脑,10.1英寸/p70处理器/4+64GB内存组合
  12. ipconfig默认网关为空_网络工程师之IPCONFIG命令详解
  13. CNN 总结 模型归类
  14. java中常量有初始化值吗,Java基础_变量、常量
  15. APP运营推广超级攻略(2015新版)
  16. 10个谷歌浏览器调试技巧
  17. 领导人要读的10本管理学书籍
  18. 【基础知识】Dom基础
  19. 复盘:霍夫曼编码平均长度计算方式,信源符号a1-a6概率为:0.1,0.4,0.06,0.1,0.04,0.3,霍夫曼编码平均长度是
  20. Kalman详尽原理介绍合集

热门文章

  1. 计算机专业美术课教案,教案《电脑美术》教学设计
  2. 春秋云镜 CVE-2022-30887 多语言药房管理系统 (MPMS) [超详细新手教程]
  3. 指针数组的概念和定义方式
  4. 【C++系列P7】模板搞不懂?脑阔抖三抖!!精讲一篇过!
  5. 事业合伙人制度研究报告
  6. 12款AI代码生成工具,都很能打
  7. 数据库安装报错:ins 30131
  8. 在C#中以编程方式将 MS Project MPP 转换为 Word 文档
  9. js在线预览pdf,doc,xls,jpg等文件
  10. 快排中的Partition函数