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

2016-02-19 20:51 50 1 收藏

今天图老师小编给大家精心推荐个CRichEditCtrl实现MSN背景,字体,超链接教程,一起来看看过程究竟如何进行吧!喜欢还请点个赞哦~

【 tulaoshi.com - 编程语言 】

相关链接: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专题专题,或

来源:https://www.tulaoshi.com/n/20160219/1624697.html

延伸阅读
标签: Web开发
在经过前面几个部分的操作之后,我们的网页已经图文并茂,具有相当的效果了,但是这对于网页来说还不够,为了网站中的众多网页能够成为一个有机的整体,必须将各个网页通过超链接方式联系起来,这样才能够让浏览者在不同的页面之间跳转。 一、链接图片和文字 为一些文字或者图片建立链接非常方便,只要用鼠标选中需要变成链接...
要向数据库中添加超级链接,要经过两个步骤,一是在表中定义字段类型为“超级链接”,一是向此字段中添加数据。 要在表中定义字段类型为“超级链接”,可以按下面的步骤操作: (1)打开数据库,选择要在“数据库”窗口中包含超级链接字段的表,单击“设计”按钮,进入设置窗口; (2)将光标移到“字段名称”栏中的一个...
过去,在幻灯片演示结束后,习惯用一个“谢谢大家”的画面来结束播放。不过近年来这一做法却不再流行,大家更倾向于播放结束后马上回到封面页,以显示演讲题目和演讲人等信息。特别是一些固定场所的演示,更希望能够循环播放,而不是播放完成后退出播放状态,再从第一张进入重新播放。其实,要实现这样的效果并不难,只需要一个小小...
PPT设置超链接跳转   我们在Powerpoint演示文稿的放映过程中,希望从某张幻灯片中快速切换到另外一张不连续的幻灯片中,可以通过超级链接来实现。 下面我们以超级链接到第10张幻灯片为例,看看具体的设置过程: 1、在幻灯片中,用文本框、图形(片)制作一个超级链接按钮,并添加相关的提示文本(如陀螺旋)。 2、选中相应...
标签: word
Word怎样批量取消超链接   大家一定知道word文档中的超链接单个取消的方法,直接选中右键点击取消超链接就OK,非常简单。但是如果是要批量的取消你会吗?一个一个去取消必然浪费太多时间。 进么今天就跟图老师小编一起来学习一下Word怎样批量取消超链接?word快速取消超链接技巧。 快捷键删除word超链接 我们可以通...

经验教程

678

收藏

13
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部