首先定义一个类继承自 CRichEditCtrl,头文件定义如下
- #pragma once
- // MyRichEdit
- class MyRichEdit : public CRichEditCtrl
- {
- DECLARE_DYNAMIC(MyRichEdit)
- public:
- MyRichEdit();
- virtual ~MyRichEdit();
- public:
- void InsertBitmap(CBitmap & bitmap );
- protected:
- DECLARE_MESSAGE_MAP()
- IRichEditOle *richOle;
- public:
- protected:
- virtual void PreSubclassWindow();
- };
然后再cpp文件中实现如下
- #include "stdafx.h"
- #include "MyIPMsg.h"
- #include "MyRichEdit.h"
- #include <objidl.h>
- #include <ole2.h>
- #include <commctrl.h>
- #include <richedit.h>
- #include <oledlg.h>
- #include <RichOle.h>
- class TDataObject : IDataObject {
- private:
- ULONG refCnt;
- HBITMAP hBmp;
- FORMATETC fe;
- public:
- TDataObject() { refCnt = 0; memset(&fe, 0, sizeof(fe)); }
- ~TDataObject() {}
- STDMETHODIMP QueryInterface(REFIID iid, void **obj);
- STDMETHODIMP_(ULONG) AddRef(void);
- STDMETHODIMP_(ULONG) Release(void);
- STDMETHODIMP GetData(FORMATETC *_fe, STGMEDIUM *sm);
- STDMETHODIMP SetData(FORMATETC *_fe , STGMEDIUM *sm, BOOL fRelease) { return E_NOTIMPL; }
- STDMETHODIMP GetDataHere(FORMATETC *_fe, STGMEDIUM *sm) { return E_NOTIMPL; }
- STDMETHODIMP QueryGetData(FORMATETC *_fe) { return E_NOTIMPL; }
- STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *_fei ,FORMATETC *_feo) { return E_NOTIMPL; }
- STDMETHODIMP EnumFormatEtc(DWORD direc, IEnumFORMATETC **ife) { return E_NOTIMPL; }
- STDMETHODIMP DUnadvise(DWORD conn) { return E_NOTIMPL; }
- STDMETHODIMP EnumDAdvise(IEnumSTATDATA **nav) { return E_NOTIMPL; }
- STDMETHODIMP DAdvise(FORMATETC *_fe, DWORD advf, IAdviseSink *as, DWORD *conn) {
- return E_NOTIMPL; }
- void InsertBitmap(IRichEditOle *richOle, HBITMAP hBmp);
- };
- HRESULT TDataObject::QueryInterface(REFIID riid, LPVOID* ppv)
- {
- *ppv = NULL;
- if (IID_IUnknown == riid || IID_IDataObject == riid) {
- *ppv = this;
- }
- else return ResultFromScode(E_NOINTERFACE);
- AddRef();
- return S_OK;
- }
- HRESULT TDataObject::GetData(FORMATETC *_fe, STGMEDIUM *sm)
- {
- HBITMAP hDupBmp = (HBITMAP)::OleDuplicateData(hBmp, CF_BITMAP, NULL);
- if (!hDupBmp) return E_HANDLE;
- sm->tymed = TYMED_GDI;
- sm->hBitmap = hDupBmp;
- sm->pUnkForRelease = NULL;
- return S_OK;
- }
- ULONG TDataObject::AddRef(void)
- {
- refCnt++;
- return refCnt;
- }
- ULONG TDataObject::Release(void)
- {
- int ret = --refCnt;
- if (0 == refCnt) {
- delete this;
- }
- return ret;
- }
- void TDataObject::InsertBitmap(IRichEditOle *richOle, HBITMAP _hBmp)
- {
- IOleClientSite *ocs = NULL;
- IStorage *is = NULL;
- LPLOCKBYTES lb = NULL;
- IOleObject *oleObj = NULL;
- REOBJECT reobj;
- CLSID clsid;
- hBmp = _hBmp;
- fe.cfFormat = CF_BITMAP;
- fe.ptd = NULL;
- fe.dwAspect = DVASPECT_CONTENT;
- fe.lindex = -1;
- fe.tymed = TYMED_GDI;
- richOle->GetClientSite(&ocs);
- ::CreateILockBytesOnHGlobal(NULL, TRUE, &lb);
- if (!ocs || !lb) goto END;
- ::StgCreateDocfileOnILockBytes(lb, STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &is);
- if (!is) goto END;
- ::OleCreateStaticFromData(this, IID_IOleObject, OLERENDER_FORMAT, &fe, ocs, is,
- (void **)&oleObj);
- if (!oleObj) goto END;
- ::OleSetContainedObject(oleObj, TRUE);
- memset(&reobj, 0, sizeof(REOBJECT));
- reobj.cbStruct = sizeof(REOBJECT);
- oleObj->GetUserClassID(&clsid);
- reobj.clsid = clsid;
- reobj.cp = REO_CP_SELECTION;
- reobj.dvaspect = DVASPECT_CONTENT;
- reobj.poleobj = oleObj;
- reobj.polesite = ocs;
- reobj.pstg = is;
- richOle->InsertObject(&reobj);
- END:
- if (oleObj) oleObj->Release();
- if (lb) lb->Release();
- if (is) is->Release();
- if (ocs) ocs->Release();
- }
- // MyRichEdit
- IMPLEMENT_DYNAMIC(MyRichEdit, CRichEditCtrl)
- MyRichEdit::MyRichEdit()
- {
- richOle=NULL;
- }
- MyRichEdit::~MyRichEdit()
- {
- }
- BEGIN_MESSAGE_MAP(MyRichEdit, CRichEditCtrl)
- END_MESSAGE_MAP()
- void MyRichEdit::InsertBitmap( CBitmap & bitmap )
- {
- TDataObject *dataObject=new TDataObject;
- dataObject->AddRef();
- dataObject->InsertBitmap(richOle,(HBITMAP)bitmap.GetSafeHandle());dataObject->Release();
- }
- void MyRichEdit::PreSubclassWindow()
- {
- this->SendMessage(EM_GETOLEINTERFACE, 0, (LPARAM)&richOle);
- CRichEditCtrl::PreSubclassWindow();
- }
使用时直接调用void MyRichEdit::InsertBitmap( CBitmap & bitmap )就行,在程序的最初还要进行如下初始化
AfxInitRichEdit();
AfxOleInit();