   Error from CreateStaticFromData call
  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;}
  -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,hr0x800401f0CoInitialize has not been called.unsigned intNeed to call this first.[Edited by - mattd on February 18, 2010 11:02:20 AM];Quote:Original post by mattdYou can also find this out in MSVC's debugger by using the ",hr" formatter in the watch window:0x800401F0,hr0x800401f0CoInitialize has not been called.unsigned intCool! Learn something new every day :)Thanks Matt, that's exactly what I needed.;  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 objectI 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 InterfaceHRESULT 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 objectImageDataObject = new RichEditBitmapClass;ImageDataObject->QueryInterface(IID_IDataObject, (void**)&DataObject);ImageDataObject->SetBitmap(Bitmap);//Get the RichEdit client sitehr = RichEditOle->GetClientSite(&OleClientSite);if (hr != S_OK)   ...//Initialize a Storage ObjectLockBytes = 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 controlOleObject = 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 controlRichEditOle->InsertObject(&reobject);//cleanupOleObject->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 handlestgm.hBitmap = Bitmap;stgm.pUnkForRelease = NULL;// Use ReleaseStgMediumfm.cfFormat = CF_BITMAP;// Clipboard format = CF_BITMAPfm.ptd = NULL;// Target Device = Screenfm.dwAspect = DVASPECT_CONTENT;// Level of detail = Full contentfm.lindex = -1;// Index = Not applicaplefm.tymed = TYMED_GDI;// Storage medium = HBITMAP handleSetData(&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;}elsereturn 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   ;  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 mattdAll 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 oneOleObject = 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 :PIt'll be a cold day in hell... :);  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.   ;  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.   