实现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、编写程序来调用控件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
    欢迎转载,不过希望转载时注明出处。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值