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