WEB开发网
开发学院软件开发VC 在RichEdit中添加表情图象的类 阅读

在RichEdit中添加表情图象的类

 2010-06-15 20:40:15 来源:WEB开发网   
核心提示:如何实现呢?在使用InsertBitmap()函数插入图象时,我发现只要先将RichEdit中的某一段文本内容选中,在RichEdit中添加表情图象的类(2),然后再调用InsertBitmap()函数,便可实现将选定内容替换成图象,前者把一个汉字作为两个字节处理,而后者把一个汉字作为一个字节处理,如:"Vi

如何实现呢?

在使用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的。它们的区别是,前者把一个汉字作为两个字节处理,而后者把一个汉字作为一个字节处理。请读者区分使用。

本文配套源码

上一页  1 2 

Tags:RichEdit 添加 表情

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接