使用DUILIB加载XML界面

这篇主要目的就是教给大家怎样在自己的工程中加载XML界面,这是最基本的应用,对于界面控件响应啥的,我就不讲了,在大家懂了这个之后,我会给大家一个其它人写的博客,再看他的文章,大家应该就更清楚明白

一,建立工程

建立win32应用程序,取名叫blog_try

这里有几点要注意:

1、选择.net framework 2.0 如果你在开发时没有选择这个,而你用了默认的3.5的话,当你发布APP的时候,你就只有哭了,因为,3.5以上的只能在WIN 7上的操作系统运行,这一点一定要注意。我有血的教训!!!

2、其它其实也没什么注意的了,选择win32下的win32项目

这里选择:windows应用程序

二、搭环境

1、删除部分生成的代码

到blog_try里,把自动生成的代码删成这个样子,即除了包含头文件和winmain函数以外,其它都不要

2、复制duilib相关文件到工程目录

2.1、把duilib源工程中的头文件全部复制到我们的blog_try工程目录下:


2.2、将lib文件同样放在blog_try工程目录下

2.3、将dll文件放在debug目录下

三、函数重写与加载界面文件

1、在stdafx.h中加入以下代码,以添加包含duilib的头文件和库文件

  1. // TODO: 在此处引用程序需要的其他头文件
  2. #include "UIlib.h"
  3. using namespace DuiLib;
  4. #ifdef _DEBUG
  5. #   ifdef _UNICODE
  6. #       pragma comment(lib, "DuiLib_ud.lib")
  7. #   else
  8. #       pragma comment(lib, "DuiLib_d.lib")
  9. #   endif
  10. #else
  11. #   ifdef _UNICODE
  12. #       pragma comment(lib, "DuiLib_u.lib")
  13. #   else
  14. #       pragma comment(lib, "DuiLib.lib")
  15. #   endif
  16. #endif

2、在blog_try.h中添加类CMainFrame,这个类继承自CwindowWnd,INotifyUI,我们也就是用这个类CMainFrame来实现绑定XML,添加对按钮等等控件的响应。

  1. class CMainFrame :
  2. public DuiLib::CWindowWnd,public INotifyUI//应用程序窗口类CWindowWnd
  3. {
  4. public:
  5. CMainFrame(void);
  6. ~CMainFrame(void);
  7. };

在blog_try.cpp中添加实现

  1. CMainFrame::CMainFrame(void)
  2. {
  3. }
  4. CMainFrame::~CMainFrame(void)
  5. {
  6. }

现在blog_try.cpp中的代码应该是:

3、重写虚函数

在新实现的类中,有三个虚函数是必须重写的,它们是:

  1. LPCTSTR GetWindowClassName() const {}  //这是个纯虚函数,大家看UIBase.cpp里对它的引用就可以明白为什么非要实现它,因为
  2. //在注册窗口类时所用的类名(classname),就是用GetWindowClassName()来获取的;
  3. //与此类似地,大家可以通过重写UINT GetClassStyle() const {}来为注册窗口类时,指定//类别,在360Demo中重写了这个函数,大家可以去看看
  4. void Notify(TNotifyUI& msg){}         //在新类中可以通过实现该类,来实现消息拦截,从而当指定的消息出现时,响应我们的函数
  5. //这个函数主要用来处理窗口上的控件发出来消息的响应
  6. LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam){}  //消息处理函数,这个主要用来处理对话框窗口产生的消息

首先是对GetWindowClassName()的重写,即返回任意一个字符串做为注册类的类名就可以了

代码如下:

  1. LPCTSTR CMainFrame::GetWindowClassName() const //重写获取类名函数,也就是指定要新建的窗口类的类名
  2. {
  3. return _T("UIMainFrame");
  4. };

然后是对Notify的重写

代码如下:

  1. void CMainFrame::OnPrepare()
  2. {
  3. }
  4. void CMainFrame::Notify(TNotifyUI& msg)//处理窗口通知消息,响应用户的输入
  5. {
  6. if( msg.sType == _T("windowinit") ) OnPrepare();
  7. }

最后是对HandleMessage()的重写:

3.1 先定义一个变量

  1. CPaintManagerUI m_pm;

这个变量将用来绘图,即画出我们图像中的各种控件与背景的,从它的类型名CPaintManagerUI也能看得出来

3.2实现HandleMessage(){}

  1. LRESULT CMainFrame::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  2. LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
  3. styleValue &= ~WS_CAPTION;
  4. ::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
  5. m_pm.Init(m_hWnd);//主窗口类与窗口句柄关联
  6. CDialogBuilder builder;
  7. CControlUI* pRoot = builder.Create(_T("UISkin.xml"), (UINT)0, NULL, &m_pm);//加载XML并动态创建界面无素,与布局界面元素,核心函数单独分析
  8. //注意:CDialogBuilder 并不是一个对话框类
  9. ASSERT(pRoot && "Failed to parse XML");
  10. if (NULL==pRoot)//如果找不到皮肤文件则退出
  11. {
  12. MessageBox(NULL,TEXT("Cant not find the skin!"),NULL,MB_ICONHAND);
  13. return 0;
  14. }
  15. m_pm.AttachDialog(pRoot);//附加控件数据到HASH表中……为pRoot作为对话框结点,为其创建控件树
  16. m_pm.AddNotifier(this);//增加通知处理
  17. return 0;
  18. }
  19. LRESULT CMainFrame::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  20. {
  21. LRESULT lRes = 0;
  22. BOOL bHandled = TRUE;
  23. switch( uMsg ) {
  24. case WM_CREATE:
  25. lRes = OnCreate(uMsg, wParam, lParam, bHandled);
  26. break;
  27. default:
  28. bHandled = FALSE;
  29. }
  30. if( bHandled ) return lRes;
  31. if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
  32. return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
  33. }

4、实现主函数WinMain()

  1. int APIENTRY _tWinMain(HINSTANCE hInstance,
  2. HINSTANCE hPrevInstance,
  3. LPTSTR    lpCmdLine,
  4. int       nCmdShow)
  5. {
  6. CPaintManagerUI::SetInstance(hInstance);//设置程序实例
  7. CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()
  8. + _T("skin"));//实例句柄与渲染类关联,获得皮肤文件目录(加载皮肤文件在OnCreate之中)
  9. HRESULT Hr = ::CoInitialize(NULL);//初始化COM库, 为加载COM库提供支持
  10. if( FAILED(Hr) )
  11. return 0;
  12. CMainFrame* pMainFrame = new CMainFrame();//创建应用程序窗口类对象
  13. if( pMainFrame == NULL )
  14. return 0;
  15. pMainFrame->Create(NULL, _T("AdderCalc"), UI_WNDSTYLE_DIALOG, 0);
  16. pMainFrame->CenterWindow();//将窗口放到桌面中央
  17. pMainFrame->ShowWindow(true);//显示窗口
  18. CPaintManagerUI::MessageLoop();//进入消息循环
  19. ::CoUninitialize();//退出程序并释放COM库
  20. return 0;
  21. }

与往常一样,代码地址:http://download.csdn.net/detail/harvic880925/5367129

另附参考资料:《DUIlib编程总结.pdf》及源码        下载地址:http://download.csdn.net/detail/harvic880925/5367161

出错及处理:

一、IDropTarget* GetTxDropTarget();

提出错误:error C2143: 语法错误: 缺少“;”(在“*”的前面)

解决:添加头文件:#include "OLEIDL.h"

使用DUILIB建立项目的更多相关文章

  1. MVC5 网站开发实践 1、建立项目

    目录 MVC5 网站开发实践 概述   一.建立项目 1.建立团队项目 在办公室和家里使用不同的电脑,为了方便代码的共享将项目建立为团队项目.   如图打开vs2013→新建→团队项目(图1),会自动 ...

  2. 安卓(android)建立项目时失败,出现Android Manifest.xml file missing几种解决方法?(总结中)

    安卓(android)建立项目时失败.出现AndroidManifest.xml file missing几种解决方法?(总结中) Eclipse新建项目.遇到这种问题.注意例如以下: 1.文件名称最 ...

  3. 关于指针要注意的地方还有尝试在codeblocks上建立项目

    1.字符串: char a[]="house"; char *b="house"; a[2]='r';可以   b[2]='r'不可以,因为这个指针变量指的是字 ...

  4. 关于QT建立项目中遇到的相关问题的处理办法

    关于QT建立项目中遇到的相关问题的处理办法 1.在QTCreater中新建一个空的工程时,第一次运行会抱一个错误,如下: -1: error: LNK1123: 转换到 COFF 期间失败: 文件无效 ...

  5. SVN中建立项目

    下午建个svn的时候,出错,有个东西配置错了,晚上google看到一篇文章,觉得作者写的不错,而且很用心,转来共享. [转至]5分钟快速建立项目版本控制 – Face Code,Brain bloom ...

  6. Flutter实战视频-移动电商-02.Flutter实战建立项目和编写入口文件

    02.Flutter实战建立项目和编写入口文件 创建项目: flutter create flutter_shop 创建完成之后呢,它会提示我们, 进入flutter_shop的目录,然后执行flut ...

  7. cocos2d-x win8下的环境配置和建立项目

    cocos2dx 跨平台.可是看网上说开发最合适还是在vs2010中,基本是编完后再移植到安卓. 1.去官网下载源代码2.2.3版本号的. 2.然后运行根文件夹下的build-win32.bat(须要 ...

  8. EF6 + MySql 建立项目引用失败

    EF6 + MySql 建立项目 步骤 在项目中使用” NuGet” 包添加 EntityFramework 和 MySql.Data ,如下图 (1)       在NuGet界面中的“浏览”选项卡 ...

  9. ASP.NET Core 入门笔记2,建立项目

    1.建立项目 2.项目结构 1.项目结构说明 根目录/文件 说明 .vscode目录 VS Code项目配置目录,相当于.vs..idea文件夹 bin目录 编译输出目录 obj目录 编译配置与中间目 ...

随机推荐

  1. C#标准的事件模型

    事件模型的几个规范: 委托类型的名称以EventHandler结束: 委托原型返回值为void; 委托原型具有两个参数:sender表示事件触发者,e表示事件参数: 事件参数的名称以EventArgs ...

  2. C++之常量

    常量 **作用**:用于记录程序中不可更改的数据 C++定义常量两种方式 1. **\#define** 宏常量: #define 常量名 常量值 * ==通常在文件上方定义==,表示一个常量 2. ...

  3. Linux CPU负载状态:%us/%sy/%ni/%id/%wa/%hi/%si/%st含义

    原文 Linux CPU负载状态:%us/%sy/%ni/%id/%wa/%hi/%si/%st含义 缙哥哥发现用了雅黑的探针,在 Linux 的 CPU 状态信息中发现,有“%us.%sy.%ni. ...

  4. 偏函数-functools.partial

    1.概念:偏函数是2.5版本以后引进来的东西.属于函数式编程的一部分,使用偏函数可以通过有效地“冻结”那些预先确定的参数,来缓存函数参数,然后在运行时,当获得需要的剩余参数后,可以将他们解冻,传递到最 ...

  5. BZOJ2152 聪明可可 点分治

    题意传送门 思路:基本的点分治思路,num数组记录从u点开始路径长度分别为1或者2或者3的路径长度(取模3意义下),然后做一个简单的容斥就好了. 为了避免计数的麻烦,<u,u>这样的点单独 ...

  6. 前端常用的库和实用技术之JavaScript高级技巧

    javascript高级技巧 变量作用域和闭包 <!DOCTYPE html> <html lang="en"> <head> <meta ...

  7. Android开发 QRCode二维码开发第三方框架

    前言 Android开发里二维码开发经常用到,这里简单的介绍下Android开发里的二维码. 最广泛使用的二维码库zxing zxing是最广泛的二维码库各个平台都可以适用它,但是Android平台使 ...

  8. BeanPostProcessor原理学习

    <Spring源码解析>笔记 1.自定义的BeanPostProcessor @Component public class MyBeanPostProcessor implements ...

  9. Allegro文档错误之:Iangle 命令

    Allegro绘制弧线时,可以使用add rarc命令,或者菜单栏里 Add|Arc w/Radius. 使用该命令时,需要输入3个参数: 1,圆心坐标:如 x –0.3 –0.8 2,半径,以及起始 ...

  10. thinkphp action参数绑定

    参数绑定是通过直接绑定URL地址中的变量作为操作方法的参数,可以简化方法的定义甚至路由的解析. 参数绑定功能默认是开启的,其原理是把URL中的参数(不包括模块.控制器和操作名)和操作方法中的参数进行绑 ...