DuiLib之-----加载XML

前端之家收集整理的这篇文章主要介绍了DuiLib之-----加载XML前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言:这几天都在搞DUILIB,以此之前我转了个大圈,看了有些人在用htmlayout,我也跟着学了学,浪费了我两周的时间,问题一堆,而且不开源,只能根据那些个帮助文档和其它人的文章自己来搞,有些函数只能只其然不知其所以然,最后让我最终放弃使用它的是,在开发中我碰到了太多的问题,并没有想像的好用,而且我在执行自带的几个DEMO的时候,反应速度很慢,所以就此我放弃了,后来再找其它的DirectUI开源开发包的时候,发现了DUILIB,现在我把我这几天的研究成果慢慢的记录出来以帮助更多的朋友,DUILIB开发组为我们做了很多的贡献,希望我们大家能够把自己研究出来的内容都公布出来,让更多的人受益,让DUILIB更加的强大。


使用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.  
  8. }
最后是对 HandleMessage()的重写:

3.1 先定义一个变量

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

3.2实现HandleMessage(){}

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

4、实现主函数WinMain()

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

猜你在找的XML相关文章