目的:在一个RichEdit中插入一个Gif动画    原代码如下:
void CImageDataObject::InsertGif(IRichEditOle* pRichEditOle,HWND hWnd, CString strName, SIZEL lSize)
{
LPLOCKBYTES lpLockBytes = NULL;
SCODE sc;
HRESULT hr;
//print to RichEdit' s IClientSite
LPOLECLIENTSITE m_lpClientSite;
//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
pRichEditOle->GetClientSite(&m_lpClientSite); ASSERT(m_lpClientSite != NULL); IUnknown * pUnk = NULL;
IObjectTest * pFun = NULL;
IOleControl * pControl = NULL; try
{
hr = ::CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ); hr = ::CoCreateInstance(
CLSID_ObjectTest,
NULL,
CLSCTX_INPROC_SERVER, // 以进程内组件 DLL 方式加载
IID_IUnknown, // 想要取得 IUnknown 接口指针
(LPVOID *) &pUnk); if( FAILED( hr ) ) return;//throw( _T("Not Register") ); hr = pUnk->QueryInterface( // 从 IUnknown 得到其它接口指针
IID_IObjectTest, // 想要取得 IFun 接口指针
(LPVOID *)&pFun );
if( FAILED( hr ) ) return;//throw( _T("Not Register") ); hr = pUnk->QueryInterface( // 从 IUnknown 得到其它接口指针
IID_IOleControl, // 想要取得 IFun 接口指针
(LPVOID *)&pControl );
if( FAILED( hr ) ) return;//throw( _T("Not Register") ); CONTROLINFO  pCI;
pControl->GetControlInfo(&pCI); CString strPicPath;
strPicPath = strName;
BSTR path = strPicPath.AllocSysString();
pFun->PlayFromFile(path); hr = pFun->QueryInterface(IID_IOleObject, (void**)&m_lpObject);
hr = m_lpObject->SetClientSite(m_lpClientSite);    if (FAILED(hr))
{
return;//throw ("...");
}
//Set it 2 b inserted
hr = OleSetContainedObject(m_lpObject, TRUE); if (FAILED(hr)) return;//throw( _T("....") );
//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 = lSize;
reobject.sizel = sizel;
HWND hWndRT = 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
hr = pRichEditOle->InsertObject(&reobject); ::SendMessage(hWndRT, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);//滚动光标到你可以看见的位置
//show it
                //就是下面出问题了  返回的两个 hr = E_FAIL????????????望知道的大虾帮忙
hr = m_lpObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_lpClientSite, 0, hWnd, NULL);//在指定的对象上执行一个动作
hr = m_lpObject->DoVerb(OLEIVERB_SHOW, NULL, m_lpClientSite, 0, hWnd, NULL); //redraw the window to show animation
RedrawWindow(hWnd,NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE); 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());
if (e.ErrorMessage() ==  _T("Not Register"))
{
return;
}else
::CoUninitialize();
}
}