CRicheditctrl- OnMouseMove

abc abc 351 Reputation points
2020-09-22T08:02:40.51+00:00

In subclassed cricheditctrl,I am using green color for particular format of text( %#__#% embed text) .In onmousemove function if char is embed text I am displaying hand cursor.

To check a char is embed text or not, I am checking the character color using below code. I am unable to select the text(multiple charcaters) in backward since I am Calling SetSel in onmousemove(), but for forward selection I am not facing any problem.

It seems that autoselection fails after a backwards selection.

How to handle this?
void CMyRichEditCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
long char_index=CharFromPos(point);
CHARRANGE crOld;
CHARFORMAT cf;
GetSel(crOld);
SetSel(char_index,char_index+1);
CString strString=GetSelText();
GetSelectionCharFormat(cf);
bEmbed=(!strString.IsEmpty() && cf.crTextColor == EMBEDCOLOR)?true:false;
SetSel(crOld);
if(bEmbed)m_bHandCursor=true;
CRichEditCtrl::OnMouseMove(nFlags, point);
}
Even you can reproduce the same issue just by having below code. if we call setsel inside onmousemove backward autoselection is not working

void CMyRichEditCtrl::OnMouseMove(UINT nFlags, CPoint point)
{

CHARRANGE crOld;
GetSel(crOld);
SetSel(crOld);
CRichEditCtrl::OnMouseMove(nFlags, point);
}

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,636 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. RLWA32 43,306 Reputation points
    2020-09-22T15:07:25.467+00:00

    I used the TOM (Text Object Model) interfaces of the rich edit control to determine if the mouse was over green text to avoid changing the control's selection.

    Add

    #include <RichOle.h>
    #include <TOM.h>
    

    Then in the declaration of CMyRichEditCtrl -

    ....rest of class
    public:
     afx_msg void OnMouseMove(UINT nFlags, CPoint point);
     virtual void PreSubclassWindow();
     afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
    private:
     CComPtr<ITextDocument> m_pDoc;
     HCURSOR m_hand;
     bool m_bOverGreen{ false };
    };
    

    In the definition of CMyRichEditCtrl class -

    void CMyRichEditCtrl::OnMouseMove(UINT nFlags, CPoint point)
    {
     // TODO: Add your message handler code here and/or call default
     CRichEditCtrl::OnMouseMove(nFlags, point);
     ClientToScreen(&point);
     CComPtr<ITextRange> pCursor;
     m_bOverGreen = false;
     if ( SUCCEEDED(m_pDoc->RangeFromPoint(point.x, point.y, &pCursor)))
     {
     CComPtr<ITextFont> pFont;
     if (SUCCEEDED(pCursor->GetFont(&pFont)))
     {
     long clr;
     if (SUCCEEDED(pFont->GetForeColor(&clr)))
     m_bOverGreen = clr == RGB(0, 255, 0);
     }
     }
    }
    
    
    void CMyRichEditCtrl::PreSubclassWindow()
    {
     // TODO: Add your specialized code here and/or call the base class
     CComPtr<IRichEditOle> pOle;
     pOle.Attach(GetIRichEditOle());
     ASSERT(pOle);
     pOle.QueryInterface(&m_pDoc);
     CRichEditCtrl::PreSubclassWindow();
    }
    
    
    BOOL CMyRichEditCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
    {
     // TODO: Add your message handler code here and/or call default
     if (m_bOverGreen)
     {
     SetCursor(m_hand);
     return TRUE;
     }
     else
     return CRichEditCtrl::OnSetCursor(pWnd, nHitTest, message);
    }
    
    2 people found this answer helpful.

  2. Viorel 114.7K Reputation points
    2020-09-22T11:49:29.617+00:00

    Maybe you should write SetSel(char_index, char_index+1)?

    1 person found this answer helpful.