新版博客已经搭建好了,有问题请访问 htt://www.crazydebug.com

在公司二期项目中为了将谷歌内核嵌入到duilib中,采用了自定义duilib控件的方法,由于也是第一次用duilib,边学边用,所有网上的资料给了我很大的帮助,尤其Redrain兄弟的文章给我启发很大,再次感谢互联网具有开源精神的程序员。

今天简单总结下duilib的自定义控件,要实现自定义控件需要做两件事情

      1、继承现有的控件类创建新的控件类
      2、让程序识别新的控件并可以在xml中使用
第一步继承我就不多说了,直接看代码吧
class CBrowserUI :public CControlUI
{
public:
CBrowserUI();
~CBrowserUI();
virtual LPCTSTR GetClass() const;
virtual LPVOID GetInterface(LPCTSTR pstrName);
//这个一定要设置,不然控件无法显示
virtual void SetPos(RECT rc, bool bNeedInvalidate = true); CefRefPtr<CefBrowser> GetBrowser()
{
return m_Browser->GetBrowser();
} CefRefPtr<CefFrame> GetMainFrame()
{
return m_Browser->GetMainFrame();
} void CloseAllBrowser();
bool CreateBrowser(const CefString & szHomePage, CHaoMainFrame * pWnd);
void LoadUrl(const CefString & url); protected:
CefRefPtr<CHaoBrowserHandler> m_Browser;
};

下面是实现文件

CBrowserUI::CBrowserUI() :m_Browser(NULL)// m_Browser(NULL)
{ } CBrowserUI::~CBrowserUI()
{
} LPCTSTR CBrowserUI::GetClass() const
{
return _T("BrowserUI");
} LPVOID CBrowserUI::GetInterface(LPCTSTR pstrName)
{
if (_tcsicmp(pstrName, _T("Browser")) == )
{
return static_cast<CBrowserUI*>(this);
}
return CControlUI::GetInterface(pstrName);
} void CBrowserUI::SetPos(RECT rc, bool bNeedInvalidate /* = true */)
{
CControlUI::SetPos(rc, bNeedInvalidate);
if (m_Browser.get())
{
CefRefPtr<CefBrowser> browser = m_Browser->GetBrowser();
DuiLib::CDuiRect rc = GetPos();
if (browser && !rc.IsNull())
{
::SetWindowPos(browser->GetHost()->GetWindowHandle(),
NULL, rc.left, rc.top, rc.GetWidth(), rc.GetHeight(), SWP_NOZORDER | SWP_NOACTIVATE);
}
}
} void CBrowserUI::CloseAllBrowser()
{
if (m_Browser.get())
{
m_Browser->CloseAllBrowsers(true);
}
} bool CBrowserUI::CreateBrowser(const CefString & szHomePage, CHaoMainFrame * pWnd)
{
CefWindowInfo info;
if (m_Browser == NULL)
{
m_Browser = new CHaoBrowserHandler(pWnd);
}
m_Browser->SetHomePage(szHomePage);
if (m_Browser != NULL)
{
info.SetAsChild(GetManager()->GetPaintWindow(), GetPos());
CefBrowserSettings browserSettings;
return CefBrowserHost::CreateBrowser(info, m_Browser.get(), szHomePage,browserSettings,NULL);
} return false;
} void CBrowserUI::LoadUrl(const CefString & url)
{
if (m_Browser.get())
{
CefRefPtr<CefFrame> mainframe = m_Browser->GetMainFrame();
if (mainframe)
mainframe->LoadURL(url);
}
}

建立新控件后,最先应该重写的两个函数是GetClass和GetInterface。他们后用来区分控件的类型的虚函数,用于动态识别控件类型和做控件的类型转换。

从Duilib的自带控件上可以看出,比如当前的自定义控件类名为CBrowserUI,那么GetClass函数返回的字符串BrowserUI。而GetInterface函数是根据传入的参数是否与自身的字符串匹配,来决定能否把自己转换为需要的控件类型。GetInterface中用来匹配的字符串,应该与xml中的对应的控件的标签名称一直,这里应该是Browser。

ButtonUI类,GetClass对应ButtonUI,GetInterface对应Button。这不是强制的,但是保持这个风格很重要

好了控件类的定义实现都有了,那么如何让xml可以识别我们定义的控件?这才是最重要的问题

为了让xml布局识别我们的新控件,我们需要完成Duilib的IDialogBuilderCallback接口,重写这个接口中的CreateControl函数。

通常情况下,可以让窗体类继承IDialogBuilderCallback接口并且重写CreateControl(DuiLib自带的WindowImplBase窗体类已经继承了这个接口,如果是继承WindowImplBase的话就直接重写CreateControl就可以了)。函数处理方法是比较传入的字符串,根据字符串来决定返回什么控件的指针,这个传入的字符串就是xml文件中控件的标签,比如<Button />中的字符串Button

CControlUI * CHaoMainFrame::CreateControl(LPCTSTR pstrClass)
{
CControlUI * pUI = NULL;
if (_tcsicmp(pstrClass, _T("MyBrowser")) == )
{
pUI = m_browser = new CBrowserUI;
}
return pUI;
}

这样一个自定义控件就搞完了,而且我用着也是很不错的,上个图吧,无图无真相

Duilib自定义控件的更多相关文章

  1. Duilib自定义控件响应指定命令(转载)

    转载:http://blog.csdn.net/panxianzhan/article/details/50772893 duilib在UIManager.h里的EVENTTYPE_UI枚举里定义了很 ...

  2. Duilib XML嵌套/自定义控件

    转载:https://www.jianshu.com/p/0fe8610dcc8d  // https://github.com/Washington-DC/Duilib-ListView  //这是 ...

  3. duilib进阶教程 -- XML嵌套及自定义控件 (4)

    代码下载:http://download.csdn.net/detail/qq316293804/6433937 之前入门教程里已经讲过了自定义控件,这里借着迅雷播放器再次举个例子. 1.我们先给迅雷 ...

  4. DUILIB创建不规则窗体,自定义控件(很不错的几十篇文章)

    http://blog.csdn.net/harvic880925/article/details/8925650 http://blog.csdn.net/harvic880925/article/ ...

  5. Duilib源码分析(四)绘制管理器—CPaintManagerUI

    接下来,分析uilib.h中的UIManager.h,在正式分析CPaintManagerUI前先了解前面的一些宏.结构: 枚举类型EVENTTYPE_UI:定义了UIManager.h中事件通告类型 ...

  6. 2013 duilib入门简明教程 -- 结合win32和MFC (16)

        虽然duilib自带在MFC中使用duilib的Demo,但只是MFC窗口和duilib窗口不重叠的情况.如果要在MFC窗口中嵌入duilib控件,或者在duilib控件中嵌入MFC的控件的话 ...

  7. duilib学习 --- 360demo 学习

    我想通过360demo的学习,大概就能把握duilib的一般用法,同时引申出一些普遍问题,和普遍解决方法.并在此分享一些链接和更多内容的深入学习..... 原谅我是一个菜鸟,什么都想知道得清清楚楚.. ...

  8. duilib各种布局的作用,相对布局与绝对布局的的意义与用法

    大多数刚使用duilib的朋友时候非常依赖duilib自带的设计器,用他可以拖拉控件,可视化的做出自己想要的界面.可是用一段时间就会发现原带的设计器有很多bug,时不时会崩溃,支持的控件数量有限,属性 ...

  9. duilib进阶教程 -- 总结 (17)

    整个教程的代码下载:http://download.csdn.net/detail/qq316293804/6502207 (由于duilib进阶教程主要介绍界面,所以这个教程只给出界面相关的代码,完 ...

随机推荐

  1. Springboot中使用kafka

    注:kafka消息队列默认采用配置消息主题进行消费,一个topic中的消息只能被同一个组(groupId)的消费者中的一个消费者消费. 1.在pom.xml依赖下新添加一下kafka依赖ar包 < ...

  2. ASP.NET Core搭建多层网站架构【8.3-编写角色业务的增删改】

    2020/01/29, ASP.NET Core 3.1, VS2019 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站架构[8.3-编写角色业务的增删改] 编写最简单的增删 ...

  3. Protobuf协议--java实现

    Protobuf协议,全称:Protocol Buffer 它跟JSON,XML一样,是一个规定好的数据传播格式.不过,它的序列化和反序列化的效率太变态了…… 来看看几张图你就知道它有多变态.  pr ...

  4. ML 是什么意思?

    ML到底是什么意思? 1.(ML)machine language机器语言,makeup language.参见:ML语言: 通用的函数式编程语言. 2.(ML)machine learning,人工 ...

  5. 吴裕雄--天生自然TensorFlow2教程:梯度下降简介

    import tensorflow as tf w = tf.constant(1.) x = tf.constant(2.) y = x * w with tf.GradientTape() as ...

  6. 【转】ssh 远程执行命令

    原文:https://blog.csdn.net/liuxiao723846/article/details/82667482 SSH 是 Linux 下进行远程连接的基本工具,不光可以登录,也可以远 ...

  7. 并行效果&迭代器

    具体文章:ALEX的文章 https://www.cnblogs.com/alex3714/articles/5765046.html 串行的并行效果: import time def consume ...

  8. CAN数据格式-BLF

    欢迎关注<汽车软件技术>公众号,回复关键字获取资料. Vector工具录制的数据,一般有ASC和BLF两种格式,本文介绍ASC. 1.BLF定义 BLF(binary logging fo ...

  9. github 初体验

    一.什么是 Github? github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开. Github 由Chris Wanstrath, ...

  10. app生命周期之即将关闭

    需求:当软件正在进行任务还未结束时,如果用户强制退出软件,需要将一些数据进行保存等处理. 策略:当用户使用多任务将软件挂起,并滑掉软件时,接下来有5妙钟的时间留给软件做处理.会调用- (void)ap ...