现在的位置: 首页 > 综合 > 正文

实现QQ表情功能(2)

2013年10月05日 ⁄ 综合 ⁄ 共 5292字 ⁄ 字号 评论关闭

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

    欢迎转载,不过希望转载时注明出处。

抱歉!评论已关闭.