Inserting a bitmap file into a CRichEditCtrl

Here is a way to put a bitmap file into an RTF control. It will insert the
file, pWorkSpace->GetWkspTempDirectory() + _T(“\”) + plotName, into the CRichEditCtrl m_reportCtrl:

This goes in the “.h” file:


LPSTORAGE m_lpStorage; // provides storage for m_lpObject
LPLOCKBYTES m_lpLockBytes; // part of implementation of m_lpStorage
LPOLEOBJECT m_lpObject; // in case you want direct access to the OLE object
LPVIEWOBJECT2 m_lpViewObject;// IViewObject for IOleObject above

The rest of this goes in the “.cpp” file:

LPUNKNOWN AFXAPI _AfxQueryInterface(LPUNKNOWN lpUnknown, REFIID iid)
{
ASSERT(lpUnknown != NULL);

LPUNKNOWN lpW = NULL;
if (lpUnknown->QueryInterface(iid, (LPLP)&lpW) != S_OK)
return NULL;

return lpW;
}

void CSimulationReportView::InsertPlotBitmap()
{
USES_CONVERSION;
SCODE sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &m_lpLockBytes);
if (sc != S_OK)
AfxThrowOleException(sc);
ASSERT(m_lpLockBytes != NULL);

sc = ::StgCreateDocfileOnILockBytes(m_lpLockBytes,
STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &m_lpStorage);
if (sc != S_OK)
{
VERIFY(m_lpLockBytes->Release() == 0);
m_lpLockBytes = NULL;
AfxThrowOleException(sc);
}

CWorkSpace * pWorkSpace = GetDocument()->GetWorkSpace();
if ( !pWorkSpace )
return;
CString plotName;
plotName.LoadString( IDS_PLOT_FILENAME );
CString szFileName( pWorkSpace->GetWkspTempDirectory() +
_T(“\”) + plotName );

// attempt to create the object
sc = ::OleCreateFromFile(CLSID_NULL, T2COLE(szFileName),
IID_IUnknown, OLERENDER_DRAW, NULL, NULL,
m_lpStorage, (void **)&m_lpObject);
if ( sc != S_OK )
{
TCHAR * lpMsgBuf;
::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL,
::GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL );
CString msg( lpMsgBuf );
msg += _T(“nnnThe following file, created inn”
“Simulation->Plot, may be missing duen”
“to not doing a File->Save Workspace:nn” );
msg += szFileName;
AfxMessageBox( msg, MB_OK );
::LocalFree( lpMsgBuf );
return;
}

// m_lpObject is currently an IUnknown, convert to IOleObject
if (m_lpObject != NULL)
{
LPUNKNOWN lpUnk = m_lpObject;
m_lpObject = QUERYINTERFACE(lpUnk, IOleObject);
lpUnk->Release();
if (m_lpObject == NULL)
AfxThrowOleException(E_OUTOFMEMORY);
}

// cache the IViewObject interface
m_lpViewObject = QUERYINTERFACE(m_lpObject, IViewObject2);
if (m_lpViewObject == NULL)
return;

// setup for advises; we assume that OLE cleans them up properly
LPADVISESINK lpAdviseSink =
(LPADVISESINK)GetInterface(&IID_IAdviseSink);

// set up view advise
VERIFY(m_lpViewObject->SetAdvise(DVASPECT_CONTENT, 0, lpAdviseSink)
== S_OK);

// the server shows these in its user-interface
// (as document title and in File Exit menu)
m_lpObject->SetHostNames(T2COLE(AfxGetAppName()),
T2COLE(GetDocument()->GetTitle()));

// all items are “contained” — this makes our reference to this object
// weak — which is needed for links to embedding silent update.
OleSetContainedObject(m_lpObject, TRUE);

CHARRANGE cr;
m_reportCtrl.GetSel( cr );
cr.cpMin = cr.cpMax -1;
m_reportCtrl.SetSel( cr );

REOBJECT reo;
memset( &reo, 0, sizeof( reo ) );
reo.cbStruct = sizeof( reo );
CLSID classID;
if ( m_lpObject->GetUserClassID( &classID ) != S_OK)
classID = CLSID_NULL;
reo.clsid = classID;
reo.cp = REO_CP_SELECTION;
reo.poleobj = m_lpObject;
reo.pstg = m_lpStorage;
LPOLECLIENTSITE lpClientSite;
m_reportCtrl.GetIRichEditOle()->GetClientSite( &lpClientSite );
reo.polesite = lpClientSite;
SIZEL sizel;
sizel.cx = sizel.cy = 0; // let richedit determine initial size
reo.sizel = sizel;
reo.dvaspect = DVASPECT_CONTENT;
reo.dwFlags = REO_RESIZABLE;
reo.dwUser = 0;
HRESULT hr = m_reportCtrl.GetIRichEditOle()->InsertObject(&reo);
}

Download demo project – 38 KB

History

More by Author

Must Read