zoukankan      html  css  js  c++  java
  • 研究Duilib的实现结构

    第一步:调用RegisterClassEx();

    第二步:调用CreateWindowEx()

    第三步:调用ShowWindow(),同时启动消息循环

     

    说明:

    1、RegisterClassRegisterClassEx

     作用:向Windows操作系统注册窗口类型

    WNDCLASSEX结构体中的WNDPROC 为一回调函数,如下:

    LRESULT CALLBACK CWindowWnd::__WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

    在这个回调函数中,可以响应该窗口的各种系统消息、键盘鼠标消息、用户自定义的消息。

     所有的窗口继承自CWindowWnd,WindowImplBase继承自CWindowWnd,(用户自定义的窗口(如CMainWnd)从WindowImplBase派生)

    __WndProc回调函数中调用WindowImplBase类的HandleMessage函数,

    HandleMessage函数中对各种消息进行分别处理,如OnCreate、OnDestroy、OnSize、OnLButtonDown、OnTimer等,

    2、CreateWindow,CreateWindowEx

    作用:创建窗口类对象

    应用项目的入口函数WinMain的第一个参数HINSTANCE实例句柄,渲染类CPaintManagerUI必须与之关联,即:

    CPaintManagerUI::SetInstance(hInstance);

     在RegisterClassEx、CreateWindowEx 时都需用到此句柄。

     3、设置skin资源目录的位置

    CPaintManagerUI::SetResourcePath,或使用压缩包:CPaintManagerUI::SetResourceZip

     

     

    4、CWindowWnd::ShowModal (或ShowWindow + CPaintManagerUI::MessageLoop(),MessageLoop函数中有消息循环)

    显示已Create的窗口,同时添加消息循环,

    MSG msg = { 0 };

     while(::GetMessage(&msg, NULL, 0, 0))

    {

      if( !CPaintManagerUI::TranslateMessage(&msg) )

       {
        ::TranslateMessage(&msg); //将虚拟键消息转换为字符消息。GetMessagePeekMessage时被读出
        ::DispatchMessage(&msg); //分发一个消息给窗口程序
      }

      if( msg.message == WM_QUIT ) break;

    }

    CPaintManagerUI::TranslateMessage 负责分发消息,按窗口类型分为2种:CHILD类型、非CHILD类型,

    这两种类型都会遍历当期应用的所有窗口和控件,逐个与当前MSG的hwnd进行比对,然后调用对应窗口或控件的MessageHandler

    CHILD类型的不同之处在于:会获取当前MSG的hwnd的父窗口,然后与缓存的所有控件或窗口进行比较。

    所有的控件和窗口继承自基类:IMessageFilterUI,重写虚函数MessageHandler,在此函数中响应系统消息、键鼠消息。

     CPaintManagerUI中有静态变量 static CStdPtrArray m_aPreMessages;    缓存的是所有的 CPaintManagerUI 对象

     有成员变量 CStdPtrArray m_aPreMessageFilters;  缓存的是所有的窗口对象。

    CPaintManagerUI::TranslateMessage 中先遍历 m_aPreMessages,找到当期MSG所属的CPaintManagerUI 对象(通过匹配HWND)

    再调用该对象所属的m_aPreMessageFilters对应的所有窗口类的MessageHandler函数,

    这些窗口类包括:WindowImplBase的派生窗口、CComboUI、CMenuUI等

    5、SubClassWindow   子类化

     (http://blog.csdn.net/weiaipan1314/article/details/51888742)

    每一个Windows窗口如EDIT]都有一个窗口处理函数负责对消息处理,子类化的办法就是用我们自己的消息处理函数来替代窗口原有的、标准的处理函数。

    当然我们自己的窗口处理函数只是关心那些特定的消息[WM_CHAR],而其它消息,再发给原来的窗口函数处理。

    在SDK中的实现方法是调用函数SetWindowLong :

      WNDPROC * oldWndProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC,(DWORD)AfxGetAfxWndProc()); 其中AfxGetAfxWndProc()使用我们自己的窗口处理函数.

    6、加载和显示图片机制

    所有的图片在第一次加载时都会缓存在一个CStdStringPtrMap对象中,类似于std::map,再次使用这个图片时,使用的缓存中图片资源

    所以如果我们的应用显示过的图片特别多,会导致应用占用的内存越来越大,并且是只增不减。

    除非调用CPaintManagerUI中的RemoveImage函数,主动从缓存中移除不再使用的图片。

    7、CRenderEngine类中汇集了DrawImage、DrawText、DrawColor、DrawLine、DrawRect等处理UI的功能函数,

    DrawImage底层调用的是windows图形设备接口函数:BitBlt、StretchBlt、AlphaBlend(绘制有透明度的图像)

    DrawText底层调用的是:GDI+的DrawString,或系统的DrawText。(透明窗口上的文本使用前者)

    DrawColor底层调用GDI+的FillRectangle

    DrawLine底层调用GDI+的DrawLine(另一个版本使用的是wingdi的 MoveToEx、LineTo)

    DrawRect底层调用GDI+的DrawRectangle(另一个版本使用的是wingdi的::Rectangle)

    8、CDialogBuilder 加载窗口或控件指定的xml文件,解析,然后创建对应的窗口或控件,返回窗口或控件的指针。

    9、所有的控件(不包括窗口)派生自CControlUI,重写虚函数SetAttribute,在此函数中解析各自特有的属性字段,

  • 相关阅读:
    javascript 之异常处理try catch finally--05
    javascript 之基本包装类型--04
    javascript 之基本数据类型、引用数据类型区别--02
    javascript 之数据类型--01
    CSS3 object-fit 图像裁剪
    jQuery.extend 使用函数
    ios 不支持iframe 解决方案
    python常用代码积累
    mysql日志类型
    python中列表 元组 字符串如何互相转换
  • 原文地址:https://www.cnblogs.com/pjl1119/p/7954712.html
Copyright © 2011-2022 走看看