实现QQ表情功能(2)
7、添加必要的成员和方法
7.1 添加成员变量
下面往CGifCtl加入些成员变量:
CComBSTR
m_strFileName;
GdiplusStartupInput
gdiplusStartupInput;
ULONG_PTR
gdiplusToken;
ImageEx*
m_pImg; //图像
效果如图:
7.2构造函数
再在CCifCtl的构造函数中加入以下代码:
GdiplusStartup(&gdiplusToken,
&gdiplusStartupInput, NULL);
m_bWndLess=true;
m_pImg=NULL;
效果如图:
7.3
FinalRelease函数
再往CGifCtl类加入一个FinalRelease函数。
void
FinalRelease()
{
GdiplusShutdown(gdiplusToken);
TimerOff();
}
效果如图:
以上添加的两个函数是用于Gdi+库的初始化。
接头就看看怎么把Gif图片显示出来。
7.4添加LoadFromFile方法
往IGifCtl接口中加入一个方法。
操作如下,选择IGifCtl,右键,选择Add Method,如图:
在Method Name中输入:LoadFromFile
在Parameters中输入:[in] BSTR FileName
点击OK.
实现LoadFromFile方法:
跳到那个方法下:
加入以下代码:
m_strFileName=FileName;
m_pImg
= new ImageEx(m_strFileName);
if
(m_pImg->IsAnimatedGif())
{
long
lFrameTime = m_pImg->GetFrameTime();
TimerOn(lFrameTime);
}
SIZEL
size5,size6;
size5.cx=m_pImg->GetWidth();
size5.cy=m_pImg->GetHeight();
m_rcPos.right=m_pImg->GetWidth()+m_rcPos.left;
m_rcPos.bottom=m_pImg->GetHeight()+m_rcPos.top;
AtlPixelToHiMetric(&size5,&size6);
SetExtent(DVASPECT_CONTENT,&size6);
if(m_spInPlaceSite!=NULL)
m_spInPlaceSite->OnPosRectChange(&m_rcPos);
FireViewChange();
效果如图:
7.5添加_OnTimer方法
再添加一个方法:_OnTimer
在_OnTimer函数中输入以下代码:
if (m_pImg != NULL)
{
m_pImg->ActiveNextFrame(); //显示下一帧
long lFrameTime =
m_pImg->GetFrameTime(); //获得下一帧的显示时间
TimerOn(lFrameTime); //修改计时器的周期为下一帧的显示时间
FireViewChange(); //刷新图片区域
}
效果如图:
7.6 修改OnDraw函数
把OnDraw函数的代码改成:
HRESULT
OnDraw(ATL_DRAWINFO& di)
{
RECT&
rc = *(RECT*)di.prcBounds;
//将剪辑区域设置为di.prcBounds指定的矩形
if
(m_pImg != NULL)
{
Graphics
graphics(di.hdcDraw);
Status
sta = graphics.DrawImage(m_pImg, rc.left,rc.top);
}
return
S_OK;
}
效果如图:
至此,这个控件的代码就写完了,编译,链接,生成控件。
8、测试
下面来测试下刚才写的那个控件。8.1 注册
先把刚写好的控件用regsvr32命令注册一下。
8.2插入控件
测试用到的是vc自带的工具ActiveX Control Test Container。
启动ActiveX Control Test Container软件。
点击工具栏上的New Control按钮
弹出以下对话框
再选择GifCtl,点击OK8.3调用方法
添加成功后,再点击Invoke Methods按钮。
弹出以下对话框,在Parameter中输入一个gif文件的路径,以下是我的gif图片的路径。G:/richedit/2.gif。输入后,点击Invoke。
可以看到控件显示gif图片了。
测试通过。
9.1 创建一个MFC工程
新建一个MFC
AppWizard工程,在Project
name输入Richedit.
点击OK后,
选择Dialog based选项,点击Finish。
9.2 添加Richedit控件
先把默认的静态控件删掉,
再把工具箱上拖到对话框的面板上。
再调下控件大小,再把按钮的标题修改下,效果如图:
9.3派生CRichedit控件
选择项目,右键,选择New Class.
在弹出的对话框中,Basc
Class中选择CRichEditCtrl,Names中输入CRichEditCtrlEx
添加一个方法,右键,选择Add Member Function.
输入:InsertFace(CString
strPicPath)。
9.4把GifOle.dll加入工程
把GifOle.dll复制到Richedit工程目录下。
在stdafx.h文件中加入以下代码:
#import "GifOle.dll" named_guids
using namespace GIFOLELib;
效果如图:
9.5实现InsertFace函数
1.添加头文件:
#include <Richole.h>
效果如图:
2.在CRicheditEx的构造函数加入以下代码,注册GifOle.dll.
WinExec("regsvr32 /s GifOle.dll",SW_HIDE);
效果如图:
3.往之前的void CRichEditCtrlEx::InsertFace(CString strPicPath)方法加入以下代码:
IStorage* lpStorage = NULL;//存储接口
IOleObject* lpOleObject = NULL;//OLE对象
LPLOCKBYTES lpLockBytes = NULL;//LOCKBYTE
IOleClientSite*
lpOleClientSite = NULL;
IGifCtl* pShowGif = NULL; //控件
CLSID clsid;
REOBJECT reobject;
HRESULT hr;
hr
=
::CoCreateInstance(CLSID_GifCtl,NULL,CLSCTX_INPROC,IID_IGifCtl,(LPVOID*)&pShowGif);
pShowGif->LoadFromFile(strPicPath.AllocSysString());
hr
= pShowGif->QueryInterface(&lpOleObject);//获得数据对象接口
hr
= lpOleObject->GetUserClassID(&clsid);
hr
= ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);//创建LOCKBYTE对象
hr
= ::StgCreateDocfileOnILockBytes(lpLockBytes,//创建复合文档
STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE,
0, &lpStorage);
GetIRichEditOle()->GetClientSite(&lpOleClientSite);
ZeroMemory(&reobject,
sizeof(REOBJECT));//初始化一个对象
reobject.cbStruct
= sizeof(REOBJECT);
reobject.clsid = clsid;
reobject.cp = REO_CP_SELECTION;
reobject.dvaspect
= DVASPECT_CONTENT;
reobject.dwFlags
= REO_BELOWBASELINE;
reobject.poleobj
= lpOleObject;
reobject.polesite
= lpOleClientSite;
reobject.pstg = lpStorage;
hr
= GetIRichEditOle()->InsertObject( &reobject );
OleSetContainedObject(lpOleObject,TRUE);
//
release the interface
if(
pShowGif != NULL )
pShowGif->Release();
if(
lpOleObject != NULL )
lpOleObject->Release();
if(
lpOleClientSite != NULL )
lpOleClientSite->Release();
if(
lpStorage != NULL )
lpStorage->Release();
效果如图:
9.6 使用CRichEditEx类
启动Class Wizard,选择Member Variables选项
点击Add Variable,输入m_richedit
1.在RicheditDlg.文件的开头加入以下的语句:
#include "RichEditCtrlEx.h"
2.在RicheditDlg.h文件中找到下面一句
CRichEditCtrl m_richedit;
把上面那句改成
CRichEditCtrlEx m_richedit;
3.在BOOL CRicheditApp::InitInstance()函数加入以下一句代码:
AfxInitRichEdit();
效果如下图:
9.7调用InserFace函数
双击对话框上的插入图片按钮。添加OnOk函数。
把OnOK函数修改成
void CRicheditDlg::OnOK()
{
//
TODO: Add extra validation here
CFileDialog
dlg(TRUE,NULL,NULL,OFN_READONLY,
"image
file(*.bmp;*.jpeg;*.jpg;*.gif)|*.bmp;*.gif;*.jpeg;*.jpg|All Files
(*.*)|*.*||");
if(dlg.DoModal()==IDOK)
m_richedit.InsertFace(dlg.GetPathName());
}
9.8运行
点击插入图片按钮添加表情
在QQ的安装目录下有个Face2文件夹,插入里面的文件
10、总结
实现QQ表情这个功能的资料比较缺乏,我也在网上找了比较久,根据网上找到的一些相关资料,一点点尝试实现的。
以上所述只是实现QQ的表情功能的第一步,更深入的内容我也在尝试中,欢迎有兴趣的网友跟我一起探讨。
项目工程代码我放在QQ群:44177419,70934898,37950043的群共享上面。需要代码的可以去那下载,也可以直接发邮件来索取。代码有错误的地方,欢迎发邮件指正。
我的联系方式:
QQ:xpmo@qq.com
MSN:msn@msn.com
邮箱:xpmo@qq.com
欢迎转载,不过希望转载时注明出处。
实现QQ表情功能(2)相关推荐
- 实现QQ表情功能(1)
作者:小鹏 0.前言 相信大家对QQ的表情不陌生.像这样: QQ的文本框控件支持各种图片格式的显示和插入.看到QQ这个有趣功能,我也想实现下.不过,实现起来却不是太容易,在我写代码的过程中,我也在网上 ...
- 向EditView插入qq表情,并可删除表情或文字
2019独角兽企业重金招聘Python工程师标准>>> 参考了一下别人实现的插入qq表情功能,在此基础上加了删除功能 代码如下: package com.push.notif;imp ...
- 测试用例集-11.QQ表情收藏功能测试用例
------·今天距2020年55天·------ 这是ITester软件测试小栈第74次推文 大家好 我是coco小锦鲤 我又双叒叕 yòu shuāng ruò zhuó 出现了 有时候聊天到不到 ...
- 微信公众帐号开发教程第9篇-QQ表情的发送与接收
我想大家对QQ表情一定不会陌生,一个个小头像极大丰富了聊天的乐趣,使得聊天不再是简单的文字叙述,还能够配上喜.怒.哀.乐等表达人物心情的小图片.本文重点要介绍的内容就是如何在微信公众平台使用QQ表情, ...
- [033] 微信公众帐号开发教程第9篇-QQ表情的发送与接收
我想大家对QQ表情一定不会陌生,一个个小头像极大丰富了聊天的乐趣,使得聊天不再是简单的文字叙述,还能够配上喜.怒.哀.乐等表达人物心情的小图片.本文重点要介绍的内容就是如何在微信公众平台使用QQ表情, ...
- 思量QQ本地会员v3.8官方2013版【免费使用部分QQ会员功能】
思量QQ本地会员(2013版) v3.8官方版 授权方式:免费软件 界面语言:简体中文 软件大小:1024KB 所属专题:网络软件 运行环境:Win2K,WinXP,Win2003,Vista,Win ...
- Android 支持表情功能
概述 1.原理和实现思路 2.表情图片显示 3.表情面板 4.表情的输入框插入和删除 5.表情添加脚本 Android中表情功能,一般都不是用ImageView去设置图片实现的, 表情一般会嵌套在文本 ...
- Android 表情功能的完整处理方案
概述 1.原理和实现思路 2.表情图片显示 3.表情面板 4.表情的输入框插入和删除 5.表情添加脚本 Android中表情功能,一般都不是用ImageView去设置图片实现的, 表情一般会嵌套在文本 ...
- WordPress文章中插入qq表情
看见一些博客中使用了QQ表情,这个效果还是很不错的,可以让文章看起来更爽,那么这个是怎么实现的呢? 下面我就来说说方法. 工具:QQ表情包,下载地址:http://yunpan.cn/cLw6UhwB ...
最新文章
- 使用Laya引擎开发微信小游戏(下)
- MagicalRecord使用中的注意事项
- LiveBins缔造者
- 对计算机的理解大一1000,大一计算机实训报告总结范文-求计算机实习报告1000字左右,急急急?...
- 发布5个月全系下跌500 麒麟980+40W快充 多亏了华为P30!
- mysql管理节点_MySql节点管理安装步骤需要在SerA和SerB上各做一次
- Word编写论文十大技巧
- 软件_避免用chrome进行网站配置调试[博]
- 线程打印_Java编程核心技术之——线程操作
- 【字符串全排列】LeetCode 567. Permutation in String
- vue将每个路由打包成html,Ant Design Vue pro 动态路由的实现和打包
- python求第三边长_如何用python求第三条边边长
- php开发电脑i56200u,八代酷睿处理器好不好?i5-6200U处理器/i5-8250U处理器对比评测...
- pdf密码强制解除软件下载 | 专业PDF解密软件 | PDF Decrypter Pro
- 摄影测量(一):概述
- 如何拥有一个游戏策划的思维
- Markdown由浅入深
- 蓝蓝算法10-数字颠倒
- PCA9555 Studying
- 注入——sql注入命令
热门文章
- python 保障系统(一)
- 51nod 1421 最大MOD值(高妙的调和级数复杂度)
- linux dprintk 日志,linux命令备忘
- 用Daemon虚拟光驱安装Oracle9i的注意事项
- 0-1背包问题小总结(hdu 2062)
- 互联网校招其他专题书籍复习方法详解
- 跟着瑜伽老师一节课程序员锻炼身体
- android开花动画,放下手机,听花开的声音 -- 花儿 の Time #Android #iPhone
- mpirun 遇到 forrtl: severe (174): SIGSEGV, segmentation fault occurred
- box-shadow使用