使用Libcef+Duilib创建自己的Chrome内核浏览器
2015-09-20 12:43
901 查看
前言:
编译Chrome开源代码是一件很恐怖的事情,代码庞大,还需要各种工具配合。在windows上快速开发chrome内核网页程序,Libcef是一个很好的选择。最近趁空闲时间,写了一个简单的浏览器,很多功能都没有完善,不知道以后还会不会继续写了,PC端确实是萎了。1、Libcef 的使用
在前面的几篇文章中大概介绍了下Libcef的使用,很多时候我们都会遇到各种问题,建议去看看它的接口函数声明,里面的注释写的非常清楚。libCEF中C++与JavaScript的交互调
Windows上使用CEF嵌入基于chrome内核浏览器小例
2、大概的要点
程序运行截图首先需要解决的是浏览器的Tab控件,扩展Duilib控件,每一个Tab控件就是一个容器里面存放着一系列Item,根据Item的个数和Tab的尺寸来计算每一个Item 节点的宽度。
对于单个节点Item控件,里面又有一个子Button控件,也就是关闭按钮。对于这个Item的消息进行处理,包括选中、双击、关闭,把这些消息都转发到父控件Tab中去处理。Tab控件同一管理这些控件的哪一个是选中状态。
然后是Libcef控件的创建,Tab中点击Add按钮后,需要创建网页控件并加载到当前窗口中去。整个父窗口在大小发生变化时,又要通知里面所有的Libcef子窗口随之变化。
然后就是关闭时,要让所有的Libcef子进程都能正常退出,就必须按照Libef文档说的那样,在退出时调用CefQuitMessageLoop()。
3、部分源代码
Duilib扩展Tab控件#pragma once #include "ScrollTabUI.h" class CScrollOptionUI : public CContainerUI { public: CScrollOptionUI(void); ~CScrollOptionUI(void); void SetParent(CScrollTabUI* pTab) { m_pParent = pTab; } protected: virtual void Init(); virtual void PaintText(HDC hDC); virtual void SetPos(RECT rc); virtual void DoEvent(TEventUI& event); bool OnBtnClose(void* pParam); private: CButtonUI* m_pBtnExit; CScrollTabUI* m_pParent; };
#include "StdAfx.h" #include "ScrollOptionUI.h" #define BTN_CLOSE_WIDTH 14 #define BTN_CLOSE_HEIGHT 14 CScrollOptionUI::CScrollOptionUI(void) : m_pBtnExit(NULL) , m_pParent(NULL) { } CScrollOptionUI::~CScrollOptionUI(void) { } void CScrollOptionUI::Init() { m_pBtnExit = new CButtonUI; CDuiString strAttr; strAttr.Format(L"float=\"true\" pos=\"%d,%d,%d,%d\" normalimage=\"close_nor.png\" hotimage=\"close_hot.png\" pushedimage=\"close_push.png\"", m_cxyFixed.cx-BTN_CLOSE_WIDTH, 0, m_cxyFixed.cx, BTN_CLOSE_HEIGHT); m_pBtnExit->ApplyAttributeList(strAttr); Add(m_pBtnExit); m_pBtnExit->OnNotify += MakeDelegate(this, &CScrollOptionUI::OnBtnClose); } void CScrollOptionUI::PaintText( HDC hDC ) { RECT rc = m_rcItem; rc.left += 4; rc.right-= 10; CRenderEngine::DrawText(hDC, m_pManager, rc, m_sText, 0xFF666666, 0, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS); } void CScrollOptionUI::SetPos( RECT rc ) { CContainerUI::SetPos(rc); RECT rcExit = {rc.right-BTN_CLOSE_WIDTH-1, rc.top+1, rc.right-1, rc.top+BTN_CLOSE_HEIGHT+1}; m_pBtnExit->SetPos(rcExit); } void CScrollOptionUI::DoEvent( TEventUI& event ) { if( event.Type == UIEVENT_BUTTONDOWN && m_pParent ) { m_pParent->SelectItem(this); } else if ( event.Type == UIEVENT_DBLCLICK && m_pParent ) { m_pParent->OnOptionDbClick(this); } CContainerUI::DoEvent(event); } bool CScrollOptionUI::OnBtnClose( void* pParam ) { TNotifyUI* pNotifyUI = (TNotifyUI*)pParam; if(pNotifyUI->sType == DUI_MSGTYPE_CLICK && m_pParent ) { m_pParent->DeleteItem(this); } return true; }
#pragma once class CScrollTabUI; class CScrollTabCallback { public: virtual void OnScrollTabCloseItem(CScrollTabUI* pTab, const int nDelIndex, const int nSelIndex) = 0; virtual void OnScrollTabSelectChange(CScrollTabUI* pTab, const int nUnSelIndex, const int nSelIndex) = 0; virtual void OnScrollTabAddItem(CScrollTabUI* pTab) = 0; virtual void OnScrollTabDbClick(CScrollTabUI* pTab, const int nIndex) = 0; }; class CScrollTabUI : public CContainerUI { public: CScrollTabUI(void); ~CScrollTabUI(void); CControlUI* AddTabItem(LPCTSTR lpText, bool bReset=false); void SelectItem(CControlUI* pItem); void DeleteItem(CControlUI* pItem); void DeleteItem(const int nIndex); void SetItemText(const int nIndex, LPCTSTR lpText); int GetItemCount()const { return m_pTabItems.size(); } void SetCallback(CScrollTabCallback* pCallback) { m_pCallback = pCallback; } void OnOptionDbClick(CControlUI* pOption); protected: virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); virtual void Init(); virtual void SetPos(RECT rc); void ResetTabPos(); int GetTabItemIndex(CControlUI* pItem); bool OnBtnClickAdd(void* pParam); private: int m_nNorWidth; int m_nMinWidth; int m_nCurWidth; int m_nSelIndex; DWORD m_dwTabSelColor; DWORD m_dwTabNorColor; CButtonUI* m_pBtnAdd; vector<CControlUI*> m_pTabItems; CScrollTabCallback* m_pCallback; };
#include "StdAfx.h" #include "ScrollTabUI.h" #include "ScrollOptionUI.h" CScrollTabUI::CScrollTabUI(void) : m_nNorWidth(100) , m_nCurWidth(0) , m_nMinWidth(30) , m_dwTabSelColor(0xffffffff) , m_dwTabNorColor(0xfff0f0f0) , m_nSelIndex(-1) , m_pBtnAdd(NULL) , m_pCallback(NULL) { } CScrollTabUI::~CScrollTabUI(void) { } CControlUI* CScrollTabUI::AddTabItem( LPCTSTR lpText, bool bReset/*=false*/ ) { CScrollOptionUI* pTabItem = new CScrollOptionUI; if ( NULL == pTabItem ) return NULL; CDuiString strAttr; strAttr.Format(L"float=\"true\" bordercolor=\"#FF999999\" bordersize=\"1\" borderround=\"2,2\" text=\"%s\" tooltip=\"%s\"", lpText, lpText); pTabItem->ApplyAttributeList(strAttr); pTabItem->SetParent(this); if ( !Add(pTabItem) ) { delete pTabItem; return NULL; } if ( m_pTabItems.empty() ) m_nSelIndex = 0; m_pTabItems.push_back(pTabItem); if ( bReset ) ResetTabPos(); return pTabItem; } void CScrollTabUI::SelectItem( CControlUI* pItem ) { if ( m_nSelIndex>=0 && m_nSelIndex<m_pTabItems.size() ) { CControlUI* pCurItem = m_pTabItems[m_nSelIndex]; if ( pCurItem ) pCurItem->SetBkColor(m_dwTabNorColor); } pItem->SetBkColor(m_dwTabSelColor); int nUnSelIndex = m_nSelIndex; m_nSelIndex = GetTabItemIndex(pItem); if ( m_pCallback ) m_pCallback->OnScrollTabSelectChange(this, nUnSelIndex, m_nSelIndex); } void CScrollTabUI::SetAttribute( LPCTSTR pstrName, LPCTSTR pstrValue ) { if ( wcscmp(pstrName, L"TabWidth") == 0 ) { m_nNorWidth = _ttoi(pstrValue); return ; } if ( wcscmp(pstrName, L"MinTabWidth") == 0 ) { m_nMinWidth = _ttoi(pstrValue); return ; } if ( wcscmp(pstrName, L"TabSelColor") == 0 ) { if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); LPTSTR pstr = NULL; m_dwTabSelColor = _tcstoul(pstrValue, &pstr, 16); return ; } if ( wcscmp(pstrName, L"TabNorColor") == 0 ) { if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); LPTSTR pstr = NULL; m_dwTabNorColor = _tcstoul(pstrValue, &pstr, 16); return ; } CContainerUI::SetAttribute(pstrName, pstrValue); } void CScrollTabUI::Init() { m_pBtnAdd = new CButtonUI; CDuiString strAttr = L"float=\"true\" pos=\"0,0,0,0\" normalimage=\"file='tab_add.png' source='0,0,25,34' dest='0,0,25,30' \" \ hotimage=\"file='tab_add.png' source='25,0,50,34' dest='0,0,25,30' \" pushedimage=\"file='tab_add.png' source='50,0,75,34' dest='0,0,25,30' \" \ disabledimage=\"file='tab_add.png' source='75,0,100,34' dest='0,0,25,30' \" tooltip=\"新建\" "; m_pBtnAdd->ApplyAttributeList(strAttr); Add(m_pBtnAdd); m_pBtnAdd->OnNotify += MakeDelegate(this, &CScrollTabUI::OnBtnClickAdd); } void CScrollTabUI::DeleteItem( CControlUI* pItem ) { int nDelIndex = GetTabItemIndex(pItem); if ( nDelIndex == -1 ) return ; DeleteItem(nDelIndex); } void CScrollTabUI::DeleteItem( const int nIndex ) { if ( nIndex<0 || nIndex>=m_pTabItems.size() ) return ; Remove(m_pTabItems[nIndex]); m_pTabItems.erase(m_pTabItems.begin()+nIndex); int nCount = m_pTabItems.size(); if ( nCount>0 ) { if ( nIndex<m_nSelIndex ) m_nSelIndex--; else if ( nIndex == m_nSelIndex ) { m_nSelIndex = nCount-1; CControlUI* pItem = m_pTabItems[m_nSelIndex]; if ( pItem ) pItem->SetBkColor(m_dwTabSelColor); } ResetTabPos(); } else m_nSelIndex = -1; if ( m_pCallback ) m_pCallback->OnScrollTabCloseItem(this, nIndex, m_nSelIndex); } void CScrollTabUI::ResetTabPos() { int nCount = m_pTabItems.size(); if ( nCount == 0 ) { RECT rcItem = {m_rcItem.left, m_rcItem.top, 25, m_rcItem.bottom}; m_pBtnAdd->SetPos(rcItem); return ; } int nWidth = m_rcItem.right - m_rcItem.left-25; int nHeight= m_rcItem.bottom - m_rcItem.top; if ( nWidth/nCount < m_nMinWidth ) return ; if ( nCount*m_nNorWidth <= nWidth ) m_nCurWidth = m_nNorWidth; else m_nCurWidth = nWidth/nCount; RECT rcItem; for( size_t i=0; i<m_pTabItems.size(); ++i ) { rcItem.left = m_nCurWidth*i + m_rcItem.left; rcItem.top = 0 + m_rcItem.top; rcItem.right= rcItem.left + m_nCurWidth; rcItem.bottom = rcItem.top + nHeight; CControlUI* pItem = m_pTabItems[i]; pItem->SetPos(rcItem); if ( m_nSelIndex == i ) pItem->SetBkColor(m_dwTabSelColor); else pItem->SetBkColor(m_dwTabNorColor); } rcItem.left = rcItem.right; rcItem.right = rcItem.left + 25; m_pBtnAdd->SetPos(rcItem); } void CScrollTabUI::SetItemText( const int nIndex, LPCTSTR lpText ) { int nCount = m_pTabItems.size(); if ( 0 == nCount || nCount <= nIndex ) return ; CControlUI* pItem = m_pTabItems[nIndex]; if ( pItem ) { pItem->SetText(lpText); pItem->SetToolTip(lpText); } } int CScrollTabUI::GetTabItemIndex( CControlUI* pItem ) { int nIndex = -1; for ( size_t i=0; i<m_pTabItems.size(); ++i ) { if ( m_pTabItems[i] == pItem ) { nIndex = i; break; } } return nIndex; } bool CScrollTabUI::OnBtnClickAdd( void* pParam ) { TNotifyUI* pNotifyUI = (TNotifyUI*)pParam; if(pNotifyUI->sType != DUI_MSGTYPE_CLICK) return true; if ( m_pCallback ) m_pCallback->OnScrollTabAddItem(this); return true; } void CScrollTabUI::SetPos( RECT rc ) { CContainerUI::SetPos(rc); ResetTabPos(); } void CScrollTabUI::OnOptionDbClick(CControlUI* pOption) { if ( m_pCallback ) m_pCallback->OnScrollTabDbClick(this, m_nSelIndex); }子控件的消息都反射给父控件去处理,父控件同一管理所有子控件(计算宽度、设置选中、取消选中)。
4、未完成的
下载管理没做,应该对下载回调进行处理,用自己封装的下载库来处理进度,并加下载管理窗口;浏览记录,对用户输入网址进行匹配;
收藏夹,导入其他浏览器的收藏夹;
菜单项,各种设置。
相关文章推荐
- Minor issue about class define and the valid scope of scope operator
- iOS:搜索栏控件UISearchBar and SearchDisplayController的使用
- IOS基础UI之(五)UIAlertView、UIActionSheet和UIAlertController详解
- JAVA基础学习(十三)--String、StringBuilder、StringBuffer与包装类
- UIMenuController的使用,对UILabel拷贝以及定制菜单
- A014-values资源
- UCGUI使用外部字库芯片显示汉字
- poj 2031--Building a Space Station(prim)
- poj 2031--Building a Space Station(prim)
- chmod\chown\chgrp\umask\SUID \SGID 详解
- [LeetCode#272] Closest Binary Search Tree Value II
- 洛谷2524 Uim的情人节礼物·其之弐解题报告
- iOS 完全复制UIView
- UIBarButtonItem随着屏幕切换变化的问题
- 修改系统TabBar上图片和文字的颜色
- Android UI高级控件之ArrayAdapter
- iOS - UIButton(UIEdgeInsets)/设置button上的文字和图片上下垂直居中对齐
- 基于UIControl控件实现ios点赞功能
- JUnit4.8.2来源分析-2 org.junit.runner.Request
- Volley框架解析(七)-----Request解析