精华内容
参与话题
问答
  • DuiLib

    2018-06-19 10:19:39
    1、XML 文件编写配置 注意: 保存为utf-8格式 window节点不能少 name节点的值需要做到整个xml文件唯一。这个值是与代码交互的关键,用于代码中标识这一个控件具体对象。 可以使用HorizontalLayout或者Vertical...
    1、XML 文件编写配置
     注意: 保存为utf-8格式
            window节点不能少
    name节点的值需要做到整个xml文件唯一。这个值是与代码交互的关键,用于代码中标识这一个控件具体对象。
    可以使用HorizontalLayout或者VerticalLayout来进行布局时占位。


    2、将建好的xml文件和所用到的图标文件打包形成一个压缩包(test.zip)。在VS 编译器中导入这个test.zip的资源。


    3、在_tWinMain函数中加入以下代码: 
       CPaintManagerUI::SetInstance(hInstance);  
       CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());   // 设置资源的默认路径(此处设置为和exe在同一目录


    CTestUIDlg *pFrame = new CTestUIDlg(_T("test.xml"));  
    pFrame->Create(NULL, _T("这是一个最简单的测试用exe,修改test.xml就可以看到效果"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);  
    pFrame->CenterWindow();  
    pFrame->ShowModal();  
    CPaintManagerUI::MessageLoop(); //!消息循环  


    4、CTestUIDlg即是我们的对话框类,它继承于WindowImplBase类,WindowImplBase类是一个XML的包装类,封装了常用操作,以方便大家使用。
       它是以XML作为界面描述的,所以用它的时候,我们必须将界面描述写到XML里。


    5、主要的几个函数:
       (1)explicit  CTestUIDlg(LPCTSTR pszXMLPath);构造函数,同其他构造函数一样,做一些初始化操作。传入的参数是xml文件路径,也就是test.xml的路径。
            CTestUIDlg::CTestUIDlg( LPCTSTR pszXMLPath )


        (2) void InitWindow();初始化窗口信息,根据前面xml文件中我们说的控件唯一标识,创建空间,其余功能相当于MFC下的OnInitDialog(),用于一些控件的初始化之类的。
        
        (3) CControlUI* CreateControl(LPCTSTR pstrClassName);用于自定义控件的创建.
     
        (4) void Notify(TNotifyUI& msg);操作消息响应,一般用于点击操作等的响应。用于处理duilib自己定义的一套消息,其消息类型请参见duilib的UIDefine.h。


        (5) LRESULT HandleMessage(UINT uMsg,WPARAM wParam,LPARAM lParam);消息响应,类似于MFC的DefWindowProc()。 
    展开全文
  • Duilib

    2018-03-25 19:59:00
    实现效果图 来原:https://www.jianshu.com/p/4474f7a9b8b6 转载于:https://www.cnblogs.com/mull/p/8646347.html

    实现效果图

    来原:https://www.jianshu.com/p/4474f7a9b8b6

    转载于:https://www.cnblogs.com/mull/p/8646347.html

    展开全文
  • duilib

    2014-10-09 09:27:00
    为什么80%的码农都做不了架构师?>>> ...

    一、Duilib的整体架构


    二、Duilib框架基本流程(Win32创建窗口流程)

             第一步:实例句柄与渲染类关联

                                      CPaintManagerUI::SetInstance(hInstance);

                    CPaintManagerUI::SetResourcePath(LPCTSTRpStrPath)

             第二步: 初始化COM库, 为加载COM库提供支持

                ::CoInitialize

        第三步:创建窗口类

        第四步:调用CWindowWnd::Create创建窗口,Create函数实现了注册窗口,指定回调函数,创建窗口,处理消息等。

        第五步:窗口居中   

                CWindowWnd::CenterWindow

           第六步:处理消息循环

                         CPaintManagerUI::MessageLoop

        第七步:CPaintManagerUI::MessageLoop

                ::CoUninitialize()

    三、Duilib窗口元素的创建机制

        第一步:响应WM_CREATE消息

        第二步:主窗口类与窗口句柄关联

                  m_pm.Init(m_hWnd)

         第三步:加载XML并动态创建界面无素,与布局界面元素

                       CDialogBuilder builder;

                                CDialogBuilderCallbackEx cb;

                                CControlUI* pRoot =builder.Create(_T("skin.xml"), (UINT)0,  &cb, &m_pm);

            第四步:附加控件到HASH表

                    CPaintManagerUI::AttachDialog

                                     InitControls

                                              FindControl

                                                      __FindControlFromNameHash

                                                     pManager->m_mNameHash.Insert

           第五步:添加通知处理

                    CPaintManagerUI::AddNotifier

           第六步:窗口的绘制(以上是窗口的创建过程,通过xml,所有控件都被加载到CPaintManagerUI

                CPaintManagerUI响应WM_PAINT消息,开始双缓存绘图

                         m_pRoot->DoPaint绘背景图 

                     CControlUI::DoPaint

                     CRenderEngine 真正的绘图类

                 pPostPaintControl->DoPostPaint 在背景图上绘制控件

                ::BitBlt 把离屏视图画到主屏上

    四、Duilib消息处理机制:

             第一步:注册消息处理函数

                      在CWindowWnd注册窗口RegisterWindowClass())里,注册消息回调函数(__WndProc);

             第二步:消息分发

                      消息回调函数(处理所有系统发送的消息),然后回调函数通过子类的CMainFrameWnd::HandleMessage对消息进行分发

           非窗口消息通过CMainFrameWnd::HandleMessage调用CPaintManagerUI::MessageHandler进行分发

             第三步:消息循环

                  在CPaintManagerUI类的MessageLoop处理消息循环。

                      接收到消息以后,进入消息回调函数(__WndProc);

    以下内容以鼠标单机Button事件为例:

             第四步:处理控件消息

                      鼠标按下时(WM_LBUTTONDOWN),查找鼠标点击的控件

                      处理控件的鼠标按下消息:通过调用基类CControlUI:: DoEvent,引起子类如CButtonUI::DoEvent事件。

                      子类的DoEvent对不同类型的事件进行处理。通过CPaintManagerUI:: SendNotify回调控件注册的事件。

    //-------------------------------------------------------------------------------------------------

    1.VC6使用记得Project Settings -> C/C++ -> Preprocessor definitions添加_USRDLL,UILIB_EXPORTS。

    2.mfc中新建duilib窗口退出时整个程序退出了,是因为duilib窗口退出时使用了PostQuitMessage(0),使得整个程序退出,换成Close(); 但是不知道什么原因有的duilib窗口先退出了,mfc窗口出非法访问错误也退出了,有的duilib窗口就不会。

    3.建duilib窗口要PostQuitMessage(0);   ::CoInitialize(NULL);

     

    ①:框架程序基本流程

       -> WinMain(入口函数)

    -> CPaintManagerUI::SetResourceInstance  (实例句柄与渲染类关联)

    -> ::CoInitialize  (初始化COM库, 为加载COM库提供支持)

    -> new C360SafeFrameWnd (创建窗口类)

    -> pFrame->Create (注册窗口类与创建窗口)

    ->RegisterSuperclass (注册一个超类 即已有一个窗口类的基上再注册一个窗口类)

    ->RegisterWindowClass(注册窗口类)

    -> ::CreateWindowEx (创建窗口,此时触发 WM_CREATE消息)

    -> HandleMessage  ( WM_CREATE消息处理OnCreate)

    -> pFrame->CenterWindow (窗口居中显示)

    -> CPaintManagerUI::MessageLoop (处理消息循环)

    -> ::CoUninitialize();   (退出程序并释放COM库)

     

    ②:上面的流程图是一个基本的WIN32程序框架,相对于 DUILIB库,此时我们应关心的是窗口上的元素是如何建立起来的。这时我们应关心WM_CREATE的消息处理函数OnCreate的实现

    -> C360SafeFrameWnd:: OnCreate

      -> m_pm.Init(m_hWnd) (主窗口类与窗口句柄关联)

    -> CControlUI* pRoot = builder.Create(加载XML并动态创建界面无素,与布局界面元素,核心函数单独分析 注意:CDialogBuilder并不是一个对话框类)

    -> m_pm.AttachDialog (附加控件数据到HASH表中)

          -> InitControls (初始化控件)

                 ->FindControl

    ->__FindControlFromNameHash

        ->pManager->m_mNameHash.Insert(把控件插入到Hash中)

     

    -> m_pm.AddNotifier增加通知处理

    ③:接下来我们应关心的是XML的加载过程,及XML中的数是如何与窗口类进行关联的

    -> CDialogBuilder::Create (加载XML文件)

    ->  m_xml.LoadFromFile

    -> CMarkup::LoadFromFile (也可从资源文件中加载::LoadResource)

        ->  CMarkup::LoadFromMem(把外部XML数据加入到内存)

    ->  m_xml.GetRoot (获得XML 根结点, 开始解析XML数据)

    ->  "window"  (解析根结点window下的三个公共元素属性)

       ->  "image"  pManager->AddImage(加载设备无关位图并关联到图像HASH中m_mImageHash.Insert)

     ->  "font"  pManager->AddFont(增加字体)

    ->  CPaintManagerUI::AddFont(增加字体 并关联字体数组m_aCustomFonts.Add)

    ->  "default" (增加默认属性 如:垂直滚动条和水平滚动条)

       -> _Parse  (解析具体的控件元素 动态生成控件元素)

                 -> node.GetName (跳过已经解析过的三个元素"image" "font" "default")

    -> _tcscmp (根据元素的名称 动态生成控件"Edit" "List" "Text"  "Combo" "Label" "Button"  "Option" "Slider" "Control" "ActiveX" "Progress"  "Container" "TabLayout" "ListHeader" "TileLayout" "DialogLayout" "VerticalLayout" "ListHeaderItem"  "ListTextElement"  "HorizontalLayout"  "ListLabelElement" "ListExpandElement" "ListContainerElement")

    -> pContainer->Add(pControl)   (增加控件)

    -> m_items.Add(关联于控件数组中)

               -> pControl->SetAttribute设置控件属性

    上面的工作完成了XML数据的加载,并动态生成了控件,把控件加载到了控件列表,建立了与控件相关的HASH。接下来我们应关心的是控件如何显示在界面上的。

    通过上面的源码,我们应关心几个核心类的关联:

    ->首先产生主窗口类:C360SafeFrameWnd,

    ->在主窗口类中放置成变量 CPaintManagerUIm_pm; 与 控件绘制和消息处理关联起来

    ->CPaintManagerUI::MessageHandler WM_PAINT

    ->双缓存绘图 

    -> m_pRoot->DoPaint绘背景图 

    -> CControlUI::DoPaint

    -> CRenderEngine 真正的绘图类

    -> pPostPaintControl->DoPostPaint在背景图上绘制控件

    ->::BitBlt 把离屏视图画到主屏上

     

    当界面元素正常显示后,接下来我们应关心的是如何处理控件的事件

    -> C360SafeFrameWnd:: HandleMessage (应用需要处理的消息及处理函数)

    -> m_pm.MessageHandler(DUILIB库帮我们处理的消息及相关的处理函数)

    -> CWindowWnd::HandleMessage(应用层和 DUILIB都不处理的消息交由系统默认处理)


    //-----------------------------------------------------------------------------------

    CTileLayoutUI: 父类CContainerUI

    四、通用
    1、script
    CMarkup
    CMarkupNode

    2、language
    CUIUtility

    3、multi-thread
    CriticalSection
    AutoCriticalSection
    CMutex
    CAutoMutex
    CEvent
    CAutoEvent
    CManualEvent

    五、主要数据成员
    1、CPaintManagerUI
    CControlUI* m_pRoot: 如果控件是叠加的则存放最下层的控件对象,否则存放第一个创建的控件对象
    CControlUI* m_pFocus: 存放获得焦点的控件对象指针
    CControlUI* m_pEventHover: 存放当前有鼠标移进移出事件的控件对象指针
    CControlUI* m_pEventClick: 存放当前有点击事件的控件对象指针
    CControlUI* m_pEventKey: 存放当前有按键事件的控件对象指针
    CStdPtrArray m_aNotifiers: 记录所有需要事件通知的窗口,根据窗口名称调用相应的消息处理函数
    CStdPtrArray m_aNameHash: 保存控件对象指针hash表(用控件名称生成hash值)

    CStdPtrArray m_aPostPaint: panel的fade效果
    CStdPtrArray m_aMessageFilters: 保存需要进行消息过滤的控件或功能(如动画类)
    CStdPtrArray m_aDelayedCleanup: 
    CStdPtrArray m_aPreMessages: 预处理消息
    HWND m_hWndPaint: 控件布局窗口句柄
    HDC m_hDcPaint: 控件布局窗口设备DC
    HDC m_hDcOffscreen: 离屏内存DC
    HBITMAP m_hbmpOffscreen: 离屏内存DC相关联HBITMAP

    2、CControlUI
    CPaintManagerUI* m_pManager: 窗口消息或绘图管理器
    CControlUI* m_pParent: 逻辑上的父窗口(控件)对象指针
    CStdString m_sName: 控件标识
    CStdString m_sText: 控件显示标题或显示脚本字符串
    CStdString m_sToolTip: 控件的Tip信息

    3、CContainerUI
    CStdPtrArray m_items: 同一层的控件对象或控件对象的子对象,例如canvas上放置的按钮、combox由edit和list两个子对象组成,其它还有tab等。具体见 CDropDownUI、CTabFolderUI、CNavigatorPanelUI三个类定义

    4、CDialogLayoutUI
    CStdValArray m_aModes: 用于存放在Layout上绝对坐标转成相对坐标(CDialogLayoutUI::RecalcArea)的控件对象(指针、大小、模式),目的是否为了让布局上的控件随布局变化而变化,能够正确绘图???

    六、控件属性
    待完成

    七、脚本例子
    <Dialog>
      <WindowCanvas pos=/"0,0,600,800/">
      <DialogLayout pos=/"0,0,600,800/">
        <Button pos=/"390, 30, 490, 58/" text=/"OK/" name=/"ok/"/>
      </DialogLayout>
      </WindowCanvas>
    </Dialog>

    八、绘图及事件处理
    1、绘图
    STEP01. CWindowWnd::__WndProc: 主窗口程序
    STEP02. pThis->HandleMessage: pThis是布局窗口对象指针,并与布局窗口绑定(SetWindowLongPtr)

    STEP03. m_pm.MessageHandler: m_pm为CPaintManagerUI唯一实例对象
    STEP04. CPaintManagerUI::MessageHandler: 处理WM_PAINT
    STEP05. m_pRoot->DoPaint: m_pRoot为最下层的控件对象(在本例中为CWindowCanvasUI控件,对应脚本中的WindowCanvas)
    STEP06. CCanvasUI::DoPaint: 往画布上绘制背景色、边角弧形、水印等。
    STEP07. CContainerUI::DoPaint: 在最下层具有容器特性的控件(CWindowCanvasUI控件)上画容器内所有控件(控件实例对象保存在m_items中)
    STEP08. pControl->DoPaint: pControl为控件对象实例之一,利用多态性来调用不同控件的绘图方法
    STEP09. CButtonUI::DoPaint: 按钮(对应脚本中Button)绘图方法,有下面两种方法
    i)文字方法: CGUIRenderEngineUI::DPaintButton
    ii)图片方法: CGUIRenderEngineUI::DoPaintBitmap
    STEP10. 新一轮消息循环

    2、事件
    STEP01. CWindowWnd::__WndProc: 
    STEP02. pThis->HandleMessage: 
    STEP03. m_pm.MessageHandler: 
    STEP04. CPaintManagerUI::MessageHandler: 处理WM_LBUTTONDOWN
    STEP05. CPaintManagerUI::FindControl: 根据鼠标坐标查找相应控件对象
    STEP06. m_pRoot->FindControl: 
    STEP07. CContainerUI::FindControl: 在最下层具有容器特性的控件(CWindowCanvasUI控件)容器内查找相应控件对象
    STEP08. CControlUI::FindControl: 在m_items中查找相对应的控件对象
    STEP09. pControl->Event: pControl为控件对象实例之一,利用多态性来调用不同控件的事件方法
    STEP10. CPaintManagerUI::MessageHandler: 处理WM_LBUTTONUP

    STEP11. m_pEventClick->Event: 利用多态性来调用不同控件的事件方法(m_pEventClick说明见"主要数据成员")
    STEP12. CButtonUI::Event: 按钮(对应脚本中Button)事件方法
    STEP13. CButtonUI::Activate: 
    STEP14. m_pManager->SendNotify: 传递控件对象指针和触发事件(文本方式)
    STEP15. CPaintManagerUI::SendNotify: 注意以下两点实现是完成控制和业务分离的关键
    i)利用重载特性调用注册的监听对象(窗口)的消息处理函数Notify(监听对象保存在m_aNotifiers中)
    for( int i = 0; i < m_aNotifiers.GetSize(); ++i )
    {
        static_cast<INotifyUI*>(m_aNotifiers[i])->Notify(Msg);
    }
    ii)布局窗口CStartPageWnd的消息处理,宏定义展开后实际就是重载的Notify函数
    DIRECT_BEGIN_NOTIFYMAP(CStartPageWnd)
        PROCESS_BUTTON_CLICK(_T("ok"),OnOk)
        。。。
    DIRECT_END_NOTIFYMAP(CStandardPageWnd)
    STEP16. CStartPageWnd::OnOk: 控件消息处理函数,此处可以加入具体的事务逻辑处理
    STEP17. 新一轮消息循环

    3、消息定义(文本)
    "click"、"changed"、"link"、"browse"、"itemclick"、"itemselect"、"dropdown"、"itemactivate"、"headerdragging"、"headerclick"、"headerdragged"、"itemexpand"、"itemcollapse"、"windowinit"、"killfocus"、"setfocus"、"timer"

    九、疑问
    1、Edit、Combox的下拉列表部分、ScrollBar、Tooltip控件是创建的实际窗口,这个与DirectUI思路还是有差别的
    2、实例中有创建一个不进行消息处理的窗口(CFrameWindowWnd),然后又创建了一个窗口(CStandardPageWnd)用于具体的控件布局。但是我用一个窗口也能实现,原作者为什么这样还不清楚

    3、控件是用文本形式来做标识的,消息类型是文本形式,是否改成数值型比较好

    十、引用
    引用一: http://www.viksoe.dk/code/windowless1.htm
    引用二: http://directui.googlecode.com/
    引用三: http://www.cnblogs.com/cutepig/archive/2010/06/14/1758204.html


    转载于:https://my.oschina.net/guyson/blog/325117

    展开全文
  • DUILIB

    2017-07-15 17:43:24
    我用SetName修改了一个Option的名字为“stne”,但是之后再其他地方用COptionUI *lsop = static_cast<COptionUI*>(m_PaintManager.FindControl(“stne”)); lsop的值却为NULL怎么办?
  • Duilib Duilib是一个Windows下免费开源的DirectUI界面库,由于简约易扩展的设计以及稳定高效的实现被各大互联网公司普遍接受,广泛应用于包括IM、视频客户端、股票行情软件、导航软件、手机辅助软件、安全软件等多个...
  • NSIS教程(9): NSIS+duilib仿QQ安装包

    万次阅读 2018-01-19 17:43:48
    本文在NSIS教程(8): 基于第三方界面库的安装包界面基础上,分享如何使用NSIS结合duilib高仿QQ安装包的过程。 先上效果图吧! 完整NSIS脚本 # ====================== 自定义宏 =======================...

    推荐:NSIS-UI-Plugin 开源NSIS UI插件框架,支持任意第三方界面库,默认提供使用Qt作为界面库的安装包示例。

    本文在NSIS教程(8): 基于第三方界面库的安装包界面基础上,分享如何使用NSIS结合duilib高仿QQ安装包的过程。

    先上效果图吧!
    这里写图片描述

    这里写图片描述

    这里写图片描述

    在这里插入图片描述

    完整NSIS脚本

    下面是仿QQ安装包项目的NSIS部分的完整脚本,从脚本中可以看到,安装包的界面已经全部封装到了插件中(插件使用C++开发),在插件dll中使用duilib库创建窗体,并响应按钮点击等事件。通过插件与NSIS间的交互,可以方便的实现用户的交互操作。

    # ====================== 自定义宏 ==============================
    !define PRODUCT_NAME           "腾讯QQ"
    !define EXE_NAME               "QQ.exe"
    !define PRODUCT_VERSION        "1.0.0.1"
    !define PRODUCT_PUBLISHER      "Tencent"
    !define PRODUCT_LEGAL          "Copyright (C) 1999-2014 Tencent, All Rights Reserved"
    
    
    # ===================== 外部插件以及宏 =============================
    !include "LogicLib.nsh"
    !include "nsDialogs.nsh"
    !include "..\..\include\common.nsh"
    
    # ===================== 安装包版本 =============================
    VIProductVersion                    "${PRODUCT_VERSION}"
    VIAddVersionKey "ProductVersion"    "${PRODUCT_VERSION}"
    VIAddVersionKey "ProductName"       "${PRODUCT_NAME}"
    VIAddVersionKey "CompanyName"       "${PRODUCT_PUBLISHER}"
    VIAddVersionKey "FileVersion"       "${PRODUCT_VERSION}"
    VIAddVersionKey "InternalName"      "${EXE_NAME}"
    VIAddVersionKey "FileDescription"   "${PRODUCT_NAME}"
    VIAddVersionKey "LegalCopyright"    "${PRODUCT_LEGAL}"
    
    # ==================== NSIS属性 ================================
    
    #SetCompressor zlib
    
    ; 安装包名字.
    Name "${PRODUCT_NAME}"
    
    # 安装程序文件名.
    OutFile "QQ Setup.exe"
    
    # 默认安装位置.
    InstallDir "$PROGRAMFILES\Tencent\${PRODUCT_NAME}"
    
    
    # 针对Vista和win7 的UAC进行权限请求.
    # RequestExecutionLevel none|user|highest|admin
    RequestExecutionLevel admin
    
    # 安装和卸载程序图标
    Icon              "image\logo.ico"
    UninstallIcon     "image\logo.ico"
    
    # 自定义页面
    Page custom DUIPage
    
    # 卸载程序显示进度
    UninstPage instfiles
    
    # ======================= DUILIB 自定义页面 =========================
    Var hInstallDlg
    
    Function DUIPage
        !insertmacro Trace "$TEMP $PLUGINSDIR"
        nsDui::InitDUISetup
        Pop $hInstallDlg
        
        # License页面
        nsDui::FindControl "btnLicenseClose"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnExitDUISetup
            nsDui::OnControlBindNSISScript "btnLicenseClose" $0
        ${EndIf}
        
        nsDui::FindControl "btnLicenseMin"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnBtnMin
            nsDui::OnControlBindNSISScript "btnLicenseMin" $0
        ${EndIf}
        
        nsDui::FindControl "btnLicenseNext"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnBtnLicenseNextClick
            nsDui::OnControlBindNSISScript "btnLicenseNext" $0
        ${EndIf}
        
        # 目录选择 页面
        nsDui::FindControl "btnDirClose"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnExitDUISetup
            nsDui::OnControlBindNSISScript "btnDirClose" $0
        ${EndIf}
        
        nsDui::FindControl "btnDirMin"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnBtnMin
            nsDui::OnControlBindNSISScript "btnDirMin" $0
        ${EndIf}
        
        nsDui::FindControl "btnSelectDir"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnBtnSelectDir
            nsDui::OnControlBindNSISScript "btnSelectDir" $0
        ${EndIf}
        
        nsDui::FindControl "btnDirPre"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnBtnDirPre
            nsDui::OnControlBindNSISScript "btnDirPre" $0
        ${EndIf}
        
        nsDui::FindControl "btnDirCancel"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnBtnCancel
            nsDui::OnControlBindNSISScript "btnDirCancel" $0
        ${EndIf}
            
        nsDui::FindControl "btnDirInstall"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnBtnInstall
            nsDui::OnControlBindNSISScript "btnDirInstall" $0
        ${EndIf}
        
    
        
        # 安装进度 页面
        nsDui::FindControl "btnDetailClose"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnExitDUISetup
            nsDui::OnControlBindNSISScript "btnDetailClose" $0
        ${EndIf}
        
        nsDui::FindControl "btnDetailMin"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnBtnMin
            nsDui::OnControlBindNSISScript "btnDetailMin" $0
        ${EndIf}
    
        # 安装完成 页面
        nsDui::FindControl "btnFinished"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnFinished
            nsDui::OnControlBindNSISScript "btnFinished" $0
        ${EndIf}
        
        nsDui::FindControl "btnFinishedMin"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnBtnMin
            nsDui::OnControlBindNSISScript "btnFinishedMin" $0
        ${EndIf}
        
        nsDui::FindControl "btnFinishedClose"
        Pop $0
        ${If} $0 == 0
            GetFunctionAddress $0 OnExitDUISetup
            nsDui::OnControlBindNSISScript "btnFinishedClose" $0
        ${EndIf}
        
        nsDui::ShowPage
    FunctionEnd
    
    Function OnBtnLicenseNextClick
        nsDui::GetCheckboxStatus "chkAgree"
        Pop $0
        ${If} $0 == "1"
            nsDui::SetDirValue "$INSTDIR"
            nsDui::NextPage "wizardTab"
        ${EndIf}
    FunctionEnd
    
    # 开始安装
    Function OnBtnInstall
        nsDui::GetDirValue
        Pop $0
        StrCmp $0 "" InstallAbort 0
        StrCpy $INSTDIR "$0"
        nsDui::NextPage "wizardTab"
        nsDui::SetSliderRange "slrProgress" 0 100
        
        # 覆盖安装时,指定不覆盖的文件
        # 将这些文件暂存到临时目录
        CreateDirectory "$TEMP\qq_file_translate"
        CopyFiles /SILENT "$INSTDIR\gf-config.xml" "$TEMP\qq_file_translate"
        
        #启动一个低优先级的后台线程
        GetFunctionAddress $0 ExtractFunc
        BgWorker::CallAndWait
        
        # 文件释放完成以后,还原暂存的文件
        CopyFiles /SILENT "$TEMP\qq_file_translate\gf-config.xml" "$INSTDIR"
        RMDir /r "$TEMP\qq_file_translate"
        
        Call CreateShortcut
        Call CreateUninstall
    InstallAbort:
    FunctionEnd
    
    Function ExtractFunc
        SetOutPath $INSTDIR
        File "app\app.7z"
        GetFunctionAddress $R9 ExtractCallback
        Nsis7z::ExtractWithCallback "$INSTDIR\app.7z" $R9
        #Delete "$INSTDIR\app.7z"
    FunctionEnd
    
    
    Function ExtractCallback
        Pop $1
        Pop $2
        System::Int64Op $1 * 100
        Pop $3
        System::Int64Op $3 / $2
        Pop $0
        
        nsDui::SetSliderValue "slrProgress" $0
    
        ${If} $1 == $2
            nsDui::SetSliderValue "slrProgress" 100
            nsDui::NextPage "wizardTab"
        ${EndIf}
    FunctionEnd
    
    
    Function OnExitDUISetup
        nsDui::ExitDUISetup
    FunctionEnd
    
    Function OnBtnMin
        SendMessage $hInstallDlg ${WM_SYSCOMMAND} 0xF020 0
    FunctionEnd
    
    Function OnBtnCancel
    FunctionEnd
    
    Function OnFinished
        # 开机启动
        nsDui::GetCheckboxStatus "chkBootStart"
        Pop $R0
        ${If} $R0 == "1"
            SetShellVarContext all
            CreateShortCut "$SMSTARTUP\QQ.lnk" "$INSTDIR\Bin\QQ.exe"
        ${EndIf}
        
        # 立即启动
        nsDui::GetCheckboxStatus "chkStartNow"
        Pop $R0
        ${If} $R0 == "1"
            Exec "$INSTDIR\Bin\QQ.exe"
        ${EndIf}
        
        # 设置主页
        nsDui::GetCheckboxStatus "chkSetHomePage"
        Pop $R0
        ${If} $R0 == "1"
            WriteRegStr HKCU "Software\Microsoft\Internet Explorer\Main" "Start Page" "http://www.qq.com"
        ${EndIf}
        
        # 显示新特征
        nsDui::GetCheckboxStatus "chkShowFeature"
        Pop $R0
        ${If} $R0 == "1"
            ExecShell "open" "$INSTDIR\QQWhatsnew.txt"
        ${EndIf}
        
        Call OnExitDUISetup
    FunctionEnd
    
    Function OnBtnSelectDir
        nsDui::SelectInstallDir
        Pop $0
    FunctionEnd
    
    Function OnBtnDirPre
        nsDui::PrePage "wizardTab"
    FunctionEnd
    
    
    # ========================= 安装步骤 ===============================
    
    Function CreateShortcut
      SetShellVarContext all
      CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
      CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\Bin\${EXE_NAME}"
      CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\卸载${PRODUCT_NAME}.lnk" "$INSTDIR\uninst.exe"
      CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\Bin\${EXE_NAME}"
      SetShellVarContext current
    FunctionEnd
    
    Function CreateUninstall
    	# 生成卸载程序
    	WriteUninstaller "$INSTDIR\uninst.exe"
    	
    	# 添加卸载信息到控制面板
    	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME}"
    	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\uninst.exe"
    	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayIcon" "$INSTDIR\${EXE_NAME}"
    	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "Publisher" "$INSTDIR\${PRODUCT_PUBLISHER}"
    FunctionEnd
    
    # 添加一个空的Section,防止编译器报错
    Section "None"
    SectionEnd
    
    
    # 卸载区段
    Section "Uninstall"
    
      ; 删除快捷方式
      SetShellVarContext all
      Delete "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk"
      Delete "$SMPROGRAMS\${PRODUCT_NAME}\卸载${PRODUCT_NAME}.lnk"
      RMDir "$SMPROGRAMS\${PRODUCT_NAME}\"
      Delete "$DESKTOP\${PRODUCT_NAME}.lnk"
      SetShellVarContext current
      
      SetOutPath "$INSTDIR"
    
      ; 删除安装的文件
      Delete "$INSTDIR\*.*"
    
      SetOutPath "$DESKTOP"
    
      RMDir /r "$INSTDIR"
      RMDir "$INSTDIR"
      
      SetAutoClose true
    SectionEnd
    
    # ============================== 回调函数 ====================================
    
    # 函数名以“.”开头的一般作为回调函数保留.
    # 函数名以“un.”开头的函数将会被创建在卸载程序里,因此,普通安装区段和函数不能调用卸载函数,而卸载区段和卸载函数也不能调用普通函数。
    
    Function .onInit
    
    FunctionEnd
    
    
    # 安装成功以后.
    Function .onInstSuccess
    
    FunctionEnd
    
    # 在安装失败后用户点击“取消”按钮时被调用.
    Function .onInstFailed
        MessageBox MB_ICONQUESTION|MB_YESNO "安装成功!" /SD IDYES IDYES +2 IDNO +1
    FunctionEnd
    
    
    # 每次用户更改安装路径的时候这段代码都会被调用一次.
    Function .onVerifyInstDir
    
    FunctionEnd
    
    # 卸载操作开始前.
    Function un.onInit
        MessageBox MB_ICONQUESTION|MB_YESNO "您确定要卸载${PRODUCT_NAME}吗?" /SD IDYES IDYES +2 IDNO +1
        Abort
    FunctionEnd
    
    # 卸载成功以后.
    Function un.onUninstSuccess
    
    FunctionEnd
    

    nsDui::InitDUISetupnsDui::FindControl这样的函数都是自己开发的nsDui插件提供的功能,该插件基于duilib,提供界面显示,控件响应等功能。

    脚本中使用了BgWorker插件来实现开启后台工作线程来执行解压缩过程:

     GetFunctionAddress $0 ExtractFunc
     BgWorker::CallAndWait
    

    使用nsis7z插件来解压缩7z文件,并且通过将函数ExtractCallback传入作为回调函数,获取解压缩进度:

    GetFunctionAddress $R9 ExtractCallback
    Nsis7z::ExtractWithCallback "$INSTDIR\app.7z" $R9
    

    需要留意 NSIS教程(8): 基于第三方界面库的安装包界面中提到的nsis7z因为版本太老导致的无法解压的问题。

    nsDui工程下载地址:
    http://download.csdn.net/download/china_jeffery/10214488
    也可以从http://download.csdn.net/download/china_jeffery/10214582下载完整的工程,含插件、脚本、图片资源等。

    推荐:NSIS-UI-Plugin 开源NSIS UI插件框架,支持任意第三方界面库,默认提供使用Qt作为界面库的安装包示例。

    展开全文
  • DUILIB入门简明教程

    千次下载 热门讨论 2013-10-08 19:03:31
    2013 duilib入门简明教程 前言(1) VS环境配置(2) 第一个程序 Hello World(3) 响应按钮事件(4) 自绘标题栏(5) XML配置界面(6) XML基础类(7) 完整的自绘标题栏(8) 界面布局(9) 界面设计器 DuiDesigner (10) 部分bug ...
  • duilib源代码,工程编译 duilib是以DirectUI为技术原理开发的一款轻量级Windows桌面UI库,具有入门简单,使用方便等特点,在国内吸引了不少的开发者。其开发原型为国外大神viksoe的...
  • duilib.dll

    2018-05-30 15:33:40
    由于找不到DuiLib.dll,无法继续执行代码。重新安装程序可能会解决此问题。 dll文件修复方法 1、下载文件。 2、复制文件“duilib.dll”到系统目录下。 3、系统目录一般为:C:\WINNT\System32 64位系统为C:\Windows\...
  • DuiCreator是为DuiLib(Direct UI Library)提供的IDE。她基于QtCreator开发,提供VC2010编译器,代码编写,调试,所见即所得界面设计(目前使用DuiDesigner),编译好的动态和静态DuiLib库,完整的项目管理能力等。 ...
  • Duilib介绍

    千次阅读 2017-06-02 10:48:33
    一、Duilib介绍 Duilib是一个开源 的directui 界面库,开放,共享,惠众,共赢,遵循bsd协议,可以免费用于商业项目,目前支持Windows 32 、Window CE、Mobile等平台。由于简约易扩展的设计以及稳定高效的实现被各...
  • MFC中使用Duilib DuiLib_Mfc

    热门讨论 2012-12-13 10:51:11
    Duilib中使用MFC 编译环境 VS2010+WIN7
  • duilib master

    2017-11-14 16:52:08
    Duilib 是一款强大的界面开发工具,可以将用户界面和处理逻辑彻底分离,极大地提高用户界面的开发效率,遵循bsd协议。
  • Duilib应用

    2016-10-13 17:34:16
    关于Duilib的一些更新以及应用,从网上大牛下载而来,看了感觉有些用处,特拿出来跟大家分享,希望对你们有所帮助
  • DUIlib使用Fastreport

    2016-08-23 16:32:28
    我在开始使用duilib做项目时,打印和数据预览都是自己绘制的,这样不仅绘制麻烦费事费事,而且客户需求是多变的,自己绘制不是那么的灵活。后面我觉得,可以使用报表等工具结合duilib进行显示或者打印,这里我使用了...
  • duilib_DemoTreeview

    千次下载 热门讨论 2011-07-02 15:59:25
    用开源DirectUI库 duilib做的一棵树,库里面修改了少量部分底层代码 已达到现有效果 实现了 对叶子节点排序、container自动计算下滚动条功能,及提高了对WTL和MFC的兼容性。
  • duilib对话框

    2018-02-27 10:32:18
    一个基于duilib的对话框,主要用到了树和tab页面。。。。。。。。。。。。。
  • duilib 3.91

    2014-08-03 10:12:08
    用vs2010编译的duilib 3.91,包含动态库和静态库两个版本
  • DuiLib仿酷狗播放器

    2018-11-28 16:12:03
    开源这个小项目的目的,是为了帮助更多使用DuiLib或者UiLib库的朋友们,去学习和熟悉这个库。我个人非常喜欢DuiLib库,同时也是国内最早的开源DirectUI界面库。并且DuiLib并不是没人管的孩子了,DuiLib2.0和DuiLib...
  • Duilib Menu

    2015-05-22 09:08:03
    Duilib 的Menu进行实现和扩展
  • duilib开源界面库

    2018-06-08 14:56:15
    国内首个开源 的directui 界面库,开放,共享,惠众,共赢,遵循bsd协议,可以免费用于商业项目,目前... Duilib 目前支持Windows 32 、Window CE、Mobile等平台,使用C++开发,遵循BSD协议,可以免费用于商业项目 。

空空如也

1 2 3 4 5 ... 20
收藏数 3,563
精华内容 1,425
关键字:

DuiLib