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窗口。
DirectUI界面编程(一)创建第一个应用的更多相关文章
- DirectUI界面编程(零)简介
有过Win32.MFC编程经验的朋友应该都知道,传统Windows应用中的按钮.编辑框等控件都是一个子窗口,操作系统通过窗口句柄来唯一标识该窗口. 使用Windows 标准控件创建用户界面,美化起来是 ...
- DirectUI界面编程(六)实现右键弹出菜单
本节向大家介绍一下右键弹出菜单是如何实现的.效果如下,在窗口中点击鼠标右键弹出菜单,点击菜单项能够响应菜单点击事件. 使用Duilib库实现的弹出菜单,实际上也是一个Windows窗口,因此我们需要创 ...
- DirectUI界面编程(三)从XML文件中加载界面
Duilib支持xml界面布局,使得界面设计与逻辑处理相分离,本节介绍如何从xml文件中加载界面元素. 我们需要以下几个步骤: 创建并初始化CPaintManagerUI对象. 创建CDialogBu ...
- DirectUI界面编程(五)WindowImplBase的使用
上节笔者向大家介绍了Duilib的界面布局并在最后编写了一个仿QQ旋风的界面,但是由于我们屏蔽了系统的标题栏,读者可能已经发现,我们的窗口没办法移动,同样也不能通过拖动来改变窗口的大小. 这就需要我们 ...
- DirectUI界面编程(四)界面布局详解
Duilib的界面布局使用xml文件进行描述,在Duilib v1.1版本的xml布局文件中我们可以使用以下这些标签(后续版本标签有扩充): 这些标签总的来讲可以分为三类: 窗口类,该类别中只有一个W ...
- DirectUI界面编程(二)绘制一个按钮
上节介绍了使用源码方式构建Duilib应用的项目配置,并创建了一个最简单的基于Duilib库的窗口,细心的读者会发现,当我们点击窗口的关闭按钮时,应用并没有真的退出,因为我们并没有对窗口事件进行处理, ...
- 为什么qt成为c++界面编程的第一选择
为什么qt成为c++界面编程的第一选择 一.前言 为什么现在QT越来越成为界面编程的第一选择,笔者从事qt界面编程已经有接近8年,在这之前我做C++界面都是基于MFC,也做过5年左右.当时为什么会从M ...
- 为什么 qt 成为 c++ 界面编程的第一选择?
为什么qt成为c++界面编程的第一选择 一.前言 为什么现在QT越来越成为界面编程的第一选择,笔者从事qt界面编程已经有接近8年,在这之前我做C++界面都是基于MFC,也做过5年左右.当时为什么会从M ...
- ASP.NET MVC 5 03 - 安装MVC5并创建第一个应用程序
不知不觉 又逢年底, 穷的钞票 所剩无几. 朋友圈里 各种装逼, 抹抹眼泪 MVC 继续走起.. 本系列纯属学习笔记,如果哪里有错误或遗漏的地方,希望大家高调指出,当然,我肯定不会低调改正的.(开个小 ...
随机推荐
- 励志:98岁老爷爷用Windows系统自带画图软件制作的神作
哈尔拉斯科,是一位很出名的老爷爷,他70岁才接触MS Paint(就是我们熟知的Windows自带的画图软件).他曾经是一名图形艺术家,但是之前他都是手工创作.他熟知怎么用双手进行艺术创作.但是后来, ...
- CV/PR:模式识别与图像处理笔试题
汉王高级研究人员(模式识别.图像处理类)招聘试题 原文链接:http://www.cnblogs.com/dongsheng/articles/2793142.html 说明: 可能您的专业并不完 ...
- @RestController无法自动注入的问题
今天在练习spring boot的时候,发现在ide中无法将@RestController注入到代码中,@RestController注解依赖的包是org.springframework.web,检 ...
- jquery插件生成简单二维码
除了利用第三方网站生成二维码外,这是一个比较简单的办法吧. <script src="/Scripts/jquery.qrcode.min.js" type="te ...
- Zabbix系列-REHL6.10离线方式安装Zabbix 4.0 LTS
环境 第零步:关闭系统默认防火墙 setenforce 0 sed -i -r "/^SELINUX=/c SELINUX=disabled" /etc/selinux/confi ...
- 前端异步编程之Promise和async的用法
传统的异步解决方案采用回调函数和事件监听的方式,而这里主要记录两种异步编程的新方案: ES6的新语法Promise ES2017引入的async函数 Generator函数(略) Promise的含义 ...
- 巴塞尔问题(Basel problem)的多种解法——怎么计算$\frac{1}{1^2}+\frac{1}{2^2}+\frac{1}{3^2}+\cdots$ ?
(PS:本文会不断更新) $\newcommand\R{\operatorname{Res}}$ 如何计算$\zeta(2)=\frac{1}{1^2}+\frac{1}{2^2}+\frac{1}{ ...
- 【Codeforces Round #493 (Div. 2) B】Cutting
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 显然只有在前i个位置奇数偶数出现次数都相同的地方才能切. (且不管前面怎么切,这里都能切的. 那么就相当于有n个物品,每个物品的代价 ...
- Android学习总结(4)——Andorid Studio熟练使用
前言 该文以Android Studio2.1.1(Bundle)为例.JDK使用的是1.8版本,也建议大家使用1.8版本. 使用技巧无先后顺序. Android Studio 2.1.1 软件下载 ...
- NYIST 119 士兵杀敌(三)
士兵杀敌(三)时间限制:2000 ms | 内存限制:65535 KB难度:5 描述南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出 ...