您当前的位置: 首页 >  ui

插件开发

暂无认证

  • 1浏览

    0关注

    492博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

第二章 第八小节Duilib中的CRichEditUI控件-富文本编辑框

插件开发 发布时间:2022-04-03 07:29:04 ,浏览量:1

文章目录
    • 1.CRichEditUI控件
    • 2.作者答疑

1.CRichEditUI控件

  CRichEditUI控件是duilib中的富文本输入控件,以下则是常用参数设置。



  上面的属性参数,属性列表中有解释,如下所示:

	
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	

  富文本编辑框是对win32 RichEdit的一种实现,源代码如下所示:

class CTxtWinHost;

    class UILIB_API CRichEditUI : public CContainerUI, public IMessageFilterUI
    {
        DECLARE_DUICONTROL(CRichEditUI)
    public:
        CRichEditUI();
        ~CRichEditUI();

        LPCTSTR GetClass() const;
        LPVOID GetInterface(LPCTSTR pstrName);
        UINT GetControlFlags() const;

        bool IsMultiLine();
        void SetMultiLine(bool bMultiLine);
        bool IsWantTab();
        void SetWantTab(bool bWantTab = true);
        bool IsWantReturn();
        void SetWantReturn(bool bWantReturn = true);
        bool IsWantCtrlReturn();
        void SetWantCtrlReturn(bool bWantCtrlReturn = true);
        bool IsTransparent();
        void SetTransparent(bool bTransparent = true);
        bool IsRich();
        void SetRich(bool bRich = true);
        bool IsReadOnly();
        void SetReadOnly(bool bReadOnly = true);
        bool IsWordWrap();
        void SetWordWrap(bool bWordWrap = true);
        int GetFont();
        void SetFont(int index);
        void SetFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
        LONG GetWinStyle();
        void SetWinStyle(LONG lStyle);
        DWORD GetTextColor();
        void SetTextColor(DWORD dwTextColor);
        int GetLimitText();
        void SetLimitText(int iChars);
        long GetTextLength(DWORD dwFlags = GTL_DEFAULT) const;
        CDuiString GetText() const;
        void SetText(LPCTSTR pstrText);
        bool IsModify() const;
        void SetModify(bool bModified = true) const;
        void GetSel(CHARRANGE &cr) const;
        void GetSel(long& nStartChar, long& nEndChar) const;
        int SetSel(CHARRANGE &cr);
        int SetSel(long nStartChar, long nEndChar);
        void ReplaceSel(LPCTSTR lpszNewText, bool bCanUndo);
        void ReplaceSelW(LPCWSTR lpszNewText, bool bCanUndo = false);
        CDuiString GetSelText() const;
        int SetSelAll();
        int SetSelNone();
        WORD GetSelectionType() const;
        bool GetZoom(int& nNum, int& nDen) const;
        bool SetZoom(int nNum, int nDen);
        bool SetZoomOff();
        bool GetAutoURLDetect() const;
        bool SetAutoURLDetect(bool bAutoDetect = true);
        DWORD GetEventMask() const;
        DWORD SetEventMask(DWORD dwEventMask);
        CDuiString GetTextRange(long nStartChar, long nEndChar) const;
        void HideSelection(bool bHide = true, bool bChangeStyle = false);
        void ScrollCaret();
        int InsertText(long nInsertAfterChar, LPCTSTR lpstrText, bool bCanUndo = false);
        int AppendText(LPCTSTR lpstrText, bool bCanUndo = false);
        DWORD GetDefaultCharFormat(CHARFORMAT2 &cf) const;
        bool SetDefaultCharFormat(CHARFORMAT2 &cf);
        DWORD GetSelectionCharFormat(CHARFORMAT2 &cf) const;
        bool SetSelectionCharFormat(CHARFORMAT2 &cf);
        bool SetWordCharFormat(CHARFORMAT2 &cf);
        DWORD GetParaFormat(PARAFORMAT2 &pf) const;
        bool SetParaFormat(PARAFORMAT2 &pf);
        bool CanUndo();
        bool CanRedo();
        bool CanPaste();
        bool Redo();
        bool Undo();
        void Clear();
        void Copy();
        void Cut();
        void Paste();
        int GetLineCount() const;
        CDuiString GetLine(int nIndex, int nMaxLength) const;
        int LineIndex(int nLine = -1) const;
        int LineLength(int nLine = -1) const;
        bool LineScroll(int nLines, int nChars = 0);
        CDuiPoint GetCharPos(long lChar) const;
        long LineFromChar(long nIndex) const;
        CDuiPoint PosFromChar(UINT nChar) const;
        int CharFromPos(CDuiPoint pt) const;
        void EmptyUndoBuffer();
        UINT SetUndoLimit(UINT nLimit);
        long StreamIn(int nFormat, EDITSTREAM &es);
        long StreamOut(int nFormat, EDITSTREAM &es);
        void SetAccumulateDBCMode(bool bDBCMode);
        bool IsAccumulateDBCMode();

        RECT GetTextPadding() const;
        void SetTextPadding(RECT rc);
        LPCTSTR GetNormalImage();
        void SetNormalImage(LPCTSTR pStrImage);
        LPCTSTR GetHotImage();
        void SetHotImage(LPCTSTR pStrImage);
        LPCTSTR GetFocusedImage();
        void SetFocusedImage(LPCTSTR pStrImage);
        LPCTSTR GetDisabledImage();
        void SetDisabledImage(LPCTSTR pStrImage);
        void PaintStatusImage(HDC hDC);

        void SetTipValue(LPCTSTR pStrTipValue);
        LPCTSTR GetTipValue();
        void SetTipValueColor(LPCTSTR pStrColor);
        DWORD GetTipValueColor();
        void SetTipValueAlign(UINT uAlign);
        UINT GetTipValueAlign();

        void DoInit();
        bool SetDropAcceptFile(bool bAccept);
        // 注意:TxSendMessage和SendMessage是有区别的,TxSendMessage没有multibyte和unicode自动转换的功能,
        // 而richedit2.0内部是以unicode实现的,在multibyte程序中,必须自己处理unicode到multibyte的转换
        virtual HRESULT TxSendMessage(UINT msg, WPARAM wparam, LPARAM lparam, LRESULT *plresult) const; 
        IDropTarget* GetTxDropTarget();
        virtual bool OnTxViewChanged();
        virtual void OnTxNotify(DWORD iNotify, void *pv);

        void SetScrollPos(SIZE szPos, bool bMsg = true);
        void LineUp();
        void LineDown();
        void PageUp();
        void PageDown();
        void HomeUp();
        void EndDown();
        void LineLeft();
        void LineRight();
        void PageLeft();
        void PageRight();
        void HomeLeft();
        void EndRight();

        SIZE EstimateSize(SIZE szAvailable);
        void SetPos(RECT rc, bool bNeedInvalidate = true);
        void Move(SIZE szOffset, bool bNeedInvalidate = true);
        void DoEvent(TEventUI& event);
        bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl);

        void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);

        LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled);

    protected:
        enum { 
            DEFAULT_TIMERID = 20,
        };

        CTxtWinHost* m_pTwh;
        bool m_bVScrollBarFixing;
        bool m_bWantTab;
        bool m_bWantReturn;
        bool m_bWantCtrlReturn;
        bool m_bTransparent;
        bool m_bRich;
        bool m_bReadOnly;
        bool m_bWordWrap;
        DWORD m_dwTextColor;
        int m_iFont;
        int m_iLimitText;
        LONG m_lTwhStyle;
        bool m_bDrawCaret;
        bool m_bInited;

        bool  m_fAccumulateDBC ; // TRUE - need to cumulate ytes from 2 WM_CHAR msgs
        // we are in this mode when we receive VK_PROCESSKEY
        UINT m_chLeadByte; // use when we are in _fAccumulateDBC mode

        RECT m_rcTextPadding;
        UINT m_uButtonState;
        CDuiString m_sNormalImage;
        CDuiString m_sHotImage;
        CDuiString m_sFocusedImage;
        CDuiString m_sDisabledImage;
        CDuiString m_sTipValue;
        DWORD m_dwTipValueColor;
        UINT m_uTipValueAlign;
    };

  除此之外,查看下两个关键函数的实现,DoEvent函数和DoPaint函数,这个实现与CEditUI对象不同,它把所有的消息转发给富文本控件。

void CRichEditUI::DoEvent(TEventUI& event)
    {
        if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type DoEvent(event);
            else CControlUI::DoEvent(event);
            return;
        }

        if( event.Type == UIEVENT_SETCURSOR && IsEnabled() )
        {
            if( m_pTwh && m_pTwh->DoSetCursor(NULL, &event.ptMouse) ) {
                return;
            }
        }
        else if( event.Type == UIEVENT_WINDOWSIZE ) {
            if( m_pTwh ) m_pTwh->NeedFreshCaret();
        }
        else if( event.Type == UIEVENT_SETFOCUS ) {
            if( m_pTwh ) {
                m_pTwh->OnTxInPlaceActivate(NULL);
                m_pTwh->GetTextServices()->TxSendMessage(WM_SETFOCUS, 0, 0, 0);
            }
            m_bFocused = true;
            Invalidate();
            return;
        }
        if( event.Type == UIEVENT_KILLFOCUS )  {
            if( m_pTwh ) {
                m_pTwh->OnTxInPlaceActivate(NULL);
                m_pTwh->GetTextServices()->TxSendMessage(WM_KILLFOCUS, 0, 0, 0);
            }
            m_bFocused = false;
            Invalidate();
            return;
        }
        else if( event.Type == UIEVENT_TIMER ) {
            if( event.wParam == DEFAULT_TIMERID ) {
                if( m_pTwh && m_pManager->IsLayered() && IsFocused() ) {
                    if (::GetFocus() != m_pManager->GetPaintWindow()) return;
                    m_bDrawCaret = !m_bDrawCaret;
                    POINT ptCaret;
                    ::GetCaretPos(&ptCaret);
                    RECT rcCaret = { ptCaret.x, ptCaret.y, ptCaret.x + m_pTwh->GetCaretWidth(), 
                        ptCaret.y + m_pTwh->GetCaretHeight() };
                    RECT rcTemp = rcCaret;
                    if( !::IntersectRect(&rcCaret, &rcTemp, &m_rcItem) ) return;
                    CControlUI* pParent = this;
                    RECT rcParent;
                    while( pParent = pParent->GetParent() ) {
                        rcTemp = rcCaret;
                        rcParent = pParent->GetPos();
                        if( !::IntersectRect(&rcCaret, &rcTemp, &rcParent) ) {
                            return;
                        }
                    }                    
                    m_pManager->Invalidate(rcCaret);
                }
                return;
            }
            if( m_pTwh ) {
                m_pTwh->GetTextServices()->TxSendMessage(WM_TIMER, event.wParam, event.lParam, 0);
            } 
            return;
        }
        if( event.Type == UIEVENT_SCROLLWHEEL ) {
            if( (event.wKeyState & MK_CONTROL) != 0  ) {
                return;
            }
        }
        if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK ) 
        {
            return;
        }
        if( event.Type == UIEVENT_MOUSEMOVE ) 
        {
            return;
        }
        if( event.Type == UIEVENT_BUTTONUP ) 
        {
            return;
        }
        if( event.Type > UIEVENT__KEYBEGIN && event.Type GetControlRect(&rc);
            // Remember wparam is actually the hdc and lparam is the update
            // rect because this message has been preprocessed by the window.
            m_pTwh->GetTextServices()->TxDraw(
                DVASPECT_CONTENT,          // Draw Aspect
                /*-1*/0,                // Lindex
                NULL,                    // Info for drawing optimazation
                NULL,                    // target device information
                hDC,                    // Draw device HDC
                NULL,                        // Target device HDC
                (RECTL*)&rc,            // Bounding client rectangle
                NULL,                     // Clipping rectangle for metafiles
                (RECT*)&rcPaint,        // Update rectangle
                NULL,                        // Call back function
                NULL,                    // Call back parameter
                0);                        // What view of the object
            if( m_bVScrollBarFixing ) {
                LONG lWidth = rc.right - rc.left + m_pVerticalScrollBar->GetFixedWidth();
                LONG lHeight = 0;
                SIZEL szExtent = { -1, -1 };
                m_pTwh->GetTextServices()->TxGetNaturalSize(
                    DVASPECT_CONTENT, 
                    GetManager()->GetPaintDC(), 
                    NULL,
                    NULL,
                    TXTNS_FITTOCONTENT,
                    &szExtent,
                    &lWidth,
                    &lHeight);
                if( lHeight  0 ) {
            RECT rc = m_rcItem;
            rc.left += m_rcInset.left;
            rc.top += m_rcInset.top;
            rc.right -= m_rcInset.right;
            rc.bottom -= m_rcInset.bottom;
            if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
            if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();

            if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) {
                for( int it = 0; it IsVisible() ) continue;
                    if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
                    if( pControl->IsFloat() ) {
                        if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
                        if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
                    }
                }
            }
            else {
                CRenderClip childClip;
                CRenderClip::GenerateClip(hDC, rcTemp, childClip);
                for( int it = 0; it IsVisible() ) continue;
                    if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
                    if( pControl->IsFloat() ) {
                        if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
                        CRenderClip::UseOldClipBegin(hDC, childClip);
                        if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
                        CRenderClip::UseOldClipEnd(hDC, childClip);
                    }
                    else {
                        if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue;
                        if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
                    }
                }
            }
        }

  CRichEditUI控件是富文本编辑框控件,同时它也是一个容器控件,可以非常方便的加入子控件。同时通过查找控件函数,找到子控件。

2.作者答疑

  如有疑问,请留言。

关注
打赏
1665481431
查看更多评论
立即登录/注册

微信扫码登录

0.0483s