文章目录
1.CRichEditUI控件
- 1.CRichEditUI控件
- 2.作者答疑
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.作者答疑如有疑问,请留言。