在 CRichEditCtrl控件里 显示位图

首先定义一个类继承自 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();


 

你可能感兴趣的:(vc++,bmp,CRichEditCtrl,IDataObject)