分享
 
 
 

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

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

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

作者:中原工学院 刘翔

下载源代码

说明

本文根据VC知识库《在线杂志》的第30期的一篇文章:《类似 MSN 信息发送框的制作》,介绍了一个可以在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的。它们的区别是,前者把一个汉字作为两个字节处理,而后者把一个汉字作为一个字节处理。请读者区分使用。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有