Error from CreateStaticFromData call

Started by
7 comments, last by RonHiler 14 years, 1 month ago
Hey guys, This function is throwing an error on me. The OleCreateStaticFromData() is returning -2147221008. I Googled that value but I'm not coming up with any english translation for that number. And GetLastError() isn't getting me anything useful. Can anyone point me in the right direction for either translating that number into something human readable or tell me what I might be doing wrong in this bit of code?

//---------------------------------------------------------------------------
IOleObject* RichEditBitmapClass::GetOleObject(IOleClientSite *OleClientSite, IStorage *Storage)
	{
	SCODE sc;
	IOleObject *OleObject;

	if (stgmed.hBitmap == NULL)
		return NULL;

	sc = OleCreateStaticFromData(this, IID_IOleObject, OLERENDER_FORMAT, &fromat, OleClientSite, Storage, (void**)&OleObject);
	if (sc != S_OK)
		return NULL;
	return OleObject;
	}
Creation is an act of sheer will
Advertisement
-2147221008 == 0x800401F0, i.e., interpret the HRESULT (why are you using a SCODE?) as hex.

Click:
Quote:
//// MessageId: CO_E_NOTINITIALIZED//// MessageText:////  CoInitialize has not been called.//#define CO_E_NOTINITIALIZED              _HRESULT_TYPEDEF_(0x800401F0L)


You can also find this out in MSVC's debugger by using the ",hr" formatter in the watch window:

0x800401F0,hr     0x800401f0     CoInitialize has not been called.     unsigned int


Need to call this first.

[Edited by - mattd on February 18, 2010 11:02:20 AM]
Quote:Original post by mattd
You can also find this out in MSVC's debugger by using the ",hr" formatter in the watch window:

0x800401F0,hr     0x800401f0     CoInitialize has not been called.     unsigned int


Cool! Learn something new every day :)

Thanks Matt, that's exactly what I needed.

Creation is an act of sheer will
Well, I'm going to need more help. My function (which is designed to display a bitmap in a rich edit box) is not working, and I have absolutely no clue as to why. I apologize for the size of the code, I'll remove the error checking to reduce it a bit.

The problem I am having is that no image is appearing in my rich edit box. If I let the routine fire once, I get no error message (but also no image), if I let it fire a second time I get this info:

HEAP[DDOCharGen.exe]: Invalid allocation size - B057CD00 (exceeded 7ffdefff)
HEAP[DDOCharGen.exe]: Invalid allocation size - B057CD00 (exceeded 7ffdefff)
Error creating ole object

I know it's asking a lot, but I'm hoping somebody will see something I am missing.

Here is the code for this function:

#pragma once#include "stdafx.h"class RichEditBitmapClass : IDataObject	{		public:		RichEditBitmapClass();		virtual ~RichEditBitmapClass();			static void InsertBitmap(HWND EditBox, HBITMAP Bitmap);		//the IUnknown interface 		HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject);		ULONG STDMETHODCALLTYPE AddRef();		ULONG STDMETHODCALLTYPE Release();				//the IDataObject Interface		HRESULT STDMETHODCALLTYPE GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);		HRESULT STDMETHODCALLTYPE GetDataHere(FORMATETC*, STGMEDIUM*);		HRESULT STDMETHODCALLTYPE QueryGetData(FORMATETC*);		HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(FORMATETC*, FORMATETC*);		HRESULT STDMETHODCALLTYPE SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL rlse);		HRESULT STDMETHODCALLTYPE EnumFormatEtc(DWORD, IEnumFORMATETC**);		HRESULT STDMETHODCALLTYPE DAdvise(FORMATETC*, DWORD, IAdviseSink*, DWORD*);		HRESULT STDMETHODCALLTYPE DUnadvise(DWORD);		HRESULT STDMETHODCALLTYPE EnumDAdvise(IEnumSTATDATA**);			private:		ULONG RefCnt;		STGMEDIUM stgmed;		FORMATETC fromat;		BOOL release;				void SetBitmap(HBITMAP Bitmap);		IOleObject* GetOleObject(IOleClientSite *OleClientSite, IStorage *Storage);	};


#include "RichEditBitmapClass.h"#include "InterfaceManagerClass.h"//---------------------------------------------------------------------------RichEditBitmapClass::RichEditBitmapClass()	{	RefCnt = 0;	release = false;	CoInitialize(NULL);	}//---------------------------------------------------------------------------RichEditBitmapClass::~RichEditBitmapClass()	{	if (release == TRUE)		ReleaseStgMedium(&stgmed);	CoUninitialize();	}//---------------------------------------------------------------------------void RichEditBitmapClass::InsertBitmap(HWND EditBox, HBITMAP Bitmap)	{	IRichEditOle *RichEditOle;	RichEditBitmapClass *ImageDataObject;	LPDATAOBJECT DataObject;	IOleClientSite *OleClientSite;		IStorage *Storage;		LPLOCKBYTES LockBytes;	HRESULT hr;	IOleObject *OleObject; 	REOBJECT reobject;	CLSID clsid;		//grab the IRichEditOle interface 	SendMessage(EditBox, EM_GETOLEINTERFACE, 0, (LPARAM)&RichEditOle);		//Get the image data object	ImageDataObject = new RichEditBitmapClass;	ImageDataObject->QueryInterface(IID_IDataObject, (void**)&DataObject);		ImageDataObject->SetBitmap(Bitmap);	//Get the RichEdit client site	hr = RichEditOle->GetClientSite(&OleClientSite);	if (hr != S_OK)	   ...	//Initialize a Storage Object	LockBytes = NULL;	hr = CreateILockBytesOnHGlobal(NULL, TRUE, &LockBytes);	if (hr != S_OK || LockBytes == NULL)            ...	hr = StgCreateDocfileOnILockBytes(LockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &Storage);	if (hr != S_OK || Storage == NULL)            ...	// The final ole object which will be inserted in the richedit control	OleObject = ImageDataObject->GetOleObject(OleClientSite, Storage);	if (OleObject == NULL)            ...		OleSetContainedObject(OleObject, TRUE);	//Now Add the object to the RichEdit 	ZeroMemory(&reobject, sizeof(REOBJECT));	reobject.cbStruct = sizeof(REOBJECT);		hr = OleObject->GetUserClassID(&clsid);	if (hr != S_OK)            ...	reobject.clsid = clsid;	reobject.cp = REO_CP_SELECTION;	reobject.dvaspect = DVASPECT_CONTENT;	reobject.poleobj = OleObject;	reobject.polesite = OleClientSite;	reobject.pstg = Storage;	// Insert the bitmap at the current location in the richedit control	RichEditOle->InsertObject(&reobject);	//cleanup	OleObject->Release();	Storage->Release();	OleClientSite->Release();	DataObject->Release();	RichEditOle->Release();	}	//---------------------------------------------------------------------------void RichEditBitmapClass::SetBitmap(HBITMAP Bitmap)	{	STGMEDIUM stgm;	FORMATETC fm;	stgm.tymed = TYMED_GDI;					// Storage medium = HBITMAP handle			stgm.hBitmap = Bitmap;	stgm.pUnkForRelease = NULL;				// Use ReleaseStgMedium	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;					// Storage medium = HBITMAP handle	SetData(&fm, &stgm, TRUE);			}	//---------------------------------------------------------------------------IOleObject* RichEditBitmapClass::GetOleObject(IOleClientSite *OleClientSite, IStorage *Storage)	{	HRESULT hr;	IOleObject *OleObject;	if (stgmed.hBitmap == NULL)		return NULL;	hr = OleCreateStaticFromData(this, IID_IOleObject, OLERENDER_FORMAT, &fromat, OleClientSite, Storage, (void**)&OleObject);	if (hr != S_OK)		return NULL;	return OleObject;	}	//---------------------------------------------------------------------------//----------------------IUnkown pure virtual functions-----------------------//---------------------------------------------------------------------------HRESULT RichEditBitmapClass::QueryInterface(REFIID iid, void **ppvObject)	{	if (iid == IID_IUnknown || iid == IID_IDataObject)		{		*ppvObject = this;		AddRef();		return S_OK;		}	else		return E_NOINTERFACE;	}	//---------------------------------------------------------------------------ULONG RichEditBitmapClass::AddRef()	{	RefCnt++;	return RefCnt;	}//---------------------------------------------------------------------------ULONG RichEditBitmapClass::Release()	{	RefCnt--;	if (RefCnt == 0)		delete this;	return RefCnt;	}//---------------------------------------------------------------------------//------------------IDataObject pure virtual functions-----------------------//---------------------------------------------------------------------------HRESULT RichEditBitmapClass::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) 	{	HANDLE Dest;		Dest = OleDuplicateData(stgmed.hBitmap, CF_BITMAP, NULL);	if (Dest == NULL)		return E_HANDLE;	pmedium->tymed = TYMED_GDI;	pmedium->hBitmap = (HBITMAP)Dest;	pmedium->pUnkForRelease = NULL;	return S_OK;	}//---------------------------------------------------------------------------HRESULT RichEditBitmapClass::GetDataHere(FORMATETC*, STGMEDIUM*) 	{	return E_NOTIMPL;	}//---------------------------------------------------------------------------HRESULT RichEditBitmapClass::QueryGetData(FORMATETC*) 	{	return E_NOTIMPL;	}	//---------------------------------------------------------------------------HRESULT RichEditBitmapClass::GetCanonicalFormatEtc(FORMATETC*, FORMATETC*) 		{	return E_NOTIMPL;	}	//---------------------------------------------------------------------------HRESULT RichEditBitmapClass::SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL rlse) 	{	fromat = *pformatetc;	stgmed = *pmedium;	release = rlse;	return S_OK;	}//---------------------------------------------------------------------------HRESULT RichEditBitmapClass::EnumFormatEtc(DWORD, IEnumFORMATETC**) 	{	return E_NOTIMPL;	}	//---------------------------------------------------------------------------HRESULT RichEditBitmapClass::DAdvise(FORMATETC*, DWORD, IAdviseSink*, DWORD *) 	{	return E_NOTIMPL;	}	//---------------------------------------------------------------------------HRESULT RichEditBitmapClass::DUnadvise(DWORD) 	{	return E_NOTIMPL;	}	//---------------------------------------------------------------------------HRESULT RichEditBitmapClass::EnumDAdvise(IEnumSTATDATA**) 	{	return E_NOTIMPL;	}


Note that this code is loosely based on the code found on this page:
http://www.codeguru.com/cpp/controls/richedit/article.php/c5383
Creation is an act of sheer will
All I can suggest is to use your debugger and find exactly what call is producing the message, and work backwards from there, inspecting handles and values (and most importantly, error codes) as you go.

That, or move to the .NET platform ASAP :P
Quote:Original post by mattd
All I can suggest is to use your debugger and find exactly what call is producing the message, and work backwards from there, inspecting handles and values (and most importantly, error codes) as you go.

Oh, I know the call that is failing. It's this one

OleObject = ImageDataObject->GetOleObject(OleClientSite, Storage);

I think there is something amiss with Storage in that call, but I can't figure out what.

Quote:That, or move to the .NET platform ASAP :P

It'll be a cold day in hell... :)
Creation is an act of sheer will
One thing that sticks out.. you really only want to CoInitialize / CoUninitialize once per thread, ever.

Try moving them out of the (de)constructor and to a more global scope.
Good point. Thanks Matt. That at least got rid of the heap error. Still no image though, and the fail is in the same place. I'll keep working on it. If/when I figure it out, I'll post the solution.
Creation is an act of sheer will
I got it!

Given the code I gave you guys, you couldn't have helped me. The problem was a level higher. I always feel like such an idiot when I figure these things out :) It turns out the graphic was being drawn the whole time, but immediately afterword, was getting cleared out again to draw the subsequent text. Duh. Anyway, the code works as shown (once you move the Co(un)initialize calls as per Matt's suggestion), if anyone wants to use it as a base for their own code.
Creation is an act of sheer will

This topic is closed to new replies.

Advertisement