How to load a CRichEditCtrl with RTF containing embedded objects.
-
I have a class called CReportEditCtrl derived from CRichEditCtrl which allows me to programmatically insert an embedded object (OLE mini-server) into the document. This is based on code here: A Rich Edit Control That Displays Bitmaps and Other OLE Objects[^] Embedding is simple enough: CComPtr<IRichEditOle> pIRichEditOle = GetIRichEditOle(); CLSID classId; HRESULT hr = ::CLSIDFromProgID(L"EmbeddedLink.Document", &classId); if (hr == S_OK) { // Get the OLE client site from the container CComPtr<IOleClientSite> pIOleClientSite; hr = pIRichEditOle->GetClientSite(&pIOleClientSite); if (hr != S_OK) { return(false); } // Get storage from the container CComPtr<IStorage> pIStorage; hr = m_pIRichEditOleCallback->GetNewStorage(&pIStorage); if (hr != S_OK) { return(false); } // Create an OLE object i.e. the embedded item CComPtr<IOleObject> pIOleObject; hr = ::OleCreate( classId, IID_IOleObject, OLERENDER_DRAW, NULL, pIOleClientSite, pIStorage, (void**)&pIOleObject); if (hr != S_OK) { return(false); } CDataObject *pDataObject = new CDataObject; pDataObject->AddRef(); pDataObject->Populate(strText); hr = pIOleObject->InitFromData(pDataObject, 0, 0); pDataObject->Release(); if (hr != S_OK) { return(false); } REOBJECT reObject; memset(&reObject, 0, sizeof(reObject)); reObject.cbStruct = sizeof(reObject); reObject.cp = CharFromPos(point); reObject.clsid = classId; reObject.poleobj = pIOleObject; reObject.polesite = pIOleClientSite; reObject.pstg = pIStorage; reObject.dvaspect = DVASPECT_CONTENT; reObject.dwFlags = REO_INPLACEACTIVE|REO_DYNAMICSIZE; hr = pIRichEditOle->InsertObject(&reObject); m_arrayIOleObject.insert(m_arrayIOleObject.end(), pIOleObject.Detach()); } When I stream out the RTF, it looks great, with embedded objects as expected. When I strea
-
I have a class called CReportEditCtrl derived from CRichEditCtrl which allows me to programmatically insert an embedded object (OLE mini-server) into the document. This is based on code here: A Rich Edit Control That Displays Bitmaps and Other OLE Objects[^] Embedding is simple enough: CComPtr<IRichEditOle> pIRichEditOle = GetIRichEditOle(); CLSID classId; HRESULT hr = ::CLSIDFromProgID(L"EmbeddedLink.Document", &classId); if (hr == S_OK) { // Get the OLE client site from the container CComPtr<IOleClientSite> pIOleClientSite; hr = pIRichEditOle->GetClientSite(&pIOleClientSite); if (hr != S_OK) { return(false); } // Get storage from the container CComPtr<IStorage> pIStorage; hr = m_pIRichEditOleCallback->GetNewStorage(&pIStorage); if (hr != S_OK) { return(false); } // Create an OLE object i.e. the embedded item CComPtr<IOleObject> pIOleObject; hr = ::OleCreate( classId, IID_IOleObject, OLERENDER_DRAW, NULL, pIOleClientSite, pIStorage, (void**)&pIOleObject); if (hr != S_OK) { return(false); } CDataObject *pDataObject = new CDataObject; pDataObject->AddRef(); pDataObject->Populate(strText); hr = pIOleObject->InitFromData(pDataObject, 0, 0); pDataObject->Release(); if (hr != S_OK) { return(false); } REOBJECT reObject; memset(&reObject, 0, sizeof(reObject)); reObject.cbStruct = sizeof(reObject); reObject.cp = CharFromPos(point); reObject.clsid = classId; reObject.poleobj = pIOleObject; reObject.polesite = pIOleClientSite; reObject.pstg = pIStorage; reObject.dvaspect = DVASPECT_CONTENT; reObject.dwFlags = REO_INPLACEACTIVE|REO_DYNAMICSIZE; hr = pIRichEditOle->InsertObject(&reObject); m_arrayIOleObject.insert(m_arrayIOleObject.end(), pIOleObject.Detach()); } When I stream out the RTF, it looks great, with embedded objects as expected. When I strea
Using the example program: A Rich Edit Control That Displays Bitmaps and Other OLE Objects I modified the code so that immediately after streaming data from the RTF file into the rich edit control, it streamed it out from the rich edit control into a second file. The output RTF file is not the same as the original. The embedded Windows Media File object is present in the output file. The other embedded objects are not present, and instead there is a metafile in place of each. Anyone any idea why some objects streamed out into the RTF file are present only as metafiles? [Added later] Okay, I have solved the problem in this post, if not the main problem. The example code contains an RTF with 4 embedded objects including one GIF. Of the non GIF objects, only one corresponds to an OLE server that is registered on my PC. So it seems that if the rich edit control is fed objects for OLE servers which are not registered, it discard all but the metafile so they can be drawn, but nothing more.
modified on Saturday, February 27, 2010 7:55 AM
-
I have a class called CReportEditCtrl derived from CRichEditCtrl which allows me to programmatically insert an embedded object (OLE mini-server) into the document. This is based on code here: A Rich Edit Control That Displays Bitmaps and Other OLE Objects[^] Embedding is simple enough: CComPtr<IRichEditOle> pIRichEditOle = GetIRichEditOle(); CLSID classId; HRESULT hr = ::CLSIDFromProgID(L"EmbeddedLink.Document", &classId); if (hr == S_OK) { // Get the OLE client site from the container CComPtr<IOleClientSite> pIOleClientSite; hr = pIRichEditOle->GetClientSite(&pIOleClientSite); if (hr != S_OK) { return(false); } // Get storage from the container CComPtr<IStorage> pIStorage; hr = m_pIRichEditOleCallback->GetNewStorage(&pIStorage); if (hr != S_OK) { return(false); } // Create an OLE object i.e. the embedded item CComPtr<IOleObject> pIOleObject; hr = ::OleCreate( classId, IID_IOleObject, OLERENDER_DRAW, NULL, pIOleClientSite, pIStorage, (void**)&pIOleObject); if (hr != S_OK) { return(false); } CDataObject *pDataObject = new CDataObject; pDataObject->AddRef(); pDataObject->Populate(strText); hr = pIOleObject->InitFromData(pDataObject, 0, 0); pDataObject->Release(); if (hr != S_OK) { return(false); } REOBJECT reObject; memset(&reObject, 0, sizeof(reObject)); reObject.cbStruct = sizeof(reObject); reObject.cp = CharFromPos(point); reObject.clsid = classId; reObject.poleobj = pIOleObject; reObject.polesite = pIOleClientSite; reObject.pstg = pIStorage; reObject.dvaspect = DVASPECT_CONTENT; reObject.dwFlags = REO_INPLACEACTIVE|REO_DYNAMICSIZE; hr = pIRichEditOle->InsertObject(&reObject); m_arrayIOleObject.insert(m_arrayIOleObject.end(), pIOleObject.Detach()); } When I stream out the RTF, it looks great, with embedded objects as expected. When I strea
Never mind. I found a far simpler solution was to represent a link as protected text, ensuring the user could not edit it, but could see the link as simple text. Unfortunately using OLE objects would have meant one application running per link, which is inefficient and, well not good.