//---------------------------------------------------------------------------
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;
}
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?
-2147221008 == 0x800401F0, i.e., interpret the HRESULT (why are you using a SCODE?) as hex.
Click:
You can also find this out in MSVC's debugger by using the ",hr" formatter in the watch window:
Need to call this first.
[Edited by - mattd on February 18, 2010 11:02:20 AM]
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.
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:
Note that this code is loosely based on the code found on this page:
http://www.codeguru.com/cpp/controls/richedit/article.php/c5383
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
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
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... :)
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.
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement