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

DirectUI界面编程(一)创建第一个应用的更多相关文章

  1. DirectUI界面编程(零)简介

    有过Win32.MFC编程经验的朋友应该都知道,传统Windows应用中的按钮.编辑框等控件都是一个子窗口,操作系统通过窗口句柄来唯一标识该窗口. 使用Windows 标准控件创建用户界面,美化起来是 ...

  2. DirectUI界面编程(六)实现右键弹出菜单

    本节向大家介绍一下右键弹出菜单是如何实现的.效果如下,在窗口中点击鼠标右键弹出菜单,点击菜单项能够响应菜单点击事件. 使用Duilib库实现的弹出菜单,实际上也是一个Windows窗口,因此我们需要创 ...

  3. DirectUI界面编程(三)从XML文件中加载界面

    Duilib支持xml界面布局,使得界面设计与逻辑处理相分离,本节介绍如何从xml文件中加载界面元素. 我们需要以下几个步骤: 创建并初始化CPaintManagerUI对象. 创建CDialogBu ...

  4. DirectUI界面编程(五)WindowImplBase的使用

    上节笔者向大家介绍了Duilib的界面布局并在最后编写了一个仿QQ旋风的界面,但是由于我们屏蔽了系统的标题栏,读者可能已经发现,我们的窗口没办法移动,同样也不能通过拖动来改变窗口的大小. 这就需要我们 ...

  5. DirectUI界面编程(四)界面布局详解

    Duilib的界面布局使用xml文件进行描述,在Duilib v1.1版本的xml布局文件中我们可以使用以下这些标签(后续版本标签有扩充): 这些标签总的来讲可以分为三类: 窗口类,该类别中只有一个W ...

  6. DirectUI界面编程(二)绘制一个按钮

    上节介绍了使用源码方式构建Duilib应用的项目配置,并创建了一个最简单的基于Duilib库的窗口,细心的读者会发现,当我们点击窗口的关闭按钮时,应用并没有真的退出,因为我们并没有对窗口事件进行处理, ...

  7. 为什么qt成为c++界面编程的第一选择

    为什么qt成为c++界面编程的第一选择 一.前言 为什么现在QT越来越成为界面编程的第一选择,笔者从事qt界面编程已经有接近8年,在这之前我做C++界面都是基于MFC,也做过5年左右.当时为什么会从M ...

  8. 为什么 qt 成为 c++ 界面编程的第一选择?

    为什么qt成为c++界面编程的第一选择 一.前言 为什么现在QT越来越成为界面编程的第一选择,笔者从事qt界面编程已经有接近8年,在这之前我做C++界面都是基于MFC,也做过5年左右.当时为什么会从M ...

  9. ASP.NET MVC 5 03 - 安装MVC5并创建第一个应用程序

    不知不觉 又逢年底, 穷的钞票 所剩无几. 朋友圈里 各种装逼, 抹抹眼泪 MVC 继续走起.. 本系列纯属学习笔记,如果哪里有错误或遗漏的地方,希望大家高调指出,当然,我肯定不会低调改正的.(开个小 ...

随机推荐

  1. 互联网的大数据神话——NoSQL

    本文摘抄于:<纵横大数据--云计算数据基础设施> 何小朝著 Chapter5. NewSQL--关系数据库联邦/联合 5.4.2  互联网的神话 对强一致性的要求放松,是因为 互联网的分布 ...

  2. 创建一个dynamics CRM workflow (四) - Development of Custom Workflows

    首先我们需要确定windows workflow foundation 已经安装. 创建之后先移除MyCustomWorkflows 里面的 Activity.xaml 从packages\Micro ...

  3. Linux终端 Tab 补全命令

    1. vi编辑器打开 /etc/bash.bashrc文件 vi /etc/bash.bashrc 2.找到文件中的下列代码 3.将注释符号#去掉,即改成 4.最后 source一下 /etc/bas ...

  4. BZOJ 1123: [POI2008]BLO 求割点_乘法原理_计数

    Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通. Input 输入n&l ...

  5. 死磕itchat源码--目录结构

    阅读itchat源码时,先弄清itchat的目录结构 itchat │ config.py │ content.py │ core.py │ log.py │ returnvalues.py │ ut ...

  6. 通过js 实现 向页面插入js代码并生效,和页面postMessage通讯

       此文章针对已经搭建好jenkins和会使用iconfont图标库而写. 主要目标就是在不通过更改html文件,完成页面交互图标信息,因为美工最多可以上传代码并且自动发布,并不会在Html中加入我 ...

  7. ASP.NET MVC5 :Attribute路由使用详解

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  8. 探索Python的多态是怎么实现的

    多态是指通过基类的指针或者引用,在运行时动态调用实际绑定对象函数的行为. 对于其他如C++的语言,多态是通过在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来 ...

  9. 提高生产力:Web前端验证的标准化

    统一验证标准,减少重复劳动,提高生产力. 当公司内部有多个Web项目的时候,统一验证标准就很有必要了.统一不同项目的验证规则,比如 同为用户名 使用同一套标准,甚至用户名和机构名等也使用同一套标准.( ...

  10. Git学习总结(11)——Git撤销操作详解

    本文主要讨论和撤销有关的 git 操作.目的是让读者在遇到关于撤销问题时能够方便迅速对照执行解决问题,而不用去翻阅参数繁多的 git 使用说明. 一开始你只需了解大致功能即可,不必记住所有命令和具体参 ...