Duilib初学笔记(II)-Hello World

My first Duilib program

  1. Prepare for development

  打开DuiFarm项目DuiFarm.cpp文件,将除_tWinMain函数之外所有内容删除。删除后的DuiFarm.cpp内容如下:

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{return 0;}

  在DuiFarm.cpp文件首引入头文件UIlib.h,并引用namespace,以及其他相关宏。

#include "..\\..\\duilib-master\\DuiLib\\UIlib.h"
using namespace DuiLib;
#ifdef _DEBUG
    #ifdef _UNICODE
        #pragma comment(lib,"..\\..\\duilib-master\\Lib\\Duilib_ud.lib")
    #else
        #pragma comment(lib,"..\\..\\duilib-master\\Lib\\Duilib_d.lib")
    #endif
#else
    #ifdef _UNICODE
        #pragma comment(lib,"..\\..\\duilib-master\\Lib\\Duilib_u.lib")
    #else
        #pragma comment(lib,"..\\..\\duilib-master\\Lib\\Duilib.lib")
    #endif
#endif

  这样,Duilib已经成功集成在项目DuiFarm项目中了。注意作者项目的文件结构,引用Duilib.h与Duilib_x.lib文件使用相对路径必须正确(,相对路径以DuiFarm下Debug目录内为参照)。

  在编写其他代码之前,需要明确几个知识点。Duilib的几个内置对象。

  1. CWindowWnd:窗口对象父类,负责创建窗口、窗口消息过程处理、提供窗口子类化与超类化接口。
  2. CPaintManagerUI:负责窗口图形绘制。CPaintManagerUI三个主要功能:绘制控件、管理消息、事件通知。
  3. CDialogBuilder:控件布局类,主要作用:解析XML,构建控件树,创建控件对象。
  4. INotifyUI:处理事件和通知。子类重载Notify(TNotify &msg)虚函数,实现处理事件通知功能。
  5. CControlUI:控件管理的父类,为控件提供通用属性。

  2.Starting coding "Hello World"

  在DuiFarm.cpp中新建类DuiFarm,继承自CWindowWnd与INotifyUI,重写CWindowWnd的虚函数GetWindowClassName、HandleMessage与INotify的虚函数Notify。代码如下:

class DuiFarm: public CWindowWnd, public INotifyUI
{
protected:
    CPaintManagerUI m_PaintManager;
public:
    virtual LPCTSTR GetWindowClassName() const
    {/*some code*/}
    virtual void    Notify(TNotifyUI& msg)
    {/*some code*/}
    virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {/*some code*/}
};

  其中三个函数的主要功能:

  1. GetWindowClassName:返回窗口名称。
  2. Notify:事件响应,如点击事件。
  3. HandleMessage:处理消息,例如创建窗口消息。

  首先补全GetWindowClassName函数的代码,在函数体内,直接返回窗体名字符串。

virtual LPCTSTR GetWindowClassName() const
{return _T("DuiFramFrame");}

  HandleMessage函数中补全对窗体创建等消息的处理。

 1 virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
 2 {
 3     LRESULT lRes = 0;
 4     if( uMsg == WM_CREATE )
 5     {
 6         m_PaintManager.Init(m_hWnd);
 7         CDialogBuilder builder;
 8         CControlUI *pRoot = builder.Create(_T("dui-design.xml"),(UINT)0,NULL,&m_PaintManager);
 9         ASSERT(pRoot&&"### XML error!");
10         m_PaintManager.AttachDialog(pRoot);
11         m_PaintManager.AddNotifier(this);
12         return lRes;
13     }
14     if( m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes))
15     {
16         return lRes;
17     }
18     return __super::HandleMessage(uMsg, wParam, lParam);
19 }

  第4行在消息为窗体创建(WM_CREATE)时,执行:

  1. 初始化当前窗口(line 6)
  2. 加载窗口设计xml文件(line 8)
  3. 绘制窗口(line 10)
  4. 添加消息通知(line 11)

  执行完上述代码,窗体即绘制完成,事件通知已可用。在上述代码中,第8行加载xml文件即为duilib的界面设计xml。犹如html之于浏览器,dui通过解析xml将控件绘制到窗体上。

  xml文件如下:

1 <?xml version="1.0" encoding="utf-8"?>
2 <Window size="100,100">
3   <HorizontalLayout bkcolor="#FFFFFF00">
4     <Button name="btnHello" text="Hello World :-)"/>
5   </HorizontalLayout>
6 </Window>

  将文件保存到项目Debug目录下(因当前项目以Debug模式运行)。这段xml描述了窗体的整体布局:

  • 第二行定义了窗体大小,长宽各500像素。
  • 第三行定义了一个横向布局,背景黄色(bkcolor为背景色设置)。
  • 第四行定义了一个按钮,名称是btnHello,显示文字为Hello World :-)

  现在窗体已经定义好,需要添加对按钮事件的处理。根据上一篇介绍,按钮事件处理要在重载的Notify函数中编写。

1 virtual void Notify(TNotifyUI& msg)
2 {
3     if(msg.sType==_T("click"))
4     {
5         if(msg.pSender->GetName()==_T("btnHello"))
6             ::MessageBox(NULL,_T("Hello World :-)"),_T("Hallo Welt :-D"),NULL);
7     }
8 }
  • 第2行代码表示:“此处要接收类型为‘click’的事件”。
  • 第5行代码表示:“在所有click事件中,此处仅接收名为‘btnHello’这家伙的事件”。
  • 第6行代码表示:“提示英德对照的Hello World,以及它们对应的口型”。

  编写到这里,项目已经具备窗口绘制、窗口布局和事件处理的基本功能,下面需要在入口函数中为之初始化与分配资源:

 1 int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
 2 {
 3     CPaintManagerUI::SetInstance(hInstance);
 4     CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
 5     DuiFarm duiFarm;
 6     duiFarm.Create(NULL, _T("Dui Farm"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
 7     duiFarm.CenterWindow();
 8     duiFarm.ShowModal();
 9     return 0;
10 }
  • 第3行~第4行,入口函数对实例和资源进行分配,第4行实参为当前项目路径。
  • 第6行:创建窗口。
  • 第7行:设置窗口在屏幕居中。
  • 第8行:显示窗口。

  _tWinMain函数内容基本固定,后续如无特别说明,将不再列出_tWinMain代码。

  在调试运行前,需要确认DuiLib[x].dll是否位于DuiFarm项目的Debug目录下(x为_d,_ud或不存在,根据项目编码以及是否为Debug模式而定)。

  运行效果如下:

  

图2.2.1 显示窗体

  如图,窗体显示黄色,而按钮实际上占据了整个窗体。点击按钮如下:

图2.2.2 点击按钮(按钮占据了整个窗体)

时间: 2024-10-16 02:13:00

Duilib初学笔记(II)-Hello World的相关文章

DuiLib学习笔记1——编译运行demo

c++中皮肤问题比较麻烦,MFC自带的太难用.DirectUI界面库就比较强大了,之前像skin++之类的基于DirectUI收费昂贵.DuiLib是基于DirectUI的界面库,可以将用户界面和处理逻辑彻底分离,极大地提高用户界面的开发效率. duilib的SVN地址:http://duilib.googlecode.com/svn/trunk 下载后运行DuiLib.sln 编译时可能会遇到几个报错. 0.开发环境本身有问题,比如用win7没有装win7sdk之类的. 1. TestApp1

DuiLib学习笔记3——颜色探究

在前面两篇日志已经能使用xml了.今天准备好好的折腾一番,结果在颜色上却掉坑里了. 起初我在ps里取颜色为0104ff 这里01为R,04为G,ff为B 在控件的属性里有这样一个属性bkcolor="#0104ff".这个代码放进去后为黑色,并非我们期望的蓝色. 后来才发现在duilib里颜色正常的是8位,ps里的是6位.另外两位为A,是代表透明度的.在duilib中颜色的表达顺序为: ARGB 透明度|红色|绿色|蓝色 大家知道蓝色加点红色就会变成粉红色,所以我这里采用蓝色的背景,如

DuiLib学习笔记(二) 扩展CScrollbar属性

DuiLib学习笔记(二) 扩展CScrollbar属性 Duilib的滚动条滑块默认最小值为滚动条的高度(HScrollbar)或者宽度(VScrollbar).并且这个值默认为16.当采用系统样式的滚动条,或者 Troy的源码(https://github.com/qdtroy/DuiLib_Ultimate)自带的样式时,是没有问题的,因为这两种样式默认高(宽)度都是16,当滑块最小时,也有16*16,背景图片(九宫格式)不会出拉伸BUG.但是,当自定义背景图片时,如果图片本身大小超过16

初学笔记(C#事件)

1.声明事件      EventHandler是一个预定义的委托,它定义了一个无返回值的方法.在 .Net Fromwork中,他的格式: public  delegate  void EventHandler (Object  sender, EvenArgs  e) 其中sender的类型为Object,表示时间发布者本身,e用来传递事件的相关信息,数据类型为EvenArgs及其派生类. 标准的EvenArgs并不包含任何事件数据, 因此EventHandler专用于表示不生成数据的事件的

lisp初学笔记

学习任何知识,都不能仅仅把它们当做知识,更重要的是要把它们在实际编程实践中应用起来,持有这样的学习观念才不至于让你变成学究式的活字典,对于程序员来说这一点尤其重要,你学习的任何语言知识,一定要在实际的程序编写过程中不断练习.不停实践,纸上得来终觉浅,绝知此事须躬行. LispBox 实际上是把 Emacs.Slime.Clozure CL 以及 QuickLisp 集成到一起,使用 LispBox 做开发环境就相当于选择了 Emacs 作为编辑器.选择 Slime 作为交互界面,那么一定要熟悉

flex入门--初学笔记1

环境:flashBuilder + eclipse 4.2 基本控件: 1 <mx:Script> 2 <![CDATA[ 3 import mx.controls.Alert; 4 public function showMsg(msg:String):void{ 5 mx.controls.Alert.show(msg); 6 } 7 ]]> 8 </mx:Script> 9 <mx:Panel title="常用控件" width=&qu

DuiLib学习笔记5——标题栏不能正常隐藏问题

我之前代码都是照着官方那个Duilib入门文档.doc来学习的.但是遇到一个问题,虽然他隐藏了windows的自带标题栏,可以自己绘画一个标题栏了,但是在这个标题栏下方,用力乱戳,就可能把系统自带的,最小化,最大化,关闭按钮戳出来.如下图: 我问了群里的朋友,都说可能是WM_NCHITTEST的问题.于是我去handle里多加了一个if判断 else if( uMsg == WM_NCHITTEST) { return 0; } 结果虽然解决了问题,但是我自己的按钮都失效了.通过debug发现,

AS3 初学笔记 actionscript-之变量

变量 变量可用来存储程序中使用的值.要声明变量,必须将 var 语句和变量名结合使用.在 ActionScript 2.0 中,只有当您使用类 型注释时,才需要使用 var 语句.在 ActionScript 3.0 中,总是需要使用 var 语句.例如,下面的 ActionScript 行声明一个名 为 i 的变量: var i; 如果在声明变量时省略了 var 语句,则在严格模式下会出现编译器错误,在标准模式下会出现运行时错误.例如,如果以前未 定义变量 i,则下面的代码行将产生错误: i;

DuiLib学习笔记4——布局

有了前面三篇的基础,现在可以开始布局了. 首先任何布局都必须包含在<Window></Window>标签内,跟<html></html>很像. DuiLib提供了两种布局方式,水平布局和垂直布局,虽然没有css左右浮动那么方便,但是有这些东西,完全可以像写页面table一样去完成. 水平布局是HorizontalLayout,垂直布局为VerticalLayout.在Window标签内,默认的是垂直布局. 下面来看一段代码,包含了水平和垂直布局. <?