在添加图片之前,先了解两个结构:
1.STGMEDIUM
这个结构描述了一个用于数据传输介质的对象。
typedef struct tagSTGMEDIUM {
DWORD tymed;//存储介质。封送处理和unmarshaling例程使用此值来确定哪个成员被使用。此值必须是TYMED枚举的因素之一。
union {
HBITMAP hBitmap; //一个位图句柄HBITMAP句柄。
HMETAFILEPICT hMetaFilePict;//hMetaFilePict图元文件句柄。
HENHMETAFILE hEnhMetaFile;//hEnhMetaFile一个增强型图元文件句柄
HGLOBAL hGlobal; //hGlobal全局内存句柄。
LPOLESTR lpszFileName; //lpszFileName长指针为空结束的字符串,其中包含一个磁盘文件,它包含数据路径。
IStream *pstm; //IStream接口指针
IStorage *pstg; //一个IStorage接口指针
} u;
IUnknown *pUnkForRelease;
} uSTGMEDIUM
成员
处理,字符串,或接口指针,接收过程可以用来访问数据被传输。如果tymed是TYMED_NULL,成员是不确定的,否则,它是下列之一:值描
pUnkForRelease
指针到一个接口的实例,它允许发送过程控制释放的存储过程调用时接收的ReleaseStgMedium作用方式。如果pUnkForRelease为NULL,ReleaseStgMedium使用默认程序,以释放存储,否则,ReleaseStgMedium使用指定的接口。
备注
你的字符串在lpszFileName成员必须通过分配或通过使用LocalAlloc malloc的。
第二个结构 FORMATETC
typedef struct tagFORMATETC
{
CLIPFORMAT cfFormat;
/* [unique] */ DVTARGETDEVICE _RPC_FAR *ptd;
DWORD dwAspect;
LONG lindex;
DWORD tymed;
} FORMATETC;
第一个参数:ctFormat
特别感兴趣的剪贴板格式。有三种类型的格式,由OLE确认:
标准交换格式,如CF_TEXT。
私人申请格式理解,只有在提供的格式,或其他应用程序提供类似功能的应用。
的OLE格式,用于创建链接或嵌入的对象。
第二个参数: dwAspect
指向一个DVTARGETDEVICE结构,它包含有关该目标设备的数据被组成的信息。一个空值时使用指定的数据格式是独立于目标设备或来电时,不关心使用什么设备。在后一种情况下,如果数据需要一个目标设备,对象应该选择一个适当的默认设备(通常为可视组件显示)。从获得的数据与一个空的目标设备,比如大多数对象图元文件,是目标设备的独立。由此产生的数据通常是因为它是,如果用户选择从文件菜单命令保存并选择了一个交换格式相同。
ptd
指定一个枚举常量的DVASPECT指示多少细节应在渲染中。单一剪贴板格式可以支持多个方面或对象的意见。大多数数据和演示传输和缓存方面的信息传递方式。例如,可能会要求呼叫者对象的一个标志性的图片,图元文件使用剪贴板格式进行检索。请注意,只有一DVASPECT价值能够dwAspect使用。也就是说,dwAspect不可能是一个布尔OR操作几个DVASPECT值的结果。
第三个参数:lindex
部分的内容时,必须将数据通过页面边界分歧。最常见的值是-1,其中确定的所有数据。对于DVASPECT_THUMBNAIL和DVASPECT_ICON,lindex被忽略的方面。
第四个参数:tymed
其中一个TYMED枚举常量指示存储介质类型用来传输数据的对象。数据可以使用任何传输介质,使对象的意义。例如,数据可以通过使用全局内存,磁盘文件,或者结构化存储的对象。欲了解更多信息,请参阅TYMED枚举。
实例代码;
Vc2005 对话框 添加一个richedit控件,并在APP::InitInstance()添加如下的语句:AfxInitRichEdit();//否则窗口一闪而过
添加一个按钮
按钮的事件如下:
在头文件.h和cpp中添加头文件afxole.h richole.h
头文件 定义
IOleObject* m_pPicObj;
BOOL GetPic(REOBJECT FAR* pObject);
cpp文件定义
BOOL CrichDlg::GetPic(REOBJECT FAR* pObject)
{
CRichEditCtrl* pTextIn1=(CRichEditCtrl*)GetDlgItem(IDC_CUSTOM2);
IRichEditOle* pITextIn1=pTextIn1->GetIRichEditOle();
LONG lCount=pITextIn1->GetObjectCount();
LRESULT lRet;
for(int i=0;i<lCount;i++)
{
lRet=pITextIn1->GetObject(0,pObject,REO_GETOBJ_POLEOBJ);
if(lRet==S_OK)
{
pObject->poleobj->Release();
if(pObject->poleobj==m_pPicObj)
{
return TRUE;
}
}
}
return FALSE;
}
void CrichDlg::OnBnClickedButton1()
{
CString sFilter=_T("Files(*.bmp)|*.bmp||");
CFileDialog dlg(TRUE,0,0,OFN_FILEMUSTEXIST,(LPCTSTR)sFilter,this);
if(dlg.DoModal()==IDOK)
{
CString m_strFile=dlg.GetPathName();
HBITMAP hBitmap=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),m_strFile,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTCOLOR);
STGMEDIUM stgm;
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;
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);
LPOLECLIENTSITE lpClientSite;
CRichEditCtrl* pTextIn1=(CRichEditCtrl*)GetDlgItem(IDC_CUSTOM2);
pTextIn1->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;
REOBJECT obj;
obj.cbStruct=sizeof(obj);
if( GetPic(&obj) )
{
long lStart,lEnd;
pTextIn1->GetSel(lStart,lEnd);
pTextIn1->SetSel(obj.cp,obj.cp+1);
pTextIn1->Clear();
pTextIn1->GetIRichEditOle()->InsertObject(&reobject);
pTextIn1->SetSel(lStart,lEnd);
}
else
{
pTextIn1->GetIRichEditOle()->InsertObject(&reobject);
}
delete pDataSource;
m_pPicObj=pOleObject;
::SendMessage(pTextIn1->m_hWnd,EM_SCROLLCARET,(WPARAM)0,(LPARAM)0);
pTextIn1->SetFocus();
}
}