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 继续走起.. 本系列纯属学习笔记,如果哪里有错误或遗漏的地方,希望大家高调指出,当然,我肯定不会低调改正的.(开个小 ...
随机推荐
- 定时器篇---java.util.TimerTask和quartz
最近项目中出现了定时执行任务的东西,研究了一下,觉得挺不错的,以后还用得到,就总结了下. 这里只介绍两种java.util.Timer 和 quartz java.util.Timer java自带的 ...
- 面试官:为什么mysql不建议执行超过3表以上的多表关联查询?
概述 前段时间在跟其他公司DBA交流时谈到了mysql跟PG之间在多表关联查询上的一些区别,相比之下mysql只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort ...
- WPF 利用RichTextBox 打印出不同颜色的文本
using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows ...
- The socket is closed!
关闭mongodb /usr/local/app/mongidb//bin/mongod --shutdown --dbpath /usr/local/data/mongo/data/ 然 ...
- 素数(Prime)
素数的判断: #include<math.h> bool IsPrime(int n) { ) return false; int sqr = (int)sqrt(1.0*n); ; i& ...
- jmeter图片的上传
首先添加一个线程组,然后在线程组里面添加一个http请求,因为是发送数据,所有是post请求,写好上传的地址,然后写好文件路径 1.添加线程组 :右键测试计划,添加-Threads(Users)-线程 ...
- SLAB
slab:由于内核会有许多小对象,这些对象构造销毁十分频繁,比如i-node,dentry,这些对象如果每次构建的时候就向内存要一个页(4kb),而其实只有几个字节,这样就会非常浪费,为了解决这个问题 ...
- 漫谈 Google 的 Native Client(NaCl) 技术(二)---- 技术篇(兼谈 LLVM)
转自:http://hzx5.blog.163.com/blog/static/40744388201172531637729/ 漫谈 Google 的 Native Client(NaCl) 技术( ...
- IOS开发:官方自带的JSON使用
apple在ios5的时候提供了json的相关处理api,其中最主要的是NSJSONSerialization类. + (BOOL)isValidJSONObject:(id)obj; + (NSDa ...
- 【JavaScript框架封装】数据类型检测模块功能封装
数据类型检测封装后的最终模块代码如下: /*数据类型检验*/ xframe.extend(xframe, { // 鸭子类型(duck typing)如果它走起路来像鸭子,叫起来也是鸭子,那么它就是鸭 ...