My FAQ,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Visual C++ > WINDOWS窗口视图
一个在RichEdit中添加表情图象的类
作者:未知 时间:2005-07-20 14:14 出处:VC知识库 责编:MyFAQ
              摘要:一个在RichEdit中添加表情图象的类

一个在RichEdit中添加表情图象的类

作者:中原工学院 刘翔

下载源代码

说明
  本文根据VC知识库《在线杂志》的第30期的一篇文章:《》,介绍了一个可以在RichEdit中添加表情图象的类CFaceEdit。 以下是使用这个类的程序截图:


图一 CFaceEdit类的使用

使用方法
  我们可以先看一下它的使用方法:

//将对话框类成员变量由CRichEditCtrl改为CFaceEdit
CFaceEdit m_FaceEdit;

//自定义一组表情
CString pSymbol[] = {":)", ":(", ";)", ":0", ";-)"};

//表情对应的图象ID
UINT nIDBmp[] =  {    IDB_BITMAP1, IDB_BITMAP2, IDB_BITMAP3, IDB_BITMAP4, IDB_BITMAP5};
m_FaceEdit.Init(5, pSymbol, nIDBmp);
......
m_FaceEdit.SetText("Visual Studio 包括许多示例:),用以说明开发人员为.NET 平台;)创建的应用程序:-) 。");
也可以以位图文件的形式导入位图:
CString sBmpFile[] = {"res\\kid.bmp", "res\\sad.bmp", "res\\showoff.bmp", "res\\quip.bmp", "res\\maze.bmp"};
m_FaceEdit.Init(5, pSymbol, sBmpFile);
...
m_FaceEdit.SetText("Visual Studio 包括许多示例:),用以说明开发人员为.NET 平台;)创建的应用程序:-) 。");
  插入图象的主要原理,是由《类似 MSN 信息发送框的制作》一文中提供的InsertBitmap()函数实现的。该函数可以通过指定图象的ID插入图象,或通过图象文件的路径来插入图象。

  那么如何将文本中的字符表情,如::)、;-) 等翻译成图象呢?例如,对于字符串:
"Visual Studio 包括许多示例:),用以说明开发人员为.NET 平台;)创建的应用程序:-)。"

翻译之后,变成:
"Visual Studio 包括许多示例,用以说明开发人员为.NET 平台创建的应用程序。"

如何实现呢?
  在使用InsertBitmap()函数插入图象时,我发现只要先将RichEdit中的某一段文本内容选中,然后再调用InsertBitmap()函数,便可实现将选定内容替换成图象。如:
"Visual Studio 包括许多示例:),用以说明开发人员为.NET 平台;)创建的应用程序:-)。"

再调用InsertBitmap()函数:
"Visual Studio 包括许多示例,用以说明开发人员为.NET 平台;)创建的应用程序:-)。"

  后面的符号只要使用相同的方法处理即可。明白了这一点,想要实现转换图象的功能也就不难了。我们可以使用CRichEditCtrl::SetSel()来实现,不过在此之前,要对各表情字符的一些信息,如位置、表情类型、长度等进行保存,以下是翻译文本的函数的代码:
/*-----------------------------------------------------------------------------
*     函数名     :SetTextWithFace
*
*     功能 :实现插入图象的算法函数。
*     实现原理:
                假设:CString pSymbol[] = {":)", ":(", "#", "AK47", ":-)"};
                先将包括表情符号的文本( 如:"haha:)" )直接显示到CRichEditCtrl中,
                然后选定其中的表情符号( 如:":)" ),再调用InsertBitmap函数
                实现插入,详见注释
-----------------------------------------------------------------------------*/
void CFaceEdit::SetTextWithFace(CString str)
{
       CString *pstr = new CString[m_nfaceCount];
       for(int n = 0; n<m_nfaceCount; n++)
       {
              pstr[n] = m_pSymbol[n];
       }

       SetWindowText(str);

       int nFaceCount = 0;           //str中共有多少个表情。
       stFace faceNode;        //faceNode中存储的是在哪个位置插入,插入哪一个表情。
       vector <stFace> vecFace;  //vecFace[0]表示第一个表情的位置和型号、vecFace[1]表示第二的位置和型号…

       /* ************************************************************************
       *           第一步:
       *           在str中查找表情字符(pstr)。
       *
       *           如str = "我们的:-)明天更美好AK47,一定:-)非常美好#。"。那么以下操作将生成四个
       *           stFace(定义见FaceEdit.h)结点,它们的值分别为{3, 3, 3}, {15, 3, 4}, {10, 1, 3}, {21, 0, 1}。
       *           使用vector数组vecFace进行存储。
       *
       * *************************************************************************/
       for(int i=0, m = -1; i<m_nfaceCount; i++)
       {
              //关键的一步:查找宽字符,汉字算一个字符。放在循环中,就可以查找重复的字符。
              while(1)
              {
                     m = (int)str.Find(pstr[i], m + 1);       //循环搜索
                     if(m != -1)
                     {
                            faceNode.nPos = m;
                            faceNode.nFaceIndex = i;
                            faceNode.nLength = (int)pstr[i].GetLength();

                            vecFace.push_back(faceNode);
                            nFaceCount++;
                     }
                     else
                     {
                            break;
                     }
              }
       }     //查找完毕
       if(nFaceCount==0)             //在str中没找到一个表情,下面就无需插入表情了。
              return;

       delete []pstr;
       /* ************************************************************************
       * 第二步:
       * 使用泛型算法sort进行排序。
       *
       * 上面的四个结点:A:{3, 3, 3}, B:{15, 3, 4}, C:{10, 1, 3}, D:{21, 0, 1},显然这不是按照
       * 顺序排的,这里应该按表情在文本中出现的次序依次替换,否则替换算法将会非常麻烦。
       *
       * *************************************************************************/
       bool less_than(stFace &face1, stFace &face2);     //声明排序的"条件"函数
       //详见我的ObjectSort工程中的说明。可参见《Essential C++》P84
       sort(vecFace.begin(), vecFace.end(), less_than); 


       /* ***********************************************************************
       * 第三步:
       * 调整各表情字符位置(nPos)。
       *
       * 排序之后各结点:A:{3, 3, 3}, C:{10, 1, 3}, B:{15, 3, 4}, D:{21, 0, 1}。
       * 经过摸索,发现这样一个规律:
       * 本结点应该向前挪的值(prev) = 上一个表情的长度(prevLength) - 1 + 上一个结点应该向前挪的值(prev)
       *
       * 如:
                     CString pSymbol[] = {":)", ":(", "#", "AK47", ":-)"};
                     序号:?                    0     1?    2?  ?3?   ?4

                     "我们的:-)明天更美好AK47,一定:-)非常美好#。"
                     位置: 3            11        18         25

                     "#"(25, 2, 1)    "AK47"(11, 3, 4)  ":-)"(3, 4, 3)   ":-)"(18, 4, 3) 
                         ~~                      ~~                ~~                  ~~
                     排序后:
                     ":-)"(3, 4, 3)   "AK47"(11,3, 4)   ":-)"(18, 4, 3)    "#"(25, 2, 1)
                           ~~                     ~~                ~~                  ~~
                     处理后:
                     ":-)"(3, 4, 3)   "AK47"(9, 3, 4)   ":-)"(13, 4, 3)    "#"(18, 2, 1)
                           ~~                     ~~                ~~                  ~~
                          少了0                  少了2            少了5          少了7
                                                 3-1+0            4-1+2          3-1+5
       *
       *
       * *********************************************************************/
       for(int t = 0, prevLength = 0, prev = 0; t<nFaceCount; t++)
       {
              vecFace[t].nPos -= prev;
              prevLength = vecFace[t].nLength;
              prev = prevLength - 1 + prev;
       }

       /* ********************************************************************
       * 第四步:
       * 下面插入表情。
       *
       * 调用InsertBitmap插入各处理完成的各结点A:{3, 3], C:{9, 1}, B:{13, 3}, D:{18, 0}。
       *
       * *********************************************************************/
       try
       {
              for(int j=0; j<nFaceCount; j++)
              {
                     stFace faceNode = vecFace[j];
                     InsertBitmap(faceNode);
              }
       }

       catch(char *sError)
       {
              MessageBox(sError, "HBITMAP", MB_OK | MB_ICONERROR);
       }
}		
注意事项
  本类有两个版本,一个是针对RichEdit 1.0的,另一个是针对RichEdit 2.0的。它们的区别是,前者把一个汉字作为两个字节处理,而后者把一个汉字作为一个字节处理。请读者区分使用。

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 myfaq.com.cn All rights reserved. www.myfaq.com.cn 版权所有