第二章 第一小节Duilib中的根控件CControlUI

1.CControlUI控件

  上一章从底层的基础架构上分析duilib采用的核心部件,如解析xml文件为控件树,两条消息传递路线,控件的绘制流程和子控件的查找等等,如果想深入使用duilib,还是应该反复阅读源码的这些部分直到轮廓原理非常清晰。
  首先介绍常用属性,如下所示:

<Control parent="" notifies="setfocus killfocus timer menu windowinit(root)">
		<Attribute name="name" default="" type="STRING" comment="控件名字,同一窗口内必须唯一,如(testbtn)"/>
		<Attribute name="pos" default="0,0,0,0" type="RECT" comment="位置,如果为float控件则指定位置和大小,否则只指定大小,如(0,0,100,100)"/>
		<Attribute name="padding" default="0,0,0,0" type="RECT" comment="外边距,如(2,2,2,2)"/>
		<Attribute name="bkcolor" default="0x00000000" type="DWORD" comment="背景颜色,如(0xFFFF0000)"/>
		<Attribute name="bkcolor2" default="0x00000000" type="DWORD" comment="背景渐变色2,和bkcolor配合使用,如(0xFFFFFF00)"/>
		<Attribute name="bkcolor3" default="0x00000000" type="DWORD" comment="背景渐变色3,和bkcolor、bkcolor2配合使用,如(0xFFFF00FF)"/>
		<Attribute name="bordercolor" default="0x00000000" type="DWORD" comment="边框颜色,如(0xFF000000)"/>
		<Attribute name="focusbordercolor" default="0x00000000" type="DWORD" comment="获得焦点时边框的颜色,如(0xFFFF0000)"/>
		<Attribute name="colorhsl" default="false" type="BOOL" comment="本控件的颜色是否随窗口的hsl变化而变化,如(false)"/>
		<Attribute name="bordersize" default="0" type="INT | RECT" comment="可以设置INT或RECT类型的值。当值为ING时则左、上、右、下都用该值作为宽。值为RECT类型时则分别设置左、上、右、下的边框"/>
		<Attribute name="leftbordersize" default="0" type="INT" comment="左边边框大小,如(1),设置该值大于0,则将忽略bordersize属性的设置"/>
		<Attribute name="topbordersize" default="0" type="INT" comment="顶部边框大小,如(1),设置该值大于0,则将忽略bordersize属性的设置"/>
		<Attribute name="rightbordersize" default="0" type="INT" comment="右边边框大小,如(1),设置该值大于0,则将忽略bordersize属性的设置"/>
		<Attribute name="bottombordersize" default="0" type="INT" comment="底部边框大小,如(1),设置该值大于0,则将忽略bordersize属性的设置"/>
		<Attribute name="borderstyle" default="0" type="INT" comment="边框样式的设置,数值范围0-5"/>
		<Attribute name="borderround" default="0,0" type="SIZE" comment="边框圆角半径,如(2,2)"/>
		<Attribute name="bkimage" default="" type="STRING" comment="背景图片,如(bk.bmp或file='aaa.jpg' res='' restype='0' dest='0,0,0,0' source='0,0,0,0' corner='0,0,0,0' mask='#FF0000' fade='255' hole='false' xtiled='false' ytiled='false')"/>
		<Attribute name="width" default="0" type="INT" comment="控件预设的宽度,如(100)"/>
		<Attribute name="height" default="0" type="INT" comment="控件预设的高度,如(30)"/>
		<Attribute name="minwidth" default="0" type="INT" comment="控件的最小宽度,如(100)"/>
		<Attribute name="minheight" default="0" type="INT" comment="控件的最小高度,如(30)"/>
		<Attribute name="maxwidth" default="9999" type="INT" comment="控件的最大宽度,如(100)"/>
		<Attribute name="maxheight" default="9999" type="INT" comment="控件的最大高度,如(30)"/>
		<Attribute name="text" default="" type="STRING" comment="显示文本,如(测试文本)"/>
		<Attribute name="tooltip" default="" type="STRING" comment="鼠标悬浮提示,如(请在这里输入你的密码)"/>
		<Attribute name="userdata" default="" type="STRING" comment="自定义标识"/>
		<Attribute name="enabled" default="true" type="BOOL" comment="是否可以响应用户操作,如(true)"/>
		<Attribute name="mouse" default="true" type="BOOL" comment="本控件是否可以响应鼠标操作,如(true)"/>
		<Attribute name="visible" default="true" type="BOOL" comment="是否可见,如(true)"/>
		<Attribute name="float" default="false" type="BOOL" comment="是否使用绝对定位,如(true)"/>
		<Attribute name="shortcut" default="" type="CHAR" comment="对应的快捷键,如(P)"/>
		<Attribute name="menu" default="false" type="BOOL" comment="是否需要右键菜单,如(true)"/>
		<Attribute name="keyboard" default="true" type="BOOL" comment="非CButtonUI类忽略该值,为false时不支持TAB_STOP,且该对象不处理键盘信息"/>
	</Control>

  本章的主要内容是分析duilib提供的各类子控件,使读者真正掌握这些控件,也可以在控件出现bug的时候,快速找到问题。请读者大致浏览下源码,阅读注释,CControlUI根控件,源代码如下:

    class UILIB_API CControlUI
    {
        DECLARE_DUICONTROL(CControlUI)
    public:
        CControlUI();
        virtual ~CControlUI();

    public:
        virtual CDuiString GetName() const;
        virtual void SetName(LPCTSTR pstrName);
        virtual LPCTSTR GetClass() const;
        virtual LPVOID GetInterface(LPCTSTR pstrName);
        virtual UINT GetControlFlags() const;

        virtual bool Activate();
        virtual CPaintManagerUI* GetManager() const;
        virtual void SetManager(CPaintManagerUI* pManager, CControlUI* pParent, bool bInit = true);
        virtual CControlUI* GetParent() const;
        void setInstance(HINSTANCE instance = NULL) {m_instance = instance;};

        // 定时器
        bool SetTimer(UINT nTimerID, UINT nElapse);
        void KillTimer(UINT nTimerID);

        // 文本相关
        virtual CDuiString GetText() const;
        virtual void SetText(LPCTSTR pstrText);

        virtual bool IsResourceText() const;
        virtual void SetResourceText(bool bResource);

        virtual bool IsDragEnabled() const;
        virtual void SetDragEnable(bool bDrag);

        virtual bool IsDropEnabled() const;
        virtual void SetDropEnable(bool bDrop);

        // 图形相关
        LPCTSTR GetGradient();
        void SetGradient(LPCTSTR pStrImage);
        DWORD GetBkColor() const;
        void SetBkColor(DWORD dwBackColor);
        DWORD GetBkColor2() const;
        void SetBkColor2(DWORD dwBackColor);
        DWORD GetBkColor3() const;
        void SetBkColor3(DWORD dwBackColor);
        DWORD GetForeColor() const;
        void SetForeColor(DWORD dwForeColor);
        LPCTSTR GetBkImage();
        void SetBkImage(LPCTSTR pStrImage);
        LPCTSTR GetForeImage() const;
        void SetForeImage(LPCTSTR pStrImage);

        DWORD GetFocusBorderColor() const;
        void SetFocusBorderColor(DWORD dwBorderColor);
        bool IsColorHSL() const;
        void SetColorHSL(bool bColorHSL);
        SIZE GetBorderRound() const;
        void SetBorderRound(SIZE cxyRound);
        bool DrawImage(HDC hDC, LPCTSTR pStrImage, LPCTSTR pStrModify = NULL);

        //边框相关
        int GetBorderSize() const;
        void SetBorderSize(int nSize);
        DWORD GetBorderColor() const;
        void SetBorderColor(DWORD dwBorderColor);
        void SetBorderSize(RECT rc);
        int GetLeftBorderSize() const;
        void SetLeftBorderSize(int nSize);
        int GetTopBorderSize() const;
        void SetTopBorderSize(int nSize);
        int GetRightBorderSize() const;
        void SetRightBorderSize(int nSize);
        int GetBottomBorderSize() const;
        void SetBottomBorderSize(int nSize);
        int GetBorderStyle() const;
        void SetBorderStyle(int nStyle);

        // 位置相关
        virtual RECT GetRelativePos() const; // 相对(父控件)位置
        virtual RECT GetClientPos() const; // 客户区域(除去scrollbar和inset)
        virtual const RECT& GetPos() const;
        virtual void SetPos(RECT rc, bool bNeedInvalidate = true);
        virtual void Move(SIZE szOffset, bool bNeedInvalidate = true);
        virtual int GetWidth() const;
        virtual int GetHeight() const;
        virtual int GetX() const;
        virtual int GetY() const;
        virtual RECT GetPadding() const;
        virtual void SetPadding(RECT rcPadding); // 设置外边距,由上层窗口绘制
        virtual SIZE GetFixedXY() const;         // 实际大小位置使用GetPos获取,这里得到的是预设的参考值
        virtual void SetFixedXY(SIZE szXY);      // 仅float为true时有效
        virtual int GetFixedWidth() const;       // 实际大小位置使用GetPos获取,这里得到的是预设的参考值
        virtual void SetFixedWidth(int cx);      // 预设的参考值
        virtual int GetFixedHeight() const;      // 实际大小位置使用GetPos获取,这里得到的是预设的参考值
        virtual void SetFixedHeight(int cy);     // 预设的参考值
        virtual int GetMinWidth() const;
        virtual void SetMinWidth(int cx);
        virtual int GetMaxWidth() const;
        virtual void SetMaxWidth(int cx);
        virtual int GetMinHeight() const;
        virtual void SetMinHeight(int cy);
        virtual int GetMaxHeight() const;
        virtual void SetMaxHeight(int cy);
        virtual TPercentInfo GetFloatPercent() const;
        virtual void SetFloatPercent(TPercentInfo piFloatPercent);
        virtual void SetFloatAlign(UINT uAlign);
        virtual UINT GetFloatAlign() const;
        // 鼠标提示
        virtual CDuiString GetToolTip() const;
        virtual void SetToolTip(LPCTSTR pstrText);
        virtual void SetToolTipWidth(int nWidth);
        virtual int      GetToolTipWidth(void);    // 多行ToolTip单行最长宽度

        // 光标
        virtual WORD GetCursor();
        virtual void SetCursor(WORD wCursor);

        // 快捷键
        virtual TCHAR GetShortcut() const;
        virtual void SetShortcut(TCHAR ch);

        // 菜单
        virtual bool IsContextMenuUsed() const;
        virtual void SetContextMenuUsed(bool bMenuUsed);

        // 用户属性
        virtual const CDuiString& GetUserData(); // 辅助函数,供用户使用
        virtual void SetUserData(LPCTSTR pstrText); // 辅助函数,供用户使用
        virtual UINT_PTR GetTag() const; // 辅助函数,供用户使用
        virtual void SetTag(UINT_PTR pTag); // 辅助函数,供用户使用

        // 一些重要的属性
        virtual bool IsVisible() const;
        virtual void SetVisible(bool bVisible = true);
        virtual void SetInternVisible(bool bVisible = true); // 仅供内部调用,有些UI拥有窗口句柄,需要重写此函数
        virtual bool IsEnabled() const;
        virtual void SetEnabled(bool bEnable = true);
        virtual bool IsMouseEnabled() const;
        virtual void SetMouseEnabled(bool bEnable = true);
        virtual bool IsKeyboardEnabled() const;
        virtual void SetKeyboardEnabled(bool bEnable = true);
        virtual bool IsFocused() const;
        virtual void SetFocus();
        virtual bool IsFloat() const;
        virtual void SetFloat(bool bFloat = true);

        virtual CControlUI* FindControl(FINDCONTROLPROC Proc, LPVOID pData, UINT uFlags);

        void Invalidate();
        bool IsUpdateNeeded() const;
        void NeedUpdate();
        void NeedParentUpdate();
        DWORD GetAdjustColor(DWORD dwColor);

        virtual void Init();
        virtual void DoInit();

        virtual void Event(TEventUI& event);
        virtual void DoEvent(TEventUI& event);

        // 自定义(未处理的)属性
        void AddCustomAttribute(LPCTSTR pstrName, LPCTSTR pstrAttr);
        LPCTSTR GetCustomAttribute(LPCTSTR pstrName) const;
        bool RemoveCustomAttribute(LPCTSTR pstrName);
        void RemoveAllCustomAttribute();

        virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
        CControlUI* ApplyAttributeList(LPCTSTR pstrList);

        virtual SIZE EstimateSize(SIZE szAvailable);
        virtual bool Paint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl = NULL); // 返回要不要继续绘制
        virtual bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl);
        virtual void PaintBkColor(HDC hDC);
        virtual void PaintBkImage(HDC hDC);
        virtual void PaintStatusImage(HDC hDC);
        virtual void PaintForeColor(HDC hDC);
        virtual void PaintForeImage(HDC hDC);
        virtual void PaintText(HDC hDC);
        virtual void PaintBorder(HDC hDC);

        virtual void DoPostPaint(HDC hDC, const RECT& rcPaint);

        //虚拟窗口参数
        void SetVirtualWnd(LPCTSTR pstrValue);
        CDuiString GetVirtualWnd() const;

    public:
        CEventSource OnInit;
        CEventSource OnDestroy;
        CEventSource OnSize;
        CEventSource OnEvent;
        CEventSource OnNotify;

    protected:
        CPaintManagerUI* m_pManager;
        CControlUI* m_pParent;
        CDuiString m_sVirtualWnd;
        CDuiString m_sName;
        bool m_bUpdateNeeded;
        bool m_bMenuUsed;
        RECT m_rcItem;
        RECT m_rcPadding;
        SIZE m_cXY;
        SIZE m_cxyFixed;
        SIZE m_cxyMin;
        SIZE m_cxyMax;
        bool m_bVisible;
        bool m_bInternVisible;
        bool m_bEnabled;
        bool m_bMouseEnabled;
        bool m_bKeyboardEnabled ;
        bool m_bFocused;
        bool m_bFloat;
        TPercentInfo m_piFloatPercent;
        UINT m_uFloatAlign;
        bool m_bSetPos; // 防止SetPos循环调用

        bool m_bDragEnabled;
        bool m_bDropEnabled;

        bool m_bResourceText;
        CDuiString m_sText;
        CDuiString m_sToolTip;
        TCHAR m_chShortcut;
        CDuiString m_sUserData;
        UINT_PTR m_pTag;

        CDuiString m_sGradient;
        DWORD m_dwBackColor;
        DWORD m_dwBackColor2;
        DWORD m_dwBackColor3;
        DWORD m_dwForeColor;
        CDuiString m_sBkImage;
        CDuiString m_sForeImage;
        DWORD m_dwBorderColor;
        DWORD m_dwFocusBorderColor;
        bool m_bColorHSL;
        int m_nBorderSize;
        int m_nBorderStyle;
        int m_nTooltipWidth;
        WORD m_wCursor;
        SIZE m_cxyBorderRound;
        RECT m_rcPaint;
        RECT m_rcBorderSize;
        HINSTANCE m_instance;

        CStdStringPtrMap m_mCustomAttrHash;
    };

  源码中的注释已经解释了部分代码的作用,源代码虽然长,但是主要一部分是事件的响应,另一部分是控件的绘制,前一部分在消息循环中已经讲解,在这小节中,集中讲解控件的绘制,如果需要开发自定义控件和熟悉控件的使用,对这部分就不得不熟悉。这部分代码放在CControlUI函数中,源码如下所示:

bool CControlUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
    {
        // 绘制循序:背景颜色->背景图->状态图->文本->边框
        SIZE cxyBorderRound;
        RECT rcBorderSize;
        if (m_pManager) {
            cxyBorderRound = GetManager()->GetDPIObj()->Scale(m_cxyBorderRound);
            rcBorderSize = GetManager()->GetDPIObj()->Scale(m_rcBorderSize);
        }
        else {
            cxyBorderRound = m_cxyBorderRound;
            rcBorderSize = m_rcBorderSize;
        }

        if( cxyBorderRound.cx > 0 || cxyBorderRound.cy > 0 ) {
            CRenderClip roundClip;
            CRenderClip::GenerateRoundClip(hDC, m_rcPaint,  m_rcItem, cxyBorderRound.cx, cxyBorderRound.cy, roundClip);
            PaintBkColor(hDC);
            PaintBkImage(hDC);
            PaintStatusImage(hDC);
            PaintForeColor(hDC);
            PaintForeImage(hDC);
            PaintText(hDC);
            PaintBorder(hDC);
        }
        else {
            PaintBkColor(hDC);
            PaintBkImage(hDC);
            PaintStatusImage(hDC);
            PaintForeColor(hDC);
            PaintForeImage(hDC);
            PaintText(hDC);
            PaintBorder(hDC);
        }
        return true;
    }

  以上代码比较清晰,就是按照背景颜色->背景图->状态图->文本->边框的顺序绘制,第一个是绘制背景颜色,代码如下所示:

void CControlUI::PaintBkColor(HDC hDC)
    {
    	//支持三重渐变色的绘制
        if( m_dwBackColor != 0 ) {
            bool bVer = (m_sGradient.CompareNoCase(_T("hor")) != 0);
            if( m_dwBackColor2 != 0 ) {
                if( m_dwBackColor3 != 0 ) {
                    RECT rc = m_rcItem;
                    rc.bottom = (rc.bottom + rc.top) / 2;
                    CRenderEngine::DrawGradient(hDC, rc, GetAdjustColor(m_dwBackColor), GetAdjustColor(m_dwBackColor2), bVer, 8);
                    rc.top = rc.bottom;
                    rc.bottom = m_rcItem.bottom;
                    CRenderEngine::DrawGradient(hDC, rc, GetAdjustColor(m_dwBackColor2), GetAdjustColor(m_dwBackColor3), bVer, 8);
                }
                else {
                    CRenderEngine::DrawGradient(hDC, m_rcItem, GetAdjustColor(m_dwBackColor), GetAdjustColor(m_dwBackColor2), bVer, 16);
                }
            }
            else if( m_dwBackColor >= 0xFF000000 ) CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwBackColor));
            else CRenderEngine::DrawColor(hDC, m_rcItem, GetAdjustColor(m_dwBackColor));
        }
    }

  第二步是绘制背景图,代码如下所示:

    void CControlUI::PaintBkImage(HDC hDC)
    {
        if( m_sBkImage.IsEmpty() ) return;
        if( !DrawImage(hDC, (LPCTSTR)m_sBkImage) ) {}
    }

  第三步是绘制状态图,根控件,该函数是空的,在一些动态控件中,该函数是有的,代码如下所示:

    void CControlUI::PaintStatusImage(HDC hDC)
    {
        return;
    }

  第四步是绘制前景色,代码如下所示:

	void CControlUI::PaintForeColor(HDC hDC)
    {
        CRenderEngine::DrawColor(hDC, m_rcItem, GetAdjustColor(m_dwForeColor));
    }

  第五步是绘制前景图像,代码如下所示:

    void CControlUI::PaintForeImage(HDC hDC)
    {
        if( m_sForeImage.IsEmpty() ) return;
        DrawImage(hDC, (LPCTSTR)m_sForeImage);
    }

  第六步是绘制文本,代码如下所示:

    void CControlUI::PaintText(HDC hDC)
    {
        return;
    }

  最后一步是绘制边框,代码如下所示:

 void CControlUI::PaintBorder(HDC hDC)
    {
        int nBorderSize;
        SIZE cxyBorderRound;
        RECT rcBorderSize;
        if (m_pManager) {
            nBorderSize = GetManager()->GetDPIObj()->Scale(m_nBorderSize);
            cxyBorderRound = GetManager()->GetDPIObj()->Scale(m_cxyBorderRound);
            rcBorderSize = GetManager()->GetDPIObj()->Scale(m_rcBorderSize);
        }
        else {
            nBorderSize = m_nBorderSize;
            cxyBorderRound = m_cxyBorderRound;
            rcBorderSize = m_rcBorderSize;
        }

        if(m_dwBorderColor != 0 || m_dwFocusBorderColor != 0) {
            //画圆角边框
            if(nBorderSize > 0 && ( cxyBorderRound.cx > 0 || cxyBorderRound.cy > 0 )) {
                if (IsFocused() && m_dwFocusBorderColor != 0)
                    CRenderEngine::DrawRoundRect(hDC, m_rcItem, nBorderSize, cxyBorderRound.cx, cxyBorderRound.cy, GetAdjustColor(m_dwFocusBorderColor), m_nBorderStyle);
                else
                    CRenderEngine::DrawRoundRect(hDC, m_rcItem, nBorderSize, cxyBorderRound.cx, cxyBorderRound.cy, GetAdjustColor(m_dwBorderColor), m_nBorderStyle);
            }
            else {
                if (IsFocused() && m_dwFocusBorderColor != 0 && nBorderSize > 0) { 
                    CRenderEngine::DrawRect(hDC, m_rcItem, nBorderSize, GetAdjustColor(m_dwFocusBorderColor), m_nBorderStyle);
                }
                else if(rcBorderSize.left > 0 || rcBorderSize.top > 0 || rcBorderSize.right > 0 || rcBorderSize.bottom > 0) {
                    RECT rcBorder;

                    if(rcBorderSize.left > 0){
                        rcBorder        = m_rcItem;
                        rcBorder.right    = rcBorder.left;
                        CRenderEngine::DrawLine(hDC,rcBorder,rcBorderSize.left,GetAdjustColor(m_dwBorderColor),m_nBorderStyle);
                    }
                    if(rcBorderSize.top > 0){
                        rcBorder        = m_rcItem;
                        rcBorder.bottom    = rcBorder.top;
                        CRenderEngine::DrawLine(hDC,rcBorder,rcBorderSize.top,GetAdjustColor(m_dwBorderColor),m_nBorderStyle);
                    }
                    if(rcBorderSize.right > 0){
                        rcBorder        = m_rcItem;
                        rcBorder.right -= 1;
                        rcBorder.left    = rcBorder.right;
                        CRenderEngine::DrawLine(hDC,rcBorder,rcBorderSize.right,GetAdjustColor(m_dwBorderColor),m_nBorderStyle);
                    }
                    if(rcBorderSize.bottom > 0){
                        rcBorder        = m_rcItem;
                        rcBorder.bottom -= 1;
                        rcBorder.top    = rcBorder.bottom;
                        CRenderEngine::DrawLine(hDC,rcBorder,rcBorderSize.bottom,GetAdjustColor(m_dwBorderColor),m_nBorderStyle);
                    }
                }
                else if(nBorderSize > 0) {
                    CRenderEngine::DrawRect(hDC, m_rcItem, nBorderSize, GetAdjustColor(m_dwBorderColor), m_nBorderStyle);
                }
            }
        }
    }

  绘制圆角矩形或者普通矩形,或者可控制矩形的四条边的绘制。以上绘制步骤在头文件里都申明为虚函数,继承至该控件的新控件可以修改部分,从而实现新控件的功能,头文件的代码如下:

        virtual bool Paint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl = NULL); // 返回要不要继续绘制
        virtual bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl);
        virtual void PaintBkColor(HDC hDC);
        virtual void PaintBkImage(HDC hDC);
        virtual void PaintStatusImage(HDC hDC);
        virtual void PaintForeColor(HDC hDC);
        virtual void PaintForeImage(HDC hDC);
        virtual void PaintText(HDC hDC);
        virtual void PaintBorder(HDC hDC);

  【小节】从以上的源代码分析,duilib的绘制功能并不强大,只是实现了文本,图像和边框的简单绘制,那为什么duilib又能制作那么绚丽的界面效果,原因在于强大的贴图功能,就是将效果制作成图片,然后绘制到控件上,而不需要从代码上实现。

2.作者答疑


  如有疑问,请留言。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
duilib 是一个基于C++的GUI库,用于构建Windows平台上的桌面应用程序。CEF(Chromium Embedded Framework)是一个开源项目,用于将Chromium引擎集成到其他应用程序,实现浏览器功能。在duilib使用CEF控件可以实现在应用程序嵌入一个内置的浏览器。 要在duilib使用CEF控件,首先需要下载CEF的二进制文件,并将相应的头文件和库文件链接到duilib项目。然后在duilibUI布局文件添加一个容器控件用来承载CEF控件,比如一个<Control>标签定义一个名为"browser"的控件。接着在C++代码通过CreateControl()方法创建CEF控件并将其添加到布局的容器控件。 在CEF控件加载网页可以通过调用LoadURL()方法来实现,比如在初始化时可以加载一个初始的网页。同时也可以通过CEF提供的接口来处理网页加载完成、前进后退等事件。另外,也可以在CEF的控件执行JavaScript代码,比如修改网页内容或者与网页交互等。 当应用程序退出时,需要通过调用CEF控件的Close()方法来释放资源并关闭CEF的相关进程。另外,需要确保在适当的时候调用CEF的资源释放方法,比如在窗口销毁前调用Shutdown()方法来释放资源。 在duilib使用CEF控件可以帮助开发者实现嵌入式浏览器功能,比如在应用程序展示在线内容或者实现基于web的功能。同时也能够与duilib的其他控件进行交互,实现更加丰富的用户体验。通过合理的使用和管理,可以让应用程序在集成CEF控件的同时保持稳定性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值