• DirectUI界面编程(一)创建第一个应用


    1.获取Duilib库文件

    通过上一节大家对DirectUI界面设计有了初步的了解,本节开始我们一起学习Duilib界面库的使用。
    首先我们需要获取Duilib库,目前最新版本为2.0,最新版本源码托管在Github上,项目地址:
    https://github.com/duilib/duilib
    笔者选择的版本为1.1版,该版本可以从Google Code上获取:
    https://code.google.com/p/duilib/downloads/list
    这里写图片描述
    由于网络上的限制,笔者在CSDN上上传了一份,CSDN下载地址:
    http://download.csdn.net/detail/rongbo_j/8882095

    下载后解压目录结构如下图所示:
    这里写图片描述
    DuiLib.sln为Visual Studio的解决方案文件,如果读者机器上安装了VS2008可以直接双击打开,官方提供了几个Demo,其他VS版本打开编译可能会有一些问题。

    2.搭建开发环境

    为了便于研究Duilib源码,我们可以以源码的方式构建项目,在上面的目录结构中我们可以看到有一个Duilib目录,该目录下为Duilib库的所有源代码,一共有32个文件:
    这里写图片描述
    1.打开Visual Studio(笔者使用的版本为2012版),新建一个空的Win32项目。

    2.进入解决方案根目录,新建一个DuiLib目录,將所有源码拷贝到该目录下。
    这里写图片描述
    例如笔者的解决方案名称为duilib_tutorial,duilib_tutorial.sln所在的目录即为解决方案根目录。

    3.在项目上点击右键=>添加=>新建筛选器,修改名称为Duilib,在新建的筛选器上点击右键=>添加=>现有项,將刚拷贝过来duilib库源码添加到我们自己的项目中。项目结构如下图所示:
    这里写图片描述
    4.由于Duilib是原本是动态库工程,任意打开一个duilib库源码文件,会发现每个类及它的成员函数前使用UILIB_API进行修饰,UILIB_API其实是一个宏,我们找到它定义的地方,该宏在UIBase.h文件开头定义:

    #ifdef UILIB_EXPORTS
    #define UILIB_API __declspec(dllexport)
    #else
    #define UILIB_API __declspec(dllimport)
    #endif

    __declspec(dllexport)是在dll工程中声明导出哪些函数使用,我们在Win32应用中并不需要这些修饰,將上面代码注释掉,重新定义UILIB_API宏,修改代码如下:

    /*
    #ifdef UILIB_EXPORTS
    #define UILIB_API __declspec(dllexport)
    #else
    #define UILIB_API __declspec(dllimport)
    #endif
    */
    #define UILIB_API

    5.Duilib工程中需要添加riched20.lib作为链接依赖项,这里我们进行修改,直接从动态库中获取函数地址,打开UIRichEdit.cpp文件,找到下面代码:

    // Create Text Services component
    if(FAILED(CreateTextServices(NULL, this, &pUnk)))
            goto err;

    CreateTextServices函数依赖于riched20.lib,我们將这段代码注释起来,从动态库中获取进CreateTextServices函数地址,上面代码修改为:

        // Create Text Services component
        /*if(FAILED(CreateTextServices(NULL, this, &pUnk)))
            goto err;*/
        typedef HRESULT(_stdcall *CTSFunc)(IUnknown *punkOuter, ITextHost *pITextHost, IUnknown **ppUnk);
        CTSFunc ctsFunc = NULL;
        auto hRiched20 = LoadLibrary(_T("Riched20.dll"));
    
        if (NULL == hRiched20)
            goto err;
        else
        {
            ctsFunc = (CTSFunc)GetProcAddress(hRiched20, "CreateTextServices");
    
            if (NULL == ctsFunc)
                goto err;
        }
    
        if (FAILED(ctsFunc(NULL, this, &pUnk)))
            goto err;

    到此为止,源码的修改工作完成,接下来我们构建第一个基于Duilib库的应用。

    3.创建第一个应用

    新建一个c++源文件,编写一个最简单的应用,代码如下:

    #include <Windows.h>
    #include "../DuiLib/StdAfx.h" 
    using namespace DuiLib;
    class CMyWnd : public CWindowWnd,public INotifyUI
    {
    public:
        CMyWnd(){}
        LPCTSTR GetWindowClassName() const
        {
            return L"MyWnd";
        }
        void Notify(TNotifyUI& msg)
        {
        }
    };
    INT WinMain(HINSTANCE hInst,HINSTANCE hPreInst,LPSTR lpCmdLine,INT Show)
    {
        CMyWnd* pFrame = new CMyWnd();
        //创建主窗口
        pFrame->Create(NULL,L"Hello World!",UI_WNDSTYLE_FRAME,WS_EX_WINDOWEDGE);
        //显示窗口
        pFrame->ShowWindow(true);
        //消息循环
        CPaintManagerUI::MessageLoop();
        delete pFrame;
        return 0;
    }

    基于Duilib库的应用必须有一个和窗口相关的类,而且该类必须继承CWindowWnd和INotifyUI。CWindowWnd和INotifyUI都是抽象类,不能直接实例化,CWindowWnd中定义了一个纯虚函数GetWindowClassName,INotifyUI中定义了一个纯虚函数Notify,因此我们必须重写这两个函数。

    上面代码中我们定了一个类CMyWnd,继承CWindowWnd和INotifyUI,重写了父类的GetWindowClassName和Notify函数,GetWindowClassName函数用于指定向操作系统注册窗口类的名称。Notify函数用于处理Duilib"控件"消息。

    WinMain函数为Win32应用入口函数,我们需要实例化一个CMyWnd对象,调用Create函数创建窗口,为了让窗口显示出来我们还需要调用ShowWindow函数。
    最后调用CPaintManagerUI类的静态函数MessageLoop进行消息循环。

    编译运行,我们可以看到一个空的Window窗口。
    这里写图片描述

    博文源码地址:https://github.com/rongbo-j/duilib-tutorial

  • 相关阅读:
    Eclipse运行单个Junit 单元测试
    梯形法求定积分(一)设计梯形法求积分的类模板,梯形法
    写一个顺序表模板,包括顺序表的基本功能,例如查找,插
    对于静态成员函数和静态成员变量的练习
    梯形法求定积分(二)设计一个函数模板,独立的非成员函
    各位高手帮我看看这个清屏程序
    对于静态成员函数和静态成员变量的练习
    二分法的递归算法和迭代算法,算法作为有序表模板类的成
    梯形法求定积分(一)设计梯形法求积分的类模板,梯形法
    二分法的递归算法和迭代算法,算法作为有序表模板类的成
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6468657.html
Copyright © 2020-2023  润新知