紧急请教一个ole的问题,希望大家都能共同学习!

ouyang1802870 2013-01-10 01:55:59
现在正在做一个企业即时通讯,在截图的时候遇到了问题,问题如下:
目前我已经将图片截取到richedit当中了,发送的时候我要获取到richedit中的每张图片的信息,网上找了相关代码研究,但是有问题,仍然无法得到图片信息,希望找到问题原因或者有更好的方式能够获取到图片信息,望大家不吝提出宝贵意见,代码如下

IRichEditOle *pobject;
SendMessage( pU->hWndSend, EM_GETOLEINTERFACE, 0, (LPARAM) &pobject);

int nObjectMount = pobject->GetObjectCount();

for(int i = 0; i < nObjectMount; ++i) //遍历位图
{
REOBJECT object;
memset(&object,0,sizeof(REOBJECT));
object.cbStruct = sizeof(REOBJECT);
pobject->GetObjectA(i, &object, REO_GETOBJ_ALL_INTERFACES);

IDataObject* pDataObject = NULL;
SCODE sc = object.poleobj->QueryInterface( IID_IDataObject,(void**&pDataObject ); // 获取IDataObject信息

if(sc != S_OK)
{
break;
}

STGMEDIUM stg;
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; // 对应CF_BITMAP

HRESULT hr = pDataObject->GetData( &fm, &stg );

if ( hr != S_OK || stg.hBitmap == NULL )
{
break; // 已经找到选中的图片对象,获取信息失败,直接退出
}

部分代码如上,我的目的是要获得图片的句柄,最后hr值显示的是“无效的FORMATETC结构”,导致获取信息失败,跳出了循环,百度、谷歌的资颇少,新账号分数不多,希望得到指导,谢谢!
...全文
402 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
liujiquan123 2013-05-27
  • 打赏
  • 举报
回复
我的问题解决方法
HBITMAP bmp = GetImage(uInt);
	InserBitMap(m_sendText,bmp,uInt);
	InserBitMap(m_viewText,bmp,uInt);
改成

        HBITMAP bmp = GetImage(uInt);
	InserBitMap(m_sendText,bmp,uInt);
	bmp = GetImage(uInt);
	InserBitMap(m_viewText,bmp,uInt);
liujiquan123 2013-05-27
  • 打赏
  • 举报
回复
我的问题是 OLE 无效的FORMATETC结构
void InserBitMap(CRichEditCtrl& richEditCtrl,HBITMAP bmp,int index)
{  
	int nEndPos = richEditCtrl.GetWindowTextLength();
	richEditCtrl.SetSel(nEndPos,nEndPos);

	STGMEDIUM stgm;
	memset(&stgm,0,sizeof(STGMEDIUM));
	stgm.tymed = TYMED_GDI;			// Storage medium = HBITMAP handle
	stgm.hBitmap = bmp;
	stgm.pUnkForRelease = NULL;		// Use ReleaseStgMedium

	FORMATETC fm;
	memset(&fm,0,sizeof(FORMATETC));
	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;

	//创建输入数据源
	IStorage*pStorage;
	//分配内存
	LPLOCKBYTES lpLockBytes = NULL;
	SCODE scode = ::CreateILockBytesOnHGlobal(NULL,TRUE,&lpLockBytes);
	if(scode != S_OK)
		AfxThrowOleException(scode);
	if(lpLockBytes == NULL)
		return;
	scode = ::StgCreateDocfileOnILockBytes(lpLockBytes,
		STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE,0,&pStorage);
	if(scode != S_OK)
	{
		VERIFY(lpLockBytes->Release() == 0);
		lpLockBytes = NULL;
		AfxThrowOleException(scode);
	}
	
	if(pStorage == NULL)
		return;
	COleDataSource *pDataSource = new COleDataSource;
	pDataSource->CacheData(CF_BITMAP,&stgm);
	LPDATAOBJECT lpDataObject =(LPDATAOBJECT) pDataSource->GetInterface(&IID_IDataObject);
	//获取RichEdit的OleClientSite
	LPOLECLIENTSITE lpClientSite;
	richEditCtrl.GetIRichEditOle()->GetClientSite(&lpClientSite);

	//创建OLE对象
	IOleObject *pOleObject;
	scode = ::OleCreateStaticFromData(lpDataObject,IID_IOleObject,OLERENDER_FORMAT,
		&fm,lpClientSite,pStorage,(void**)&pOleObject);
	if(scode != S_OK) 
		AfxThrowOleException(scode);
	if(pOleObject == NULL)
		return;
	//插入OLE对象
	REOBJECT reobject;
	ZeroMemory(&reobject, sizeof(REOBJECT));
	reobject.cbStruct = sizeof(REOBJECT);

	CLSID clsid;
	scode = pOleObject->GetUserClassID(&clsid);
	if(scode != S_OK)
		AfxThrowOleException(scode);
	reobject.clsid = clsid;
	reobject.cp = REO_CP_SELECTION;
	reobject.dvaspect = DVASPECT_CONTENT;
	reobject.poleobj = pOleObject;
	reobject.polesite = lpClientSite;
	reobject.pstg = pStorage;
	reobject.dwUser = index;

	richEditCtrl.GetIRichEditOle()->InsertObject(&reobject);
	//////////////////////////////////////////////////////////////////////////
	pOleObject->Release(); pOleObject = NULL;
	lpClientSite->Release();lpClientSite = NULL;
	pStorage->Release();pStorage = NULL;
	lpDataObject->Release();lpDataObject = NULL;
	lpLockBytes->Release();lpLockBytes = NULL;
	if(pDataSource)
	{
	//	ZeroMemory(pDataSource,sizeof(COleDataSource));
		pDataSource = NULL;
	}
}

HBITMAP CTalkDlg::GetImage(int index)
{
	IMAGEINFO info;
	m_imgListFaces.GetImageInfo(index,&info);
	int wid = info.rcImage.right-info.rcImage.left;
	int hei = info.rcImage.bottom-info.rcImage.top;

	CClientDC cdc(NULL);
	CDC memDC;
	CBitmap bitmap2;
	bitmap2.CreateCompatibleBitmap(&cdc,wid,hei);
	memDC.CreateCompatibleDC(&cdc);
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap2);
	memDC.FillSolidRect(0,0,wid,hei,m_sendText.SetBackgroundColor(TRUE,0));
	m_imgListFaces.Draw(&memDC,index,CPoint(0,0),ILD_NORMAL);
	memDC.SelectObject(pOldBitmap);
	return (HBITMAP)bitmap2.Detach();
}
liujiquan123 2013-05-27
  • 打赏
  • 举报
回复
我也碰到这个问题了
大蓝头 2013-01-22
  • 打赏
  • 举报
回复
借楼主个位置:哪位帮忙解答下这个问题:http://bbs.csdn.net/topics/210038758
大蓝头 2013-01-22
  • 打赏
  • 举报
回复
有一种情况是需要这样处理的,你从其他地方复制过来的图片,是不知道其路径的。
w_xei 2013-01-22
  • 打赏
  • 举报
回复
我们是在另外的地方保存图片路径名称,传递的时候去读取文件,不在编辑框中取
大蓝头 2013-01-22
  • 打赏
  • 举报
回复
楼上啥意思呀?
jimette 2013-01-22
  • 打赏
  • 举报
回复
引用 2 楼 TragicGuy 的回复:
给你个我的代码,项目中使用的,确实可行。C/C++ code?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051DWORD CSkinRichEdit::GetSelectObjectUser(){ DWORD dRet = -1;……
大蓝头 2013-01-22
  • 打赏
  • 举报
回复
reobject.dwUser = SetImagePath(strPath); 这一句代码,原来是想重新设置dwUser这个属性的,但发现没办法保存到对象中,不知道这里要如何写才行。
大蓝头 2013-01-21
  • 打赏
  • 举报
回复
这是获取当前选中的图片,我也想问下你有没有更快的获取选择中片的办法
大蓝头 2013-01-21
  • 打赏
  • 举报
回复
给你个我的代码,项目中使用的,确实可行。

DWORD CSkinRichEdit::GetSelectObjectUser()
{
	DWORD dRet = -1;
	int nCount = m_pIRichEditOle->GetObjectCount(); // 当前m_ChatEdit中所有的object对象
	for ( int i=nCount -1; i >= 0; i-- )
	{
		REOBJECT reobject;
		memset( &reobject, 0 , sizeof(REOBJECT) );
		reobject.cbStruct = sizeof(REOBJECT);
		
		SCODE sc = m_pIRichEditOle->GetObject( i, &reobject, REO_GETOBJ_ALL_INTERFACES ); // 获取到reobject对象
		if ( sc != S_OK )
		{
			continue;
		}

		if ( (reobject.dwFlags & REO_SELECTED) != REO_SELECTED ) // 检验当前reobject是否处于选中状态
		{
			continue; // 不是当前选中的对象,继续查找
		}
		IDataObject* pDataObject = NULL;
		sc = reobject.poleobj->QueryInterface( IID_IDataObject, (void**)&pDataObject ); // 获取IDataObject信息
		if ( sc != S_OK )
		{
			break; // 已经找到选中的图片对象,获取信息失败,直接退出
		}
		CString strPath = "";
		if(reobject.dwUser > 0)
		{			
			dRet = reobject.dwUser;	
		}
		else
		{
			FORMATETC fmtetc = { CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
			STGMEDIUM stgmed;

			// ask the IDataObject for some CF_TEXT data, stored as a HGLOBAL
			if(pDataObject->GetData(&fmtetc, &stgmed) == S_OK)
			{
				CString strPath = "c:\\test.bmp";
				
				SaveToBmp(stgmed.hBitmap, strPath);
				dRet = reobject.dwUser = SetImagePath(strPath);
				ReleaseStgMedium(&stgmed);
			}
		}
		pDataObject->Release();
		break;
	}
	return dRet;
}
ouyang1802870 2013-01-10
  • 打赏
  • 举报
回复
大家顶起啊,困扰中

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧