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、编写程序来调用控件GifOle.dll


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)相关推荐

  1. 实现QQ表情功能(1)

    作者:小鹏 0.前言 相信大家对QQ的表情不陌生.像这样: QQ的文本框控件支持各种图片格式的显示和插入.看到QQ这个有趣功能,我也想实现下.不过,实现起来却不是太容易,在我写代码的过程中,我也在网上 ...

  2. 向EditView插入qq表情,并可删除表情或文字

    2019独角兽企业重金招聘Python工程师标准>>> 参考了一下别人实现的插入qq表情功能,在此基础上加了删除功能 代码如下: package com.push.notif;imp ...

  3. 测试用例集-11.QQ表情收藏功能测试用例

    ------·今天距2020年55天·------ 这是ITester软件测试小栈第74次推文 大家好 我是coco小锦鲤 我又双叒叕 yòu shuāng ruò zhuó 出现了 有时候聊天到不到 ...

  4. 微信公众帐号开发教程第9篇-QQ表情的发送与接收

    我想大家对QQ表情一定不会陌生,一个个小头像极大丰富了聊天的乐趣,使得聊天不再是简单的文字叙述,还能够配上喜.怒.哀.乐等表达人物心情的小图片.本文重点要介绍的内容就是如何在微信公众平台使用QQ表情, ...

  5. [033] 微信公众帐号开发教程第9篇-QQ表情的发送与接收

    我想大家对QQ表情一定不会陌生,一个个小头像极大丰富了聊天的乐趣,使得聊天不再是简单的文字叙述,还能够配上喜.怒.哀.乐等表达人物心情的小图片.本文重点要介绍的内容就是如何在微信公众平台使用QQ表情, ...

  6. 思量QQ本地会员v3.8官方2013版【免费使用部分QQ会员功能】

    思量QQ本地会员(2013版) v3.8官方版 授权方式:免费软件 界面语言:简体中文 软件大小:1024KB 所属专题:网络软件 运行环境:Win2K,WinXP,Win2003,Vista,Win ...

  7. Android 支持表情功能

    概述 1.原理和实现思路 2.表情图片显示 3.表情面板 4.表情的输入框插入和删除 5.表情添加脚本 Android中表情功能,一般都不是用ImageView去设置图片实现的, 表情一般会嵌套在文本 ...

  8. Android 表情功能的完整处理方案

    概述 1.原理和实现思路 2.表情图片显示 3.表情面板 4.表情的输入框插入和删除 5.表情添加脚本 Android中表情功能,一般都不是用ImageView去设置图片实现的, 表情一般会嵌套在文本 ...

  9. WordPress文章中插入qq表情

    看见一些博客中使用了QQ表情,这个效果还是很不错的,可以让文章看起来更爽,那么这个是怎么实现的呢? 下面我就来说说方法. 工具:QQ表情包,下载地址:http://yunpan.cn/cLw6UhwB ...

最新文章

  1. 使用Laya引擎开发微信小游戏(下)
  2. MagicalRecord使用中的注意事项
  3. LiveBins缔造者
  4. 对计算机的理解大一1000,大一计算机实训报告总结范文-求计算机实习报告1000字左右,急急急?...
  5. 发布5个月全系下跌500 麒麟980+40W快充 多亏了华为P30!
  6. mysql管理节点_MySql节点管理安装步骤需要在SerA和SerB上各做一次
  7. Word编写论文十大技巧
  8. 软件_避免用chrome进行网站配置调试[博]
  9. 线程打印_Java编程核心技术之——线程操作
  10. 【字符串全排列】LeetCode 567. Permutation in String
  11. vue将每个路由打包成html,Ant Design Vue pro 动态路由的实现和打包
  12. python求第三边长_如何用python求第三条边边长
  13. php开发电脑i56200u,八代酷睿处理器好不好?i5-6200U处理器/i5-8250U处理器对比评测...
  14. pdf密码强制解除软件下载 | 专业PDF解密软件 | PDF Decrypter Pro
  15. 摄影测量(一):概述
  16. 如何拥有一个游戏策划的思维
  17. Markdown由浅入深
  18. 蓝蓝算法10-数字颠倒
  19. PCA9555 Studying
  20. 注入——sql注入命令

热门文章

  1. python 保障系统(一)
  2. 51nod 1421 最大MOD值(高妙的调和级数复杂度)
  3. linux dprintk 日志,linux命令备忘
  4. 用Daemon虚拟光驱安装Oracle9i的注意事项
  5. 0-1背包问题小总结(hdu 2062)
  6. 互联网校招其他专题书籍复习方法详解
  7. 跟着瑜伽老师一节课程序员锻炼身体
  8. android开花动画,放下手机,听花开的声音 -- 花儿 の Time #Android #iPhone
  9. mpirun 遇到 forrtl: severe (174): SIGSEGV, segmentation fault occurred
  10. box-shadow使用