#include <comdef.h> #include <richedit.h> #include <richole.h> #include <OleIdl.h> class ImageDataObject:IDataObject { public: static void InsertBitmap(IRichEditOle* pRichEditOle,HBITMAP hBitmap); private: ULONG m_ulRefCnt; BOOL m_bRelease; STGMEDIUM m_stgmed; FORMATETC m_format; public: ImageDataObject():m_ulRefCnt(0) { m_bRelease=False; } ~ImageDataObject() { if(m_bRelease) ::ReleaseStgMedium(&m_stgmed); } STDMETHOD(QueryInterface)(REFIID iid,void **ppvObject) { if(iid==IID_IUnknown||iid==IID_IDataObject) { *ppvObject=this; AddRef(); return S_OK; } return E_NOINTERFACE; } STDMETHOD_(ULONG,AddRef)(void) { m_ulRefCnt++; return m_ulRefCnt; } STDMETHOD_(ULONG,Release)(void) { if(--m_ulRefCnt==0) delete this; return m_ulRefCnt; } STDMETHOD(GetData)(FORMATETC *pFormatetc,STGMEDIUM *pMedium) { HANDLE hDst; hDst=::OleDuplicateData(m_stgmed.hBitmap,CF_BITMAP,NULL); assert(hDst); pMedium->tymed=TYMED_GDI; pMedium->hBitmap=(HBITMAP)hDst; pMedium->pUnkForRelease=NULL; return S_OK; } STDMETHOD(GetDataHere)(FORMATETC *pFormatetc,STGMEDIUM *pMedium) { return E_NOTIMPL; } STDMETHOD(QueryGetData)(FORMATETC *pFormatetc) { return E_NOTIMPL; } STDMETHOD(GetCanonicalFormatEtc)(FORMATETC *pFormatetcIn,FORMATETC *pFormatetcOut) { return E_NOTIMPL; } STDMETHOD(SetData)(FORMATETC *pFormatetc,STGMEDIUM *pMedium,BOOL fRelase) { m_format=*pFormatetc; m_stgmed=*pMedium; return S_OK; } STDMETHOD(EnumFormatEtc)(DWORD dwDirection,IEnumFORMATETC **ppEnumFormatEtc) { return E_NOTIMPL; } STDMETHOD(DAdvise)(FORMATETC *pFormatetc,DWord dwDvf,IAdviseSink *pAdvSink, DWORD *pdwConnection) { return E_NOTIMPL; } STDMETHOD(DUnadvise)(DWORD dwConnection) { return E_NOTIMPL; } STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppEnumAdvise) { return E_NOTIMPL; } void SetBitmap(HBITMAP hBitmap); IOleObject* GetOleObject(IOleClientSite *pOleClientSite,IStorage *pStorage); }; void ImageDataObject::InsertBitmap(IRichEditOle *pRichEditOle,HBITMAP hBitmap) { SCODE sc; ImageDataObject *pods=new ImageDataObject; LPDATAOBJECT lpDataObject; pods->QueryInterface(IID_IDataObject,(void**)&lpDataObject); pods->SetBitmap(hBitmap); IOleClientSite *pOleClientSite; pRichEditOle->GetClientSite(&pOleClientSite); IStorage *pStorage; LPLOCKBYTES lpLockBytes=NULL; sc=CreateILockBytesOnHGlobal(NULL,True,&lpLockBytes); //创建全局存储 if(sc!=S_OK) throw Exception(""); assert(lpLockBytes); sc=StgCreateDocfileOnILockBytes(lpLockBytes,STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0,&pStorage); if(sc!=S_OK) throw Exception(""); assert(pStorage); IOleObject *pOleObject; pOleObject=pods->GetOleObject(pOleClientSite,pStorage); OleSetContainedObject(pOleObject,True); REOBJECT reobject={0}; reobject.cbStruct=sizeof(reobject); CLSID clsid; sc=pOleObject->GetUserClassID(&clsid); if(sc!=S_OK) throw Exception(""); reobject.clsid=clsid; reobject.cp=REO_CP_SELECTION; reobject.dvaspect=DVASPECT_CONTENT; reobject.poleobj=pOleObject; reobject.polesite=pOleClientSite; reobject.pstg=pStorage; pRichEditOle->InsertObject(&reobject); pOleObject->Release(); pOleClientSite->Release(); pStorage->Release(); lpDataObject->Release(); } void ImageDataObject::SetBitmap(HBITMAP hBitmap) { assert(hBitmap); STGMEDIUM stgm={0}; stgm.tymed=TYMED_GDI; stgm.hBitmap=hBitmap; stgm.pUnkForRelease=NULL; FORMATETC fm; fm.cfFormat=CF_BITMAP; fm.ptd=NULL; fm.dwAspect=DVASPECT_CONTENT; fm.lindex=-1; fm.tymed=TYMED_GDI; this->SetData(&fm,&stgm,True); } IOleObject* ImageDataObject::GetOleObject(IOleClientSite *pOleClientSite,IStorage *pStorage) { assert(m_stgmed.hBitmap); SCODE sc; IOleObject *pOleObject; sc=OleCreateStaticFromData(this,IID_IOleObject,OLERENDER_FORMAT, &m_format,pOleClientSite,pStorage, (void**)&pOleObject); if(sc!=S_OK) throw Exception(""); return pOleObject; }
调用方法:
IRichEditOle* pOle=NULL; SendMessage(RichEdit1->Handle,EM_GETOLEINTERFACE,0,(LPARAM)&pOle); assert(pOle); HBITMAP hBitmap=(HBITMAP)LoadImageA(NULL,"C:/000.BMP",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); assert(hBitmap); ImageDataObject::InsertBitmap(pOle,hBitmap); DeleteObject(hBitmap);