void
CMyRichEditCtrl::InsertSysHintBitmap(UINT bmpID)
... {
HBITMAP hBitmap = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),
MAKEINTRESOURCE(bmpID),IMAGE_BITMAP,0,0,
LR_CREATEDIBSECTION);
//描述存储媒体自身
STGMEDIUM stgm;
stgm.tymed = TYMED_GDI; // Storage medium = HBITMAP handle
stgm.hBitmap = hBitmap;
stgm.pUnkForRelease = NULL; // Use ReleaseStgMedium
//指定了存储类型(数据格式和存储媒体)
FORMATETC fm;
fm.cfFormat = CF_BITMAP; // Clipboard format = CF_BITMAP
fm.ptd = NULL; // Target Device = Screen
fm.dwAspect = DVASPECT_CONTENT; // Level of detail = Full content
fm.lindex = -1; // Index = Not applicaple
fm.tymed = TYMED_GDI; //IDataObject存储的媒体类型为GDI位图
//创建输入数据源
IStorage *pStorage;
//分配内存
LPLOCKBYTES lpLockBytes = NULL;
SCODE 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);
COleDataSource *pDataSource = new COleDataSource;
pDataSource->CacheData(CF_BITMAP, &stgm);
LPDATAOBJECT lpDataObject =
(LPDATAOBJECT)pDataSource->GetInterface(&IID_IDataObject);
//获取RichEdit的OLEClientSite
LPOLECLIENTSITE lpClientSite;
this->GetIRichEditOle()->GetClientSite( &lpClientSite );
//创建OLE对象
IOleObject *pOleObject;
sc = OleCreateStaticFromData(lpDataObject,IID_IOleObject,OLERENDER_FORMAT,
&fm,lpClientSite,pStorage,(void **)&pOleObject);
if(sc!=S_OK)
AfxThrowOleException(sc);
//插入OLE对象
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 = lpClientSite;
reobject.pstg = pStorage;
reobject.dwUser = 0;
HRESULT hr = GetIRichEditOle()->InsertObject( &reobject );
delete pDataSource;
}
... {
HBITMAP hBitmap = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),
MAKEINTRESOURCE(bmpID),IMAGE_BITMAP,0,0,
LR_CREATEDIBSECTION);
//描述存储媒体自身
STGMEDIUM stgm;
stgm.tymed = TYMED_GDI; // Storage medium = HBITMAP handle
stgm.hBitmap = hBitmap;
stgm.pUnkForRelease = NULL; // Use ReleaseStgMedium
//指定了存储类型(数据格式和存储媒体)
FORMATETC fm;
fm.cfFormat = CF_BITMAP; // Clipboard format = CF_BITMAP
fm.ptd = NULL; // Target Device = Screen
fm.dwAspect = DVASPECT_CONTENT; // Level of detail = Full content
fm.lindex = -1; // Index = Not applicaple
fm.tymed = TYMED_GDI; //IDataObject存储的媒体类型为GDI位图
//创建输入数据源
IStorage *pStorage;
//分配内存
LPLOCKBYTES lpLockBytes = NULL;
SCODE 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);
COleDataSource *pDataSource = new COleDataSource;
pDataSource->CacheData(CF_BITMAP, &stgm);
LPDATAOBJECT lpDataObject =
(LPDATAOBJECT)pDataSource->GetInterface(&IID_IDataObject);
//获取RichEdit的OLEClientSite
LPOLECLIENTSITE lpClientSite;
this->GetIRichEditOle()->GetClientSite( &lpClientSite );
//创建OLE对象
IOleObject *pOleObject;
sc = OleCreateStaticFromData(lpDataObject,IID_IOleObject,OLERENDER_FORMAT,
&fm,lpClientSite,pStorage,(void **)&pOleObject);
if(sc!=S_OK)
AfxThrowOleException(sc);
//插入OLE对象
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 = lpClientSite;
reobject.pstg = pStorage;
reobject.dwUser = 0;
HRESULT hr = GetIRichEditOle()->InsertObject( &reobject );
delete pDataSource;
}
这个函数接受一个“位图资源ID”参数,上面的函数有些问题,当位图的颜色大于256色时,运行正常。但小于这个颜色时(即:用VC资源管理器能打开的位图)将会出现这样一个错误“一个对话框,提示 系统资源不足,无法完成此操作 ”。
修改办法:将上面代码黄色的部分,即LoadImage的最后一个参数改为“LR_DEFAULTCOLOR”即可。为什么我也不知道。
MSDN描述这2个参数意义为:
LR_DEFAULTCOLOR:缺省标志;它不作任何事情。它的含义是“无LR_MONOCHROME”。
LR_CREATEDIBSECTION:当参数uType指定为IMAGE_BITMAP时,使得函数返回一个DIB部分位图,而不是一个兼容的位图。这个标志在装载一个位图,而不是映射它的颜色到显示设备时非常有用。