zoukankan      html  css  js  c++  java
  • duilib查看过的资料整理

      1、duilib中各个类的简单介绍

      2、源码分析 

      3、各个控件可以设置的属性

      4、duilib的消息流程处理

      5、工程编译入门

      6、MFC中混合使用duilib制作界面

      7、从Win32窗口到duilib

      8、实例:使用duilib开发的简单Windows安装包

      9、duilib各种布局的含义

      10、duilib中V和H布局中的滚动条问题

        

      7 ---> CWindowWnd直接包装了Win32里的窗口函数。

      Win32里有什么窗口函数,无非就是注册、创建、显示、消息循环、窗口回调,注意这些都是全局的C函数,

      CWindowWnd直接以C++的形式包装了这窗口显示基本要素,注意其中窗口回调一定要是静态的可在编译期确定编译地址的。利用传递this指针给类内静态成员函数的做法也很常见。

      CWindowWnd直接抛弃了MFC的所有机制,千万不要再记住MFC里那些烦人的机制了!

     

      部分摘要记录:

      1 ---> 

      CWindowWnd,窗口对象管理父类,主要作用:

      1)        创建窗口。

      2)        窗口消息过程处理。

      3)        提供窗口子类化与超类化接口。

      2.        CDialogBuilder,控件布局类,主要作用:

      1)        读取XML脚本,分析脚本,构建控件树。

      2)        创建控件对象。

      3.        CPaintManagerUI,窗口消息及图形绘制管理器类,与窗口绑定,主要作用:

      1)        绘制控件。

      2)        消息管理。

      3)        事件通知。

      4.        INotifyUI,事件通知抽象类,主要作用:

      1)        重载Notify虚函数,处理事件通知。

      自问自答1:

      CWindowsWnd与CPaintManagerUI的关系?

      duilib本质上没有脱离Windows编程,也就是Windows的核心编程一套API,仍然是使用的。提到Wnd(也就是窗口),你想到什么?当然是窗口显示过程的一套流程,建立窗口样式类(最重要的包括窗口各种属性、窗口名称和窗口过程回调),注册该窗口类,创建窗口,显示窗口,消息循环,处理具体的消息回调过程。

      CWindowsWnd继承于CWnd,对是Wnd的封装,对Win32 窗体的封装。

      传统Windows的绘图又是怎样的呢?窗口CWnd的核心是HWnd,HWnd关于一个HDC,就是跟绘图相关的都被HDC封装了。GDI提供的是一组API,绘图对HDC操作,也就相当于在Wnd上画图了。

      传统Windows里每个控件都是一个窗口,包含上面所说的窗口本质都是一样的,只是形成了父子窗口的关系。

      CPaintManagerUI就是跟duilib与传统windows的结合了。duilib的核心是在窗口上直接画UI,而不是采用一个个子窗口。

      CPaintManagerUI负责这些控件的绘制,同时,这些控件是画在Wnd上的,CPaintManagerUI肯定要负责与CWnd的交互。

      这些交互是什么呢?一个控件可能与父窗口产生的交互是什么?

      a、父窗口刷新,子窗口也会刷新。

      b、父窗口收到鼠标点击,键盘按下事件,一定要找到对应的控件,然后把消息传递给该控件。

      比如鼠标停留在Button上,Button四周显示虚线,这些就是在控件内部要做的处理。

      c、子控件获得某些消息后,最终的消息处理自身是不能处理的(这属于业务逻辑,而不是控件基础功能)。

      能想到的交互就这么些,不同控件能接收的消息不同,内部对消息的基础反映也不同,能给父窗口发送的消息也不一样。

      CPaintManagerUI就完成这样一个交互。

      6 ---> 这个例子给了我很大的启示,我接受到的传统GUI怎么做的,duilib界面怎么做的,有一个对比,很多事情就豁然开朗了。

      传统MFC窗口继承与CWnd,当使用对话框时,资源IDD_DIALOG对应生成一个窗口, CMyDialog子类化(SubClass)这个窗口,SubClass这个词是有误解的,实质是CMyDiglog类托管了窗口的回调过程。

      资源IDD_DIALOG上的每一个控件都会生成一个窗口,在CMyDialog中怎么使用这些窗口呢?GetDlgItem可以通过窗口ID返回窗口类对象,如CRichEdit *pEdit。控件与父窗口的交互过程是这样的,每一个窗口都会有回调函数,系统处理消息,将每个消息发送给对应窗口的回调函数,这些消息将被CWnd或者CEdit以成员函数的方式处理。

      对于控件的逻辑处理,控件将发消息给父窗口,交给父窗口处理(通过向父窗口发送消息的方式)。

      再来看下CDuilib_Dialog(下面代码中命名为CFrameWindowWnd )。

     1 class CFrameWindowWnd : public CWindowWnd, public INotifyUI
     2 {
     3 public:
     4     CFrameWindowWnd() { };
     5     LPCTSTR GetWindowClassName() const { return _T("UIMainFrame"); };
     6     UINT GetClassStyle() const { return UI_CLASSSTYLE_FRAME | CS_DBLCLKS; };
     7     void OnFinalMessage(HWND /*hWnd*/) { delete this; };
     8 
     9     void Notify(TNotifyUI& msg)
    10     {
    11         if( msg.sType == _T("click") ) {
    12             if( msg.pSender->GetName() == _T("closebtn") ) {
    13                 Close();
    14             }
    15         }
    16     }
    17 
    18     LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    19     {
    20         if( uMsg == WM_CREATE ) {
    21             m_pm.Init(m_hWnd);
    22             CControlUI *pButton = new CButtonUI;
    23             pButton->SetName(_T("closebtn"));
    24             pButton->SetBkColor(0xFFFF0000);
    25             m_pm.AttachDialog(pButton);
    26             m_pm.AddNotifier(this);
    27             return 0;
    28         }
    29         else if( uMsg == WM_DESTROY ) {
    30             ::PostQuitMessage(0);
    31         }
    32         LRESULT lRes = 0;
    33         if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
    34         return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
    35     }
    36 
    37 public:
    38     CPaintManagerUI m_pm;
    39 };
    CFrameWindowWnd中只重载了5个函数,前三个都很好理解
    1、GetWindowClassName 返回窗口创建时的窗口名称,创建窗口时需要。
    2、GetClassStyle 返回窗口创建时的样式。这也没什么说的。
    3、OnFinalMessage 这个是对WM_DESTORY消息的再处理。应该是CWindowWnd::HandleMessage里处理WM_DESTORY消息调用了OnFinalMessage虚函数。
    4、NotifyUI 是自绘控件发给CWindowWnd的消息,在这里处理各控件消息即可。控件有各种类型、不同控件也有各种消息。
    5、LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)里面代码都值得仔细揣摩。
    一、
    if( uMsg == WM_CREATE ) {          /* 本窗口创建时 */ 21 m_pm.Init(m_hWnd);     /* CPaintManagerUI 与本窗口的关联 直接关联了m_hWnd */ 22 CControlUI *pButton = new CButtonUI;   23 pButton->SetName(_T("closebtn")); 24 pButton->SetBkColor(0xFFFF0000); 25 m_pm.AttachDialog(pButton);  /* 控件与CPaintManager的关系 */ 26 m_pm.AddNotifier(this); /* 设置了INotify的回调,控件产生的消息都通过此接口返回到CFrameWindowWnd处理,INotify回调接口设置的就是CFrameWindowWnd类 */ 27 return 0; 28 }
    二、
      if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;    /* 消息先交给控件自身处理 */
    24 
    25     return CWindowWnd::HandleMessage(uMsg, wParam, lParam);             /* 控件不处理的话再由窗口来处理 */

    这样CPaintManagerUI 自绘控件、父窗体、INotify接口的关系大致弄清楚了,消息循环机制也大概弄清楚了。
     再看看怎么创建这个窗口的。
    1 if(m_dlgDuilib == NULL)
    2 {
    3         m_dlgDuilib.Create(this->m_hWnd, NULL,     UI_WNDSTYLE_DIALOG & (~( WS_BORDER | WS_CAPTION )) , 0, 0, 0, 800, 600);
    4     }
    5     m_dlgDuilib.CenterWindow();
    6     m_dlgDuilib.ShowWindow(TRUE);
    7 }

      Create函数不是CWnd::Create,应该是对CWnd::Create函数的包装,此函数应该包括了窗体注册(所以需要窗体名字、窗体的大小等参数)。

      7 ---> 解决了6中的一些困惑。

  • 相关阅读:
    Java8 lambda表达式10个示例
    我和阿里云RDS的故事
    Spring Mvc 传递参数要controller出现了400,日期参数全局处理,格式化yyyy-MM-dd 和yyyy-MM-dd HH:mm:ss
    剑指Offer_36_两个链表的第一个公共结点
    剑指Offer_35_数组中的逆序对
    剑指Offer_34_找出字符串中第一个只出现一次的字符
    剑指Offer_33_丑数
    剑指Offer_32_把数组排成最小的数
    剑指Offer_31_整数中1出现的次数(从1到n整数中1出现的次数)
    剑指Offer_30_连续子数组的最大和
  • 原文地址:https://www.cnblogs.com/kanite/p/9544700.html
Copyright © 2011-2022 走看看