`
阿尔萨斯
  • 浏览: 4177017 次
社区版块
存档分类
最新评论

RichEdit中插入GIF动画(使用QQ的ImageOle.dll)

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>

最近做聊天记录,需要显示GIF动画.看了很多文章,基本多是用QQ的ImageOle.dll或者Gif89a.dll来实现.当然还有其他方法,包括Static控件中使用CPictureEx来实现GIF.

ImageOle.dll使用了GdiPlus.dll,制作安装包时最好把这个dll也带上( XP系统自带)

(本文的代码来自其他网友)

参考a: http://www.codeproject.com/richedit/AnimatedEmoticon.asp?print=true

参考b: http://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx

1. 先用 regsvr32 注册一下ImageOle.dll

2. 代码

CRichEditCtrlEx 继承自CRichEditCtrl

void CRichEditCtrlEx::insertGif(CString strFilePath) //strFilePath gif文件路径
{
LPLOCKBYTES lpLockBytes = NULL;
SCODE sc;
HRESULT hr;
//print to RichEdit' s IClientSite
LPOLECLIENTSITE m_lpClientSite;
//A smart point to IAnimator
ImageOleLib::IGifAnimatorPtr m_lpAnimator;
//ptr 2 storage
LPSTORAGE m_lpStorage;
//the object 2 b insert 2
LPOLEOBJECT m_lpObject;
//Create lockbytes
sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
if (sc != S_OK)
AfxThrowOleException(sc);
ASSERT(lpLockBytes != NULL);
//use lockbytes to create storage
sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
STGM_SHARE_EXCLUSIVE |STGM_CREATE |STGM_READWRITE, 0, &m_lpStorage);
if (sc != S_OK)
{
VERIFY(lpLockBytes->Release() == 0);
lpLockBytes = NULL;
AfxThrowOleException(sc);
}
ASSERT(m_lpStorage != NULL);
//get the ClientSite of the very RichEditCtrl
GetIRichEditOle()->GetClientSite(&m_lpClientSite);
ASSERT(m_lpClientSite != NULL);
try
{
//Initlize COM interface

hr = ::CoInitialize(NULL) ;//( NULL, COINIT_APARTMENTTHREADED );
if( FAILED(hr) )
_com_issue_error(hr);

//Get GifAnimator object
//here, I used a smart point, so I do not need to free it
hr = m_lpAnimator.CreateInstance(ImageOleLib::CLSID_GifAnimator);
if( FAILED(hr) )
_com_issue_error(hr);
//COM operation need BSTR, so get a BSTR
BSTR path = strFilePath.AllocSysString();

//Load the gif
hr = m_lpAnimator->LoadFromFile(path);
if( FAILED(hr) )
_com_issue_error(hr);

TRACE0( m_lpAnimator->GetFilePath() );

//get the IOleObject
hr = m_lpAnimator.QueryInterface(IID_IOleObject, (void**)&m_lpObject);
if( FAILED(hr) )
_com_issue_error(hr);

//Set it 2 b inserted
OleSetContainedObject(m_lpObject, TRUE);

//2 insert in 2 richedit, you need a struct of REOBJECT
REOBJECT reobject;
ZeroMemory(&reobject, sizeof(REOBJECT));

reobject.cbStruct = sizeof(REOBJECT);
CLSID clsid;
sc = m_lpObject->GetUserClassID(&clsid);
if (sc != S_OK)
AfxThrowOleException(sc);
//set clsid
reobject.clsid = clsid;
//can be selected
reobject.cp = REO_CP_SELECTION;
//content, but not static
reobject.dvaspect = DVASPECT_CONTENT;
//goes in the same line of text line
reobject.dwFlags = REO_BELOWBASELINE; //REO_RESIZABLE |
reobject.dwUser = 0;
//the very object
reobject.poleobj = m_lpObject;
//client site contain the object
reobject.polesite = m_lpClientSite;
//the storage
reobject.pstg = m_lpStorage;

SIZEL sizel;
sizel.cx = sizel.cy = 0;
reobject.sizel = sizel;
HWND hWndRT = this->m_hWnd;
//Sel all text
// ::SendMessage(hWndRT, EM_SETSEL, 0, -1);
// DWORD dwStart, dwEnd;
// ::SendMessage(hWndRT, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
// ::SendMessage(hWndRT, EM_SETSEL, dwEnd+1, dwEnd+1);
//Insert after the line of text
GetIRichEditOle()->InsertObject(&reobject);
::SendMessage(hWndRT, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);
VARIANT_BOOL ret;
//do frame changing
ret = m_lpAnimator->TriggerFrameChange();
//show it
m_lpObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_lpClientSite, 0, m_hWnd, NULL);
m_lpObject->DoVerb(OLEIVERB_SHOW, NULL, m_lpClientSite, 0, m_hWnd, NULL);

//redraw the window to show animation
RedrawWindow();

if (m_lpClientSite)
{
m_lpClientSite->Release();
m_lpClientSite = NULL;
}
if (m_lpObject)
{
m_lpObject->Release();
m_lpObject = NULL;
}
if (m_lpStorage)
{
m_lpStorage->Release();
m_lpStorage = NULL;
}

SysFreeString(path);
}
catch( _com_error e )
{
AfxMessageBox(e.ErrorMessage());
::CoUninitialize();
}

}




分享到:
评论

相关推荐

    richedit中表情的嵌入应用imageole.dll

    richedit中表情的嵌入应用imageole.dll

    ImageOle.dll

    做qq表情时用到的一个dll,使用的时候把它添加到项目中就可以了

    vc-聊天室系统-显示qq表情-文件传送

    应用qq中的ImageOle.dll接口 重载richedit 加入insertface函数 文件传送 由serchSocket发出请求 ,然后以filesocket建立连接,一个一个文件传送 将文件拖到程序窗口就能向连接框中的ip发送文件

    一个聊天软件

    qq表情功能 应用qq中的ImageOle.dll接口 重载richedit 加入insertface函数 文件传送 由serchSocket发出请求 ,然后以filesocket建立连接,一个一个文件传送 将文件拖到程序窗口就能向连接框中的ip发送文件

    聊天窗口演示(XML+GDI表情管理、图文混排...)

    自动释放表情图片资源(程序所在目录)及QQ表情组件(放到\System32\ImageOle.dll),程序自动注册组件,让程序支持GIF格式表情的插入。程序仿FeiQ自动生成表情页面缓存图片,快捷增加大量表情。本程序生成缓存图时...

    Edit扩展类,允许插入图片

    Edit扩展类,实现在edit控件中插入图片

    网狐V5源码下载 (开发库+系统模块)

    │ │ │ ImageOle.dll │ │ │ Information.h │ │ │ IPC_GameFrame.h │ │ │ KernelEngineHead.h │ │ │ LapseCount.h │ │ │ ListControl.h │ │ │ Macro.h │ │ │ MissionManager.h │ │ │ ...

Global site tag (gtag.js) - Google Analytics