c++ - Can my RichEdit Control contain clickable links? -
i want display series of strings edit control or rich edit 2.0 control. after that, want of text displayed underlined , in blue. these underlined texts can clicked open dialog or sort.
is there way this?
rich edit 2.0 supports automatic richedit hyperlinks while rich edit 4.1 , newer (msftedit.dll) supports friendly name hyperlinks.
you can emulate friendly name hyperlinks in rich edit 2.0 using combination of cfe_link
, cfe_hidden
character formatting flags. mark text cfe_link
, hide url applying cfe_hidden
. handle en_link
notification react on clicks. @ point have parsing extract hidden url rich text.
alternatively use cfe_link
text , use std::map
map text urls. work long there 1:1 mapping of text url.
edit: noted want "to open dialog" when link clicked, applying cfe_link
should enough in case.
edit 2: if don't need display formatted text , don't need scrolling, suggest use syslink control. links displayed syslink control have better accessibility links in richedit control. former supports tab key navigate through individual links whereas latter not.
implementing friendly name hyperlinks (rich edit 4.1+)
disclaimer: following code has been tested under win 10 creators update. haven't found time yet test under older os versions.
- in
initinstance()
method ofcwinapp
-derived class, callafxinitrichedit5()
if version of visual studio supports it. otherwise callloadlibraryw(l"msftedit.dll")
. - make sure richedit control uses right window class. resource editor creates richedit 2.0 default. need manually edit .rc file using text editor , replace
richedit20a
orrichedit20w
richedit50w
.w
stands unicode version of control. call
cricheditctrl::streamin()
insert rtf containing hyperlink(s). in following provide helper functionstreaminrtf()
simplifies task of streaming string control:struct streaminrtfcallbackdata { char const* prtf; size_t size; }; dword callback streaminrtfcallback( dword_ptr dwcookie, lpbyte pbbuff, long cb, long *pcb ) { streaminrtfcallbackdata* pdata = reinterpret_cast<streaminrtfcallbackdata*>( dwcookie ); // copy number of bytes requested control or number of remaining characters // of source buffer, whichever smaller. size_t sizetocopy = std::min<size_t>( cb, pdata->size ); memcpy( pbbuff, pdata->prtf, sizetocopy ); *pcb = sizetocopy; pdata->prtf += sizetocopy; pdata->size -= sizetocopy; return 0; } dword streaminrtf( cricheditctrl& richedit, char const* prtf, size_t size = -1, bool selection = false ) { streaminrtfcallbackdata data; data.prtf = prtf; data.size = ( size == -1 ? strlen( prtf ) : size ); editstream es; es.dwcookie = reinterpret_cast<dword_ptr>( &data ); es.dwerror = 0; es.pfncallback = streaminrtfcallback; int flags = sf_rtf | ( selection ? sff_selection : 0 ); richedit.streamin( flags, es ); return es.dwerror; }
example usage (using raw string literal here make rtf more readable):
streaminrtf( m_richedit, r"({\rtf1 {\field{\*\fldinst {hyperlink "https://www.stackoverflow.com" }}{\fldrslt {stackoverflow}}}\par other text\par })" );
to handle clicks need enable
en_link
notifications richedit control, e. g.:m_richedit.seteventmask( m_richedit.geteventmask() | enm_link );
add handler
en_link
message map:begin_message_map(cmydialog, cdialog) on_notify( en_link, idc_richedit1, onlink ) end_message_map()
define event handler method handle mouse clicks , return key:
void cmydialog::onlink( nmhdr* pnm, lresult* presult ) { enlink* pnml = reinterpret_cast<enlink*>( pnm ); if( pnml->msg == wm_lbuttondown || ( pnml->msg == wm_keydown && pnml->wparam == vk_return ) ) { cstring url; m_richedit.gettextrange( pnml->chrg.cpmin, pnml->chrg.cpmax, url ); afxmessagebox( l"url: \"" + url + l"\"" ); *presult = 1; // message handled } *presult = 0; // enable default processing }
beginning windows 8, control can show tooltip displays url of link under mouse cursor. feature can enabled sending
em_seteditstyle
message control:dword style = ses_hyperlinktooltips | ses_nofocuslinknotify; m_richedit.sendmessage( em_seteditstyle, style, style );
in case missing defines, here are:
#ifndef ses_hyperlinktooltips #define ses_hyperlinktooltips 8 #endif #ifndef ses_nofocuslinknotify #define ses_nofocuslinknotify 32 #endif
Comments
Post a Comment