| HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit ControlID: Q220844 
 | 
The RichEdit control does not provide a direct method for loading a bitmap and inserting it into an RTF document. The ActiveX control (RichTextBox) provides the Add method through the COleObjects class, but this action loads the bitmap for editing in the registered bitmap editor (usually Paintbrush) before inserting it into the document. Both the DLL and the OCX expose the IRichEditOle interface which, however, provides the InsertObject method. This requires a fully-populated RichEdit Object (REOBJECT) structure to be passed.
The following code is based on a project in which the Microsoft RichTextBox control has been inserted. With minor changes, it can apply to the RichEdit DLL as well.
	LPRICHEDITOLE	m_pRichEditOle;
	LPOLEOBJECT	m_lpObject;
	LPSTORAGE         m_lpStorage;
	LPOLECLIENTSITE	m_lpClientSite; 
	::SendMessage((HWND)m_ctlRichText.GetHwnd(), EM_GETOLEINTERFACE, 0, (LPARAM)&m_pRichEditOle);
	ASSERT(m_pRichEditOle != NULL); 
BOOL CRichTextDlg::CreateFromFile(LPCTSTR lpszFileName)
{
	USES_CONVERSION;
	ASSERT_VALID(this);
	ASSERT(m_lpObject == NULL);     // one time only
	ASSERT(m_lpStorage == NULL);
	ASSERT(m_lpClientSite == NULL);
	LPLOCKBYTES lpLockBytes = NULL;
	CLSID clsid = CLSID_NULL;
	OLERENDER render = OLERENDER_DRAW;
	CLIPFORMAT cfFormat = 0;
	LPFORMATETC lpFormatEtc = NULL;
	SCODE sc;
	sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
	if (sc != S_OK)
		AfxThrowOleException(sc);
	ASSERT(lpLockBytes != NULL);
	sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
		STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &m_lpStorage);
	if (sc != S_OK)
	{
		VERIFY(lpLockBytes->Release() == 0);
		lpLockBytes = NULL;
		AfxThrowOleException(sc);
	}
	ASSERT(m_lpStorage != NULL);
	// fill in FORMATETC struct
	FORMATETC formatEtc;
	lpFormatEtc = &formatEtc;
	lpFormatEtc->cfFormat = cfFormat;
	lpFormatEtc->ptd = NULL;
	lpFormatEtc->dwAspect = DVASPECT_CONTENT;
	lpFormatEtc->lindex = -1;
	lpFormatEtc->tymed = (DWORD)-1;
	// attempt to create the object
	m_pRichEditOle->GetClientSite(&m_lpClientSite);
	sc = ::OleCreateFromFile(clsid, T2COLE(lpszFileName),
		IID_IUnknown, OLERENDER_NONE, lpFormatEtc, m_lpClientSite, m_lpStorage,
		(void**)&m_lpObject);
	if (sc != S_OK)
		AfxThrowOleException(sc);
	// m_lpObject is currently an IUnknown, convert to IOleObject
	if (m_lpObject != NULL)
	{
		LPUNKNOWN lpUnk = m_lpObject;
		lpUnk->QueryInterface(IID_IOleObject, (void**)&m_lpObject);
		lpUnk->Release();
		if (m_lpObject == NULL)
			AfxThrowOleException(E_OUTOFMEMORY);
	}
	// 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);
	ASSERT_VALID(this);
	return TRUE;
}
 
	REOBJECT reobject;
	ZeroMemory(&reobject, sizeof(REOBJECT));
	reobject.cbStruct = sizeof(REOBJECT);
	CLSID clsid;
	SCODE sc = m_lpObject->GetUserClassID(&clsid);
	if (sc != S_OK)
		AfxThrowOleException(sc);
	reobject.clsid = clsid;
	reobject.cp = REO_CP_SELECTION;
	reobject.dvaspect = DVASPECT_CONTENT;
	reobject.dwFlags = REO_RESIZABLE | REO_BELOWBASELINE;
	reobject.dwUser = 0;
	reobject.poleobj = m_lpObject;
	ASSERT(m_lpClientSite != NULL);
	reobject.polesite = m_lpClientSite;
	ASSERT(m_lpStorage != NULL);
	reobject.pstg = m_lpStorage;
	SIZEL sizel;
	sizel.cx = sizel.cy = 0;
	reobject.sizel = sizel; 
	HWND hWndRT = (HWND)m_ctlRichText.GetHwnd();
	::SendMessage(hWndRT, EM_SETSEL, 0, -1);
	DWORD dwStart, dwEnd;
	::SendMessage(hWndRT, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
	::SendMessage(hWndRT, EM_SETSEL, dwEnd+1, dwEnd+1); 
	CString strCr = "\r\n";
	m_ctlRichText.SetSelText((LPCTSTR)strCr); 
	m_pRichEditOle->InsertObject(&reobject); 
	::SendMessage(hWndRT, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0); 
	if (m_lpObject)
	{
		m_lpObject->Release();
		m_lpObject = NULL;
	}
	if (m_lpStorage)
	{
		m_lpStorage->Release();
		m_lpStorage = NULL;
	}
	if (m_lpClientSite)
	{
		m_lpClientSite->Release();
		m_lpClientSite = NULL;
	} Additional query words:
Keywords          : kbole kbBitmap kbCtrl kbMFC kbRichEdit kbVC600 kbDSupport 
Version           : winnt:6.0
Platform          : winnt 
Issue type        : kbhowto Last Reviewed: July 1, 1999