void CExRichEditWindowless::InsertGif(LONG gif) { CComQIPtr<IDynamicOleCom> spDyn; HRESULT hr = spDyn.CoCreateInstance(STR_PROGID); if(SUCCEEDED(hr)) { LPOLEOBJECT lpOleObject = NULL; HRESULT hr = spDyn->QueryInterface(IID_IOleObject, (void**)&lpOleObject); IUnknownPtr lpUnk = lpOleObject; hr = lpUnk->QueryInterface(IID_IOleObject, (LPVOID*)&lpOleObject); if (lpOleObject == NULL) throw(E_OUTOFMEMORY); //hr = lpOleObject->SetClientSite( static_cast<IOleClientSite *>( this ) ); IViewObject2Ptr lpViewObject;// IViewObject for IOleObject above hr = lpOleObject->QueryInterface(IID_IViewObject2, (LPVOID*)&lpViewObject); if (hr != S_OK) { AtlThrow(hr); } IRichEditOle* pRichEditOle = GetIRichEditOle(); ////获取RichEdit的OLEClientSite IOleClientSitePtr lpClientSite; hr = pRichEditOle->GetClientSite(&lpClientSite); if (hr != S_OK) { AtlThrow(hr); } REOBJECT reobject; ZeroMemory(&reobject,sizeof(REOBJECT)); reobject.cbStruct = sizeof(REOBJECT); CLSID clsid; hr = lpOleObject->GetUserClassID(&clsid); if (hr != S_OK) { AtlThrow(hr); } reobject.clsid = clsid; reobject.cp = -1; //reobject.cp = REO_CP_SELECTION; reobject.dvaspect = DVASPECT_CONTENT;//DVASPECT_OPAQUE; reobject.poleobj = lpOleObject; reobject.polesite = lpClientSite; //reobject.pstg = lpStorage; SIZEL sizel; sizel.cx = sizel.cy = 0; // let richedit determine initial size Image* img = (Image*)gif; SIZEL sizeInPix = {img->GetWidth(), img->GetHeight()}; SIZEL sizeInHiMetric; AtlPixelToHiMetric(&sizeInPix, &sizeInHiMetric); reobject.sizel = sizeInHiMetric; reobject.dwFlags = REO_BELOWBASELINE|REO_STATIC;//REO_RESIZABLE CExRichEditData* pdata = new CExRichEditData; pdata->m_dataType = GIF; pdata->m_data = (void*)gif; reobject.dwUser = (DWORD)pdata;//TODO 用户数据 lpOleObject->SetClientSite(lpClientSite); hr = pRichEditOle->InsertObject(&reobject); lpOleObject->SetExtent(DVASPECT_CONTENT, &sizeInHiMetric); OleSetContainedObject(lpOleObject, TRUE); lpOleObject->Release(); spDyn->SetHostWindow((LONG)hwndParent); spDyn->InsertGif(gif); } }
void UIIMEdit::InsertImage(BSTR bstrFileName,SIZE size,BOOL isGif) { LPSTORAGE lpStorage = NULL; LPOLEOBJECT lpObject = NULL; LPLOCKBYTES lpLockBytes = NULL; LPOLECLIENTSITE lpClientSite = NULL; GifSmiley::IGifSmileyCtrl* lpAnimator = nullptr; HRESULT hr = ::CoCreateInstance(GifSmiley::CLSID_CGifSmileyCtrl, NULL, CLSCTX_INPROC, GifSmiley::IID_IGifSmileyCtrl, (LPVOID*)&lpAnimator); if (NULL == lpAnimator || FAILED(hr)) { LOG__(ERR, _T("InsertImage CoCreateInstance failed")); goto End; } COLORREF backColor = (COLORREF)(::GetSysColor(COLOR_WINDOW)); HWND hwnd = (HWND)((long)m_pManager->GetPaintWindow()); IRichEditOle *pRichEditOle = m_pRichEditOle; if (NULL == pRichEditOle) goto End; BSTR path = NULL; //Create lockbytes hr = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes); if (FAILED(hr)) { LOG__(ERR, _T("InsertImage CreateILockBytesOnHGlobal failed")); goto End; } //use lockbytes to create storage SCODE sc = ::StgCreateDocfileOnILockBytes(lpLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &lpStorage); if (sc != S_OK) { LOG__(ERR, _T("InsertImage StgCreateDocfileOnILockBytes failed")); goto End; } // retrieve OLE interface for richedit and Get site pRichEditOle->GetClientSite(&lpClientSite); try { //COM operation need BSTR, so get a BSTR path = bstrFileName; //Load the image if (isGif) lpAnimator->LoadFromFile(path); else { UInt32 height = (size.cy < GetHeight()) ? size.cy : GetHeight(); UInt32 width = (size.cx < GetWidth() / 2) ? size.cx : GetWidth() / 2; lpAnimator->LoadFromFileSized(path, width, height); } //Set back color OLE_COLOR oleBackColor = (OLE_COLOR)backColor; lpAnimator->put_BackColor(oleBackColor); //get the IOleObject hr = lpAnimator->QueryInterface(IID_IOleObject, (void**)&lpObject); if (FAILED(hr)) { LOG__(ERR, _T("InsertImage lpAnimator QueryInterface failed")); goto End; } //Set it to be inserted OleSetContainedObject(lpObject, TRUE); //to insert into richedit, you need a struct of REOBJECT REOBJECT reobject; ZeroMemory(&reobject, sizeof(REOBJECT)); reobject.cbStruct = sizeof(REOBJECT); CLSID clsid; hr = lpObject->GetUserClassID(&clsid); //set clsid reobject.clsid = clsid; //can be selected reobject.cp = REO_CP_SELECTION; //content, but not static reobject.dvaspect = DVASPECT_CONTENT; //goes in the same line of text line reobject.dwFlags = REO_BELOWBASELINE; //reobject.dwUser = (DWORD)myObject; //the very object reobject.poleobj = lpObject; //client site contain the object reobject.polesite = lpClientSite; //the storage reobject.pstg = lpStorage; SIZEL sizel = { 0 }; reobject.sizel = sizel; LPOLECLIENTSITE lpObjectClientSite = NULL; hr = lpObject->GetClientSite(&lpObjectClientSite); if (FAILED(hr) || lpObjectClientSite == NULL) lpObject->SetClientSite(lpClientSite); pRichEditOle->InsertObject(&reobject); //redraw the window to show animation ::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE); } catch (...) { LOG__(ERR, _T("InsertImage unknown exeption")); } End: if (lpClientSite) { lpClientSite->Release(); lpClientSite = nullptr; } if (lpObject) { lpObject->Release(); lpObject = nullptr; } if (lpLockBytes) { lpLockBytes->Release(); lpLockBytes = nullptr; } if (lpStorage) { lpStorage->Release(); lpStorage = nullptr; } if (lpAnimator) { lpAnimator->Release(); lpAnimator = nullptr; } }
// 插入表情图片 BOOL RichEdit_InsertFace(ITextServices *pTextServices, ITextHost *pTextHost, LPCTSTR lpszFileName, int nFaceId, int nFaceIndex, COLORREF clrBg, BOOL bAutoScale, int nReservedWidth) { BSTR bstrFileName = NULL; IRichEditOle * pRichEditOle = NULL; IOleClientSite *pOleClientSite = NULL; IImageOle* pImageOle = NULL; IOleObject *pOleObject = NULL; REOBJECT reobject = {0}; HRESULT hr = E_FAIL; if (NULL == pTextServices || NULL == pTextHost || NULL == lpszFileName || NULL == *lpszFileName) return FALSE; TCHAR cProtocol[16] = {0}; _tcsncpy(cProtocol, lpszFileName, 7); if ((_tcsicmp(cProtocol, _T("http://")) != 0) && ::GetFileAttributes(lpszFileName) == 0xFFFFFFFF) return FALSE; bstrFileName = ::SysAllocString(lpszFileName); if (NULL == bstrFileName) return FALSE; pTextServices->TxSendMessage(EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle, NULL); if (NULL == pRichEditOle) goto Ret0; hr = ::CoCreateInstance(CLSID_ImageOle, NULL, CLSCTX_INPROC_SERVER, IID_IImageOle, (void**)&pImageOle); if (FAILED(hr)) goto Ret0; hr = pImageOle->QueryInterface(IID_IOleObject, (void **)&pOleObject); if (FAILED(hr)) goto Ret0; pRichEditOle->GetClientSite(&pOleClientSite); if (NULL == pOleClientSite) goto Ret0; pOleObject->SetClientSite(pOleClientSite); pImageOle->SetTextServices(pTextServices); pImageOle->SetTextHost(pTextHost); pImageOle->SetFaceId(nFaceId); pImageOle->SetFaceIndex(nFaceIndex); pImageOle->SetBgColor(clrBg); pImageOle->SetAutoScale(bAutoScale, nReservedWidth); pImageOle->LoadFromFile(bstrFileName); hr = ::OleSetContainedObject(pOleObject, TRUE); reobject.cbStruct = sizeof(REOBJECT); reobject.clsid = CLSID_ImageOle; reobject.cp = REO_CP_SELECTION; reobject.dvaspect = DVASPECT_CONTENT; reobject.dwFlags = REO_BELOWBASELINE; reobject.poleobj = pOleObject; reobject.polesite = pOleClientSite; reobject.dwUser = 0; hr = pRichEditOle->InsertObject(&reobject); Ret0: if (pOleObject != NULL) pOleObject->Release(); if (pImageOle != NULL) pImageOle->Release(); if (pOleClientSite != NULL) pOleClientSite->Release(); if (pRichEditOle != NULL) pRichEditOle->Release(); if (bstrFileName != NULL) ::SysFreeString(bstrFileName); return SUCCEEDED(hr); }