CRichEditCtrlEx : Replacing "RICHEDIT" control with "RichEdit20A"


Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame

While writing a dev notes Visual Studio plug in, I wanted the rich edit control in a dialog to understand URL's so developers could add links to sites and email addresses.   After talking to "Long John", he led me to the easy way of doing it, and now I am posting the work for others.  Basically this requires CRichEditCtrlEx to use the new rich edit DLL RICHED20.DLL.  The first thing to do it change the window class name of the rich edit controls from "RICHEDIT" to "RichEdit20A" in the *.rc file.  Next, we create a class derived from CRichEditCtrl called CRichEditCtrlEx and override the Create() method:

class CRichEditCtrlEx : public CRichEditCtrl
    virtual ~CRichEditCtrlEx();
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL( CRichEditCtrlEx )
    virtual BOOL Create( DWORD in_dwStyle, const RECT& in_rcRect, 
                         CWnd* in_pParentWnd, UINT in_nID );
    // Generated message map functions
    //{{AFX_MSG( CRichEditCtrlEx )

Now implement the Create() method like this:

BOOL CRichEditCtrlEx::Create(DWORD in_dwStyle,  const RECT& in_rcRect,
                             CWnd* in_pParentWnd, UINT in_nID)
    if( ! ::AfxInitRichEditEx() )
        return FALSE ;
    CWnd* l_pWnd = this ;
    return l_pWnd->Create( _T( "RichEdit20A" ), NULL, in_dwStyle, 
                           in_rcRect, in_pParentWnd, in_nID );

This is almost exactly what is in CRichEditCtrl::Create(), except the different window class name, and the call to AfxInitRichEdit() has been changed to AfxInitRichEditEx() which first calls AfxInitRichEdit (we do not want to break the normal CRichEditCtrl).   In the RichEditCtrlEx.h file, you need to add the DLL holder class and function prototype:

    virtual ~_AFX_RICHEDITEX_STATE();

    HINSTANCE m_hInstRichEdit20 ;

BOOL PASCAL AfxInitRichEditEx();

Now, in the source code, add the implementation:

    m_hInstRichEdit20 = NULL ;

    if( m_hInstRichEdit20 != NULL )
        ::FreeLibrary( m_hInstRichEdit20 ) ;


BOOL PASCAL AfxInitRichEditEx()
    if( ! ::AfxInitRichEdit() )
        return FALSE ;
    _AFX_RICHEDITEX_STATE* l_pState = &_afxRichEditStateEx ;
    if( l_pState->m_hInstRichEdit20 == NULL )
        l_pState->m_hInstRichEdit20 = LoadLibraryA("RICHED20.DLL") ;
    return l_pState->m_hInstRichEdit20 != NULL ;

Last thing to help out it we add a method to set the auto URL detection in the Rich Edit to on/off:

inline BOOL CRichEditCtrlEx::AutoURLDetect( BOOL in_fEnable )
    ASSERT(::IsWindow( m_hWnd ) );
    return ( BOOL )::SendMessage( m_hWnd, EM_AUTOURLDETECT, in_fEnable, 0 );

See the attached sample for the full source code.

Now to use this in your code, you need to use CRichEditCtrlEx for the rich edits you want to include URL detection, and you must call AfxInitRichEditEx() in your CMyApp::InitInstance() if you have dialogs using the rich edit controls.

To then use the URL, you must set the event mask on the rich edit control to include ENM_LINK and then the control will send EN_LINK notifications.  The EN_LINK notification uses the ENLINK structure which includes a message ID.  This message will be:


If you want to override the default action, set the pResult to 1, otherwise set it to zero.  See the example code to see how to handle this notification.

Download demo project - 16KB (this sample was compiled and tested using VC 6.0 sp1 on NT 4.0 sp4)

This article was originally published on January 18th, 1999

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date