使用dulilib DirectUI库(一)
1、在创建的窗口类里面
需要继承CWindowWnd、INotifyUI
对于CWindowWnd里面的方法:
实现CWindowWnd的方法virtualLPCTSTRGetWindowClassName()const=0;,重载virtualUINTGetClassStyle()const;返回窗口的风格类型,重载virtualvoidOnFinalMessage(HWNDhWnd);,
对于INotifyUI里面的,只有一个唯一的抽象方法:
virtualvoidNotify(TNotifyUI&msg)=0;
当你实现了这个Notify,才能正常的接收、处理消息
来看看主要的消息处理部分:
void Notify(TNotifyUI& msg)
{
if( msg.sType == _T("windowinit") ) OnPrepare();
else if( msg.sType == _T("click") ) {
if( msg.pSender->GetName() == _T("insertimagebtn") ) {
CRichEditUI* pRich = static_cast<CRichEditUI*>(m_pm.FindControl(_T("testrichedit")));
if( pRich ) {
pRich->RemoveAll();
}
}
else if( msg.pSender->GetName() == _T("changeskinbtn") ) {
if( CPaintManagerUI::GetResourcePath() == CPaintManagerUI::GetInstancePath() )
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("skin\\FlashRes"));
else
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
CPaintManagerUI::ReloadSkin();
}
}
}
分开来看:
a、
void Notify(TNotifyUI& msg)
{
if( msg.sType == _T("windowinit") ) OnPrepare();
}
窗口刚创建的时候,发出来的消息时windowsinit,所以这里进行OnPrepare();
void OnPrepare()
{
CSliderUI* pSilder = static_cast<CSliderUI*>(m_pm.FindControl(_T("alpha_controlor")));
if( pSilder ) pSilder->OnNotify += MakeDelegate(this, &CFrameWindowWnd::OnAlphaChanged);
pSilder = static_cast<CSliderUI*>(m_pm.FindControl(_T("h_controlor")));
if( pSilder ) pSilder->OnNotify += MakeDelegate(this, &CFrameWindowWnd::OnHChanged);
pSilder = static_cast<CSliderUI*>(m_pm.FindControl(_T("s_controlor")));
if( pSilder ) pSilder->OnNotify += MakeDelegate(this, &CFrameWindowWnd::OnSChanged);
pSilder = static_cast<CSliderUI*>(m_pm.FindControl(_T("l_controlor")));
if( pSilder ) pSilder->OnNotify += MakeDelegate(this, &CFrameWindowWnd::OnLChanged);
}
这种方法很简单,只是找到每一个CSliderUI,而且是通过CPaintManagerUI的FindControl方法(参数为xml中描述的每一个CSliderUI的名称)
找到之后进行:
if( pSilder ) pSilder->OnNotify += MakeDelegate(this, &CFrameWindowWnd::OnAlphaChanged);
主要是给这个CSliderUI加上消息的映射,MakeDelegate的两个参数分别是哪个UI控件(object)和需要绑定的方法
b、第二种事件类型
void Notify(TNotifyUI& msg)
{
else if( msg.sType == _T("click") ) {
else if( msg.pSender->GetName() == _T("changeskinbtn") ) {
if( CPaintManagerUI::GetResourcePath() == CPaintManagerUI::GetInstancePath() )
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("skin\\FlashRes"));
else
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
CPaintManagerUI::ReloadSkin();
}
}
}
这里有这么多的事件要处理,就拿一个换肤的例子来看看(如上面的例子):
其实也很简单,这么多的代码,只是找到对应的资源路径(比如最上边的一个if语句,判断当前的资源路径是否和当前的程序实例的路径相等,如果相等就……),比如这里"skin\\FlashRes",前面再加上项目的路径,来构成一个绝对路径。
CPaintManagerUI::ReloadSkin();是用来,替换资源的,比如xml中有一个资源的是这样的:
我们的资源路径下面有:
那么执行了这个方面,在使用到winbk.bmp的地方就会被直接替换掉了。
2、那么我的小伙伴们都要奇怪了,这个程序在什么地方响应windows的消息呢?
看看这段代码:
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if( uMsg == WM_CREATE ) {
m_pm.Init(m_hWnd);
CDialogBuilder builder;
CControlUI* pRoot = builder.Create(_T("test1.xml"), (UINT)0, NULL, &m_pm);
ASSERT(pRoot && "Failed to parse XML");
m_pm.AttachDialog(pRoot);
m_pm.AddNotifier(this);
Init();
return 0;
}
else if( uMsg == WM_DESTROY ) {
::PostQuitMessage(0L);
}
else if( uMsg == WM_ERASEBKGND ) {
return 1;
}
LRESULT lRes = 0;
if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
}
一看这里的WM_CREATE,就知道他是对windows的消息进行响应的部分。
这里只看WM_CREATE消息,其他的部分要么是退出的消息,要么就是北京擦除的消息、让windows自动处理默认消息的。
而WM_CREATE消息
if( uMsg == WM_CREATE ) {
m_pm.Init(m_hWnd);
CDialogBuilder builder;
CControlUI* pRoot = builder.Create(_T("test1.xml"), (UINT)0, NULL, &m_pm);
ASSERT(pRoot && "Failed to parse XML");
m_pm.AttachDialog(pRoot);
m_pm.AddNotifier(this);
Init();
return 0;
}
可以看到首先需要对CPaintManagerUI进行初始化,窗口的句柄是在CWindowWnd中的
得到的,CFrameWindowWnd继承了CWindowsWnd,所以这个成员变量的值自然也就存在了。CDialogBuilder是一个对话框的创建者,他负责创建一个对话框,在以这个库做UI的窗体,都是以对话框的形式显示出来的。
CControlUI* pRoot = builder.Create(_T("test1.xml"), (UINT)0, NULL, &m_pm);
通过xml文件和CPaintManagerUI来创建一个对话框,创建出来的对话框作为顶层(其他的控件作为子层)保存在pRoot中。最后把这个对话框放入到渲染管理(CPaintManagerUI大管家)中,这样duilib就能自己去渲染出来了。m_pm.AddNotifier(this);对这个大管家设置消息响应的类。这样一个检查的初始化就完成了。
3、main函数
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)
{
HRESULT Hr = ::CoInitialize(NULL);
CFrameWindowWnd* pFrame = new CFrameWindowWnd(); pFrame->Create(NULL, _T("这是一个最简单的测试用exe,修改test1.xml就可以看到效果"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
pFrame->CenterWindow();
pFrame->ShowWindow(true);
CPaintManagerUI::MessageLoop(); ::CoUninitialize();
return 0;
}
CFrameWindowWnd*是我们重载的类,通过creat可以创建出来一个实例,CenterWindow()可以创建一个窗体,ShowWindow(true)可以把窗体给显示出来。CPaintManagerUI::MessageLoop()进行整个UI的消息循环。
CoInitialize和CoUninitialize是初始化com的。
使用dulilib DirectUI库(一)的更多相关文章
- 自己写的一个DirectUI库,基础控件基本都已实现
http://download.csdn.net/detail/pcradio/9254881 http://blog.csdn.net/pcradio
- duilib DirectUI库里面的一个简单的例子RichListDemo
1.首先来看这里的CRichListWnd 已经不再是从CWindowWnd继承了 classCRichListWnd:publicWindowImplBase 从WindowImplBase中,可以 ...
- 重大发现: windows下C++ UI库 UI神器-SOUI(转载)
转载:http://www.cnblogs.com/setoutsoft/p/4996870.html 在Windows平台上开发客户端产品是一个非常痛苦的过程,特别是还要用C++的时候.尽管很多语言 ...
- directUI
MFC界面开发中,习惯了使用控件,亦或者是自绘制控件来美化界面,但操作起来繁琐,还不太美观.DirectUI的出现,对于界面开发,给了我们一个新的选择,目前很多公司使用了该技术对其产品进行了美化,效果 ...
- C++界面库
刚开始用C++做界面的时候,根本不知道怎么用简陋的MFC控件做出比较美观的界面,后来就开始逐渐接触到BCG Xtreme ToolkitPro v15.0.1,Skin++,等界面库,以及一些网友自 ...
- 仿迅雷播放器教程 -- C++ windows界面库对比(11)
从上一篇文章中可以看出,C++的界面方向还很弱,没有任何一个界面库可以一统天下,所以才造成了界面库百家争鸣的情况. 从时间上看: 1.出来最早的是QT,1991年就有了. 2.VC++ 虽然1992年 ...
- 转: windows下C++ UI库 UI神器-SOUI
转:http://www.cnblogs.com/setoutsoft/p/4996870.html 前言 在Windows平台上开发客户端产品是一个非常痛苦的过程,特别是还要用C++的时候.尽管很多 ...
- C++界面库(十几种,很全)
刚开始用C++做界面的时候,根本不知道怎么用简陋的MFC控件做出比较美观的界面,后来就开始逐渐接触到BCG Xtreme ToolkitPro v15.0.1,Skin++,等界面库,以及一些网友自 ...
- UI神器-SOUI
前言 在Windows平台上开发客户端产品是一个非常痛苦的过程,特别是还要用C++的时候.尽管很多语言很多方法都可以开发Windows桌面程序,目前国内流行的客户端产品都是C++开发的,比如QQ,YY ...
随机推荐
- thinkphp5.0 API友好
新版ThinkPHP针对API开发做了很多的优化,并且不依赖原来的API模式扩展. 数据输出 新版的控制器输出采用Response类统一处理,而不是直接在控制器中进行输出,通过设置default_re ...
- ES6-Set 和 Map 数据结构
ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个构造函数,用来生成 Set 数据结构. const s = new Set(); [2, 3 ...
- Python类总结-描述符__get__(),__set__(),__delete__()
1 描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),set(),delete()中的一个,这也被称为描述符协议 get():调用一个属性时,触发 set():为一 ...
- platform 模块
python中,platform 模块给我们提供了很多方法去获取操作系统的信息,如: import platform platform.platform() #获取操作系统名称及版本号 'Window ...
- 缩略图信息提取工具vinetto
缩略图信息提取工具vinetto 在Windows操作系统中,为了方便用户快速浏览图片,系统会自动为每个图片生成预览图.预览图默认保存在同目录的Thumbs.db文件中.当图片文件删除后,Thum ...
- nyoj 269 VF 动规
VF 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 Vasya is the beginning mathematician. He decided to make a ...
- hdu 1069 动规 Monkey and Banana
Monkey and Banana Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
- 网络流—最大流(Edmond-Karp算法)
一.含义 从源点到经过的所有路径的最终到达汇点的所有流量和 例如: 在这个图中求源点1,到汇点4的最大流.答案为50,其中1->2->4为20 :1->4为20 :1->2-& ...
- [BZOJ4373]算术天才⑨与等差数列(线段树)
[l,r]中所有数排序后能构成公差为k的等差数列,当且仅当: 1.区间中最大数-最小数=k*(r-l) 2.k能整除区间中任意两个相邻数之差,即k | gcd(a[l+1]-a[l],a[l+2]-a ...
- 【并查集】BZOJ4668-冷战
[题目大意] 给出N个军工厂和M 个操作,操作分为两类: • 0 u v,这次操作苏联会修建一条连接 u 号军工厂及 v 号军工厂的铁路,注意铁路都是双向的; • 1 u v, Reddington ...