CRichEditCtrl实现MSN背景,字体,超链接

King丶1st

King丶1st

2016-02-19 20:51

今天图老师小编给大家精心推荐个CRichEditCtrl实现MSN背景,字体,超链接教程,一起来看看过程究竟如何进行吧!喜欢还请点个赞哦~
相关链接:CRichEditCtrl实现MSN/QQ动画表情
  
  首先对标题说明一下,在MSN中,聊天的窗口可能是一个自定义的类。大家用Spy ++可以看看。  对与自定义窗口,可以使用CreateWindow, SetWindowLong或者是SubclassWindow实现,不过这不是我现在讨论的话题。
  
  好, 先看看效果再说(如图1):
  
  图1:实现效果图一、MSN超链接的实现
  关于HyperLink的是实现,我找到了一种自绘的实现方式,自己维护,效果也很不错(如图2)。
  
  图2:超链接  就在我觉得实现OLE的插入有难度时,就想过了直接自己绘制,自己维护,但是觉得做法不是很正统,对不起Microsoft给我留的IRichEditOle接口,就没有使用这种解决方法。我们大致讲一下实现方式:
  
  定义一个strUCt描述每个hyperlink对象:
  1typedef struct _HYPERLINKINFO
  2{
  3 CRect rectDimension;
  4 CString csLinkText;
  5 UINT unLinkDlgID;
  6 inline operator = (struct _HYPERLINKINFO linkInfo){ rectDimension = linkInfo.rectDimension;csLinkText = linkInfo.csLinkText;unLinkDlgID = linkInfo.unLinkDlgID;}
  7}HYPERLINKINFO,*LPHYPERLINKINFO;
  这里有一个UINT unLinkDlgID,是来描述点击这个link后弹出的dialog的。
  
  CRect rectDimension;用来保存这个link的rect,以检查鼠标是否在其中,以显示鼠标光标;对于多links,他使用了一个CList来维护(或者可以选择使用std::list):
  1CList m_lsLinks;
  其中很要害的就是判定鼠标是不是在一个link的rect内。这种实现的确很不错,但是我要说的是另一个更现代的实现方式,实现起来也简单得多,要害的就是有个Style =。ENM_LINK 这个style在RichEdit20中才有,所以我们应该使用RichEdit20A!我们维护这样一个类:
  1class _AFX_RICHEDITEX_STATE
  2{
  3public:
  4 _AFX_RICHEDITEX_STATE();
  5 virtual ~_AFX_RICHEDITEX_STATE();
  6 HINSTANCE m_hInstRichEdit20 ;
  7};
更多内容请看MSN专题专题,或
  实现代码就一点,就是用这个类来Load Richedit20
  1_AFX_RICHEDITEX_STATE::_AFX_RICHEDITEX_STATE()
  2{
  3 m_hInstRichEdit20 = NULL ;
  4}
  5
  6
  7
  8_AFX_RICHEDITEX_STATE::~_AFX_RICHEDITEX_STATE()
  9{
   !-- frame contents -- !-- /frame contents -- 10 if( m_hInstRichEdit20 != NULL )
  11 {
  12 ::FreeLibrary( m_hInstRichEdit20 ) ;
  13 }
  14}
  15
  16
  17
  18_AFX_RICHEDITEX_STATE _afxRichEditStateEx ;
  19
  20
  21
  
   22BOOL PASCAL AfxInitRichEditEx()
  23{
  24 if( ! ::AfxInitRichEdit() )
  25 {
  26 return FALSE ;
  27 }
  28 _AFX_RICHEDITEX_STATE* l_pState = &_afxRichEditStateEx ;
  29 if( l_pState-m_hInstRichEdit20 == NULL )
  30 {
  31 l_pState-m_hInstRichEdit20 = LoadLibraryA("RICHED20.DLL") ;
  32 }
  33 return l_pState-m_hInstRichEdit20 != NULL ;
  34}
  然后在我们创建RichEdit的时候,就使用 RichEdit20A 作为ClassName;
  1CreateEx(dwExStyle, _T( "RichEdit20A" ), NULL, dwStyle, rect, pParentWnd, nID, NULL );
  这样一来,你就使用先进的RichEdit20A了, 可以简单的实现你的要的功能了。先给你的RichEditCtrl设置EN_LINK Style, 代码量也是少得可怜:
  1unsigned mask = ::SendMessage(m_hWnd, EM_GETEVENTMASK, 0, 0);
  2::SendMessage(m_hWnd, EM_SETEVENTMASK, 0, mask ENM_LINK ENM_MOUSEEVENTS ENM_SCROLLEVENTS ENM_KEYEVENTS);
  3::SendMessage(m_hWnd, EM_AUTOURLDETECT, true, 0);
  假如你觉得使用CRichEditCtrl的Member Function更方便的话,当然可以使用GetEventMak和SetEventMask,同样方便。为了扩展的需要,RichEdit20并没有定义为,当你点击links的时候用浏览器打开这个页面,而是让你处理这个点击,你就可以任意的扩展!
  ON_NOTIFY(EN_LINK, IDC_SENDMSG, OnRichEditExLink )
  知道在哪加吧。这个IDC_SENGMSG就是RichEdit的Resource ID, OnRichEditExLink就是处理这个消息的函数咯,然后看最后的代码。
  1void CMsgerDlg::OnRichEditExLink( NMHDR* in_pNotifyHeader, LRESULT* out_pResult )
  2{
  3 ENLINK* l_pENLink = ( ENLINK* )in_pNotifyHeader ;
  4 *out_pResult = 0 ;
  5 switch( l_pENLink-msg )
  6 {
  7 default:{}
  8 break ;
  9
  10 case WM_LBUTTONDOWN:
  11 {
  12 CString l_URL ;
  13 CHARRANGE l_CharRange ;
  14 CExtRichEdit *m_TempEdit;
  15 m_TempEdit = (CExtRichEdit*)CExtRichEdit::FromHandle(l_pENLink-nmhdr.hwndFrom);
  16 m_TempEdit-GetSel( l_CharRange ) ;
  17 m_TempEdit-SetSel( l_pENLink-chrg ) ;
  18 l_URL = m_TempEdit-GetSelText() ;
  19 m_TempEdit-SetSel( l_CharRange ) ;
  20 CWaitCursor l_WaitCursor ;
  21 ShellExecute( this-GetSafeHwnd(), _T( "open" ), l_URL, NULL, NULL, SW_SHOWNORMAL ) ;
  22 *out_pResult = 1 ;
  23 }
  24 break ;
  25
  26 case WM_LBUTTONUP:
  27 {
  28 *out_pResult = 1 ;
  29 }
  30 break ;
  31 }
  超链接就说到这里,下面是背景跟字体。
  
更多内容请看MSN专题专题,或
  
  二、MSN背景的实现
  
  关于背景的实现,有人认为不能直接处理WM_ERASEBKGND,还有需要Hook才行,或者是重写WM_PAINT处理函数。
  
   !-- frame contents -- !-- /frame contents --   但其实很简单的,要害的一点就是RICHEDIT20A的WS_EX_TRANSPARENT这个Style。有了它,我们就可以Create一个透明的CRichEditCtrl了,然后就直接在Dialog上绘图片!这样看起来就是RichEdit的背景了。首先:
  
   1m_Chat.CreateEx(WS_EX_TRANSPARENT, "RICHEDIT20A", "", WS_VISIBLE WS_CHILD
  2 WS_CLIPCHILDREN WS_VSCROLL ES_MULTILINE ES_READONLY
  3 ES_AUTOVSCROLL ES_LEFT ES_WANTRETURN, rt, this, IDC_CHAT, NULL);
  这样就得到了一个透明的RichEdit了。
  
  然后就可以使用两种方法绘制窗体背景。
  (1)响应WM_ERASEBKGND
  
  (2)
  OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
  还有就是透明的代价,RichEdit不会刷新背景了,得自己做。算最小刷新Rect就是讨论的主要问题了。这里就不作具体讨论了。
  
  
  三、MSN字体的实现
  
  字体的实现是很简单的,这里没有使用rtf,觉得太烦琐了,而且也不需要那么复杂的控制,仅仅是一个结构CHARFORMAT:
  1typedef struct _charformat
  2{
  3 UINT cbSize;
  4 _WPAD _wPad1;
  5 DWord dwMask;
  6 DWORD dwEffects;
  7 LONG yHeight;
  8 LONG yOffset;
  9 COLORREF crTextColor;
  10 BYTE bCharSet;
  11 BYTE bPitchAndFamily;
  12 char szFaceName[LF_FACESIZE];
  13 _WPAD _wPad2;
  14} CHARFORMATA;
  相当的明白了,就不用多说;对于CRichEditCtrl,它提供的关于格式的接口有:
  SetDefaultCharFormat(CHARFORMAT &cf);
  SetSel(CHARFORMAT &cf);
  大家一看便知,不多说,那么如何使用CFontDialog选择字体呢?其实很简单咯,因为有这个东西 = CFontDialog::GetCharFormat(CHARFORMAT &cf);所以,总的实现可能就是这么简单的几句代码:
  1CFontDialog fontdlg;
  2
  3 int ret = fontdlg.DoModal();
  4 if(IDOK == ret)
  5 {
  6 CHARFORMAT cf;
  7 fontdlg.GetCharFormat(cf);
  8 m_SendMsg.SetDefaultCharFormat(cf);
  9 }
更多内容请看MSN专题专题,或
展开更多 50%)
分享

猜你喜欢

CRichEditCtrl实现MSN背景,字体,超链接

编程语言 网络编程
CRichEditCtrl实现MSN背景,字体,超链接

在RichEdit中实现超链接

编程语言 网络编程
在RichEdit中实现超链接

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Word怎样做超链接和取消超链接

电脑入门
Word怎样做超链接和取消超链接

实现彩色闪烁超链接效果的JS代码

电脑网络
实现彩色闪烁超链接效果的JS代码

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

图形超链接类

C语言教程 C语言函数
图形超链接类

用超链接实现幻灯片循环播放

电脑入门
用超链接实现幻灯片循环播放

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

C/C++编程新手错误语录

C/C++编程新手错误语录

实例解析C++/CLI中的继承与枚举

实例解析C++/CLI中的继承与枚举
下拉加载更多内容 ↓