描述:
怎样在CRichEditCtrl中插入BMP图片或GIF文件(类似QQ那样表情符)
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
下载COM底成代码:如下ImageDataObject.h
class CImageDataObject : IDataObject
{
public:
// This static fumction accepts those parameters:
// IRichEditOle* : a pointer to IRochEditOle interface for the RichEdit Control
// HBITMAP : the bitmap handle.
//
// After calling the function, it inserts the image in the current
// position of the RichEdit
//
static void InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap);
private:
ULONG m_ulRefCnt;
BOOL m_bRelease;
// The data being bassed to the richedit
//
STGMEDIUM m_stgmed;
FORMATETC m_fromat;
public:
CImageDataObject() : m_ulRefCnt(0)
{
m_bRelease = FALSE;
}
~CImageDataObject()
{
if (m_bRelease)
::ReleaseStgMedium(&m_stgmed);
}
// Methods of the IUnknown interface
//
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
{
if (iid == IID_IUnknown || iid == IID_IDataObject)
{
*ppvObject = this;
AddRef();
return S_OK;
}
else
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;
}
// Methods of the IDataObject Interface
//
STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) {
HANDLE hDst;
hDst = ::OleDuplicateData(m_stgmed.hBitmap, CF_BITMAP, NULL);
if (hDst == NULL)
{
return E_HANDLE;
}
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* pformatectIn ,FORMATETC* pformatetcOut ) {
return E_NOTIMPL;
}
STDMETHOD(SetData)(FORMATETC* pformatetc , STGMEDIUM* pmedium , BOOL fRelease ) {
m_fromat = *pformatetc;
m_stgmed = *pmedium;
return S_OK;
}
STDMETHOD(EnumFormatEtc)(DWORD dwDirection , IEnumFORMATETC** ppenumFormatEtc ) {
return E_NOTIMPL;
}
STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink,
DWORD *pdwConnection) {
return E_NOTIMPL;
}
STDMETHOD(DUnadvise)(DWORD dwConnection) {
return E_NOTIMPL;
}
STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise) {
return E_NOTIMPL;
}
// Some Other helper functions
//
void SetBitmap(HBITMAP hBitmap);
IOleObject *GetOleObject(IOleClientSite *pOleClientSite, IStorage *pStorage);
};
ImageDataObject.cpp
#include "stdafx.h"
#include "ImageDataObject.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Static member functions
//////////////////////////////////////////////////////////////////////
void CImageDataObject::InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap)
{
SCODE sc;
// Get the image data object
//
CImageDataObject *pods = new CImageDataObject;
LPDATAOBJECT lpDataObject;
pods->QueryInterface(IID_IDataObject, (void **)&lpDataObject);
pods->SetBitmap(hBitmap);
// Get the RichEdit container site
//
IOleClientSite *pOleClientSite;
pRichEditOle->GetClientSite(&pOleClientSite);
// Initialize a Storage Object
//
IStorage *pStorage;
LPLOCKBYTES lpLockBytes = NULL;
sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
if (sc != S_OK)
AfxThrowOleException(sc);
ASSERT(lpLockBytes != NULL);
sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &pStorage);
if (sc != S_OK)
{
VERIFY(lpLockBytes->Release() == 0);
lpLockBytes = NULL;
AfxThrowOleException(sc);
}
ASSERT(pStorage != NULL);
// The final ole object which will be inserted in the richedit control
//
IOleObject *pOleObject;
pOleObject = pods->GetOleObject(pOleClientSite, pStorage);
// all items are "contained" -- this makes our reference to this object
// weak -- which is needed for links to embedding silent update.
OleSetContainedObject(pOleObject, TRUE);
// Now Add the object to the RichEdit
//
REOBJECT reobject;
ZeroMemory(&reobject, sizeof(REOBJECT));
reobject.cbStruct = sizeof(REOBJECT);
CLSID clsid;
sc = pOleObject->GetUserClassID(&clsid);
if (sc != S_OK)
AfxThrowOleException(sc);
reobject.clsid = clsid;
reobject.cp = REO_CP_SELECTION;
reobject.dvaspect = DVASPECT_CONTENT;
reobject.poleobj = pOleObject;
reobject.polesite = pOleClientSite;
reobject.pstg = pStorage;
// Insert the bitmap at the current location in the richedit control
//
pRichEditOle->InsertObject(&reobject);
// Release all unnecessary interfaces
//
pOleObject->Release();
pOleClientSite->Release();
pStorage->Release();
lpDataObject->Release();
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
////////////////////////////////////////////////////
您可能想查找下面的文章:
- QQ图文发送方式?可否将OCX控件当作OLE对象插入CRichEditCtrl?ADO如何读取XML中的记录集?寻求技术高人请进
- 想做一个可插入到CRichEditCtrl中显示GIF动画的组件,遇到点问题,请朋友们帮忙指点谢谢
- ATL做的一个控件,用于插入到CRichEditCtrl中显示GIF图片,控件中用一个线程显示GIF图片,
- ATL写的ActiveX控件,在CRichEditCtrl容器里怎样控制ActiveX大小?
- 如何开发一个OLE组件,可以插入到OLE容器中使用比如插入CRichEditCtrl?
- 急问:CRichEditCtrl中StreamOut用法出错的问题???????????????
- CRichEditCtrl插入ole图片与Ctrl+V插入图片不一样??
- 请教CRichEditCtrl修改字间距问题
- CRichEditCtrl和数据库交互!
- CRichEditCtrl里无窗口的控件怎么添加窗口提示?