FARINTERNAL_(BOOL) UtGetClassID(LPUNKNOWN lpUnk, CLSID FAR* lpClsid) { VDATEHEAP(); LPOLEOBJECT lpOleObj; // IOleObject pointer LPPERSIST lpPersist; // IPersist pointer // try to ask it as an object if (lpUnk->QueryInterface(IID_IOleObject, (LPLPVOID)&lpOleObj) == NOERROR) { lpOleObj->GetUserClassID(lpClsid); lpOleObj->Release(); return(TRUE); } // try to ask it as a persistent object if (lpUnk->QueryInterface(IID_IPersist, (LPLPVOID)&lpPersist) == NOERROR) { lpPersist->GetClassID(lpClsid); lpPersist->Release(); return(TRUE); } *lpClsid = CLSID_NULL; return(FALSE); }
STDMETHODIMP COleUILinkInfo::SetLinkSource( DWORD dwLink, LPTSTR lpszDisplayName, ULONG lenFileName, ULONG* pchEaten, BOOL fValidateSource) { USES_CONVERSION; COleClientItem* pItem = (COleClientItem*)dwLink; ASSERT_VALID(pItem); ASSERT_KINDOF(COleClientItem, pItem); ASSERT(pItem->GetType() == OT_LINK); LPOLEOBJECT lpObject = NULL; CLSID clsid; // parse the portion known to be a file name into a file moniker TCHAR szName[_MAX_PATH]; lstrcpyn(szName, lpszDisplayName, (int)lenFileName + 1); LPMONIKER lpmk = NULL; SCODE sc = CreateFileMoniker(T2COLE(szName), &lpmk); if (lpmk == NULL) return sc; LPBC lpbc = NULL; if (fValidateSource) { sc = CreateBindCtx(0, &lpbc); if (sc != S_OK) { lpmk->Release(); return sc; } } // nUneaten is the number of chars left to parse UINT nUneaten = lstrlen(lpszDisplayName) - lenFileName; // lpszRemainder is the left over display name LPTSTR lpszRemainder = lpszDisplayName + lenFileName; *pchEaten = lenFileName; // parse the rest of the display name while (nUneaten > 0) { // attempt to parse next moniker ULONG nEaten = 0; LPMONIKER lpmkNext = NULL; sc = _AfxParseDisplayName(lpmk, lpbc, lpszRemainder, &nEaten, &lpmkNext); if (sc != S_OK) { lpmk->Release(); lpbc->Release(); return sc; } // advance through the display name nUneaten -= nEaten; *pchEaten += nEaten; lpszRemainder += nEaten; if (lpmkNext != NULL) { // create composite out of current and next LPMONIKER lpmkTemp = NULL; sc = CreateGenericComposite(lpmk, lpmkNext, &lpmkTemp); if (FAILED(sc)) { lpmk->Release(); lpmkNext->Release(); lpbc->Release(); return sc; } // make current = next lpmkNext->Release(); lpmk->Release(); lpmk = lpmkTemp; } } if (fValidateSource) { // attempt to bind the the object sc = lpmk->BindToObject(lpbc, NULL, IID_IOleObject, (LPLP)&lpObject); if (FAILED(sc)) { pItem->m_bLinkUnavail = TRUE; lpbc->Release(); lpmk->Release(); RELEASE(lpObject); return sc; } ASSERT(lpObject != NULL); // call GetUserClassID while bound so default handler updates lpObject->GetUserClassID(&clsid); pItem->m_bLinkUnavail = FALSE; } // get IOleLink interface LPOLELINK lpOleLink = QUERYINTERFACE(pItem->m_lpObject, IOleLink); ASSERT(lpOleLink != NULL); // set source from moniker sc = lpOleLink->SetSourceMoniker(lpmk, clsid); // update the cache if object was successfully bound if (lpObject != NULL) { lpObject->Update(); lpObject->Release(); } // cleanup lpOleLink->Release(); RELEASE(lpmk); RELEASE(lpbc); return sc; }
HGLOBAL AFXAPI _AfxOleGetObjectDescriptorData( LPOLEOBJECT lpOleObj, LPCOLESTR lpszSrcOfCopy, DWORD dwDrawAspect, POINTL pointl, LPSIZEL lpSizelHim) { USES_CONVERSION; CLSID clsid; LPOLESTR lpszFullUserTypeName = NULL; LPMONIKER lpSrcMonikerOfCopy = NULL; HGLOBAL hObjDesc = NULL; IBindCtx *pbc = NULL; SCODE sc; SIZEL sizelHim; BOOL bFreeSrcOfCopy = FALSE; LPVIEWOBJECT2 lpViewObj2; LPOLELINK lpOleLink; BOOL fIsLink; TCHAR szLinkedTypeFmt[80]; LPCOLESTR lpszLinkedTypeFmt; LPOLESTR lpszBuf = NULL; DWORD dwStatus = 0; // query for IOleLink lpOleLink = QUERYINTERFACE(lpOleObj, IOleLink); fIsLink = lpOleLink != NULL; // query for IViewObject2 lpViewObj2 = QUERYINTERFACE(lpOleObj, IViewObject2); // Get CLSID sc = lpOleObj->GetUserClassID(&clsid); if (sc != S_OK) clsid = CLSID_NULL; // Get FullUserTypeName sc = lpOleObj->GetUserType(USERCLASSTYPE_FULL, &lpszFullUserTypeName); // if object is a link, then expand usertypename to be "Linked %s" if (fIsLink && lpszFullUserTypeName != NULL) { // Note: If this LoadString call fails, it is likely that // _AFX_NO_OLE_RESOURCES is defined in your .RC file. // To correct the situation remove the following line from your // resource script: // #define _AFX_NO_OLE_RESOURCES // This should be done using the Resource.Set Includes... command. VERIFY(AfxLoadString(AFX_IDS_PASTELINKEDTYPE, szLinkedTypeFmt)); lpszLinkedTypeFmt = T2COLE(szLinkedTypeFmt); lpszBuf = (LPOLESTR)CoTaskMemAlloc((ocslen(lpszFullUserTypeName) + ocslen(lpszLinkedTypeFmt) + 1) * sizeof(OLECHAR)); if (lpszBuf != NULL) { #ifdef OLE2ANSI sprintf(lpszBuf, lpszLinkedTypeFmt, lpszFullUserTypeName); #else swprintf(lpszBuf, lpszLinkedTypeFmt, lpszFullUserTypeName); #endif CoTaskMemFree(lpszFullUserTypeName); lpszFullUserTypeName = lpszBuf; } } // get source of copy if (fIsLink) { sc = lpOleLink->GetSourceDisplayName((LPOLESTR*)&lpszSrcOfCopy); bFreeSrcOfCopy = TRUE; } else if (lpszSrcOfCopy == NULL) { sc = lpOleObj->GetMoniker( OLEGETMONIKER_TEMPFORUSER, OLEWHICHMK_OBJFULL, &lpSrcMonikerOfCopy); if (sc == S_OK) { CreateBindCtx(0, &pbc); lpSrcMonikerOfCopy->GetDisplayName(pbc, NULL, (LPOLESTR*)&lpszSrcOfCopy); RELEASE(pbc); bFreeSrcOfCopy = TRUE; } } if (lpSizelHim) { // Use extents passed by the caller sizelHim = *lpSizelHim; } else if (lpViewObj2) { // Get the current extents from the object sc = lpViewObj2->GetExtent(dwDrawAspect, -1, NULL, (LPSIZEL)&sizelHim); if (sc != S_OK) sizelHim.cx = sizelHim.cy = 0; } else { sizelHim.cx = sizelHim.cy = 0; } // Get dwStatus sc = lpOleObj->GetMiscStatus(dwDrawAspect, &dwStatus); if (sc != S_OK) dwStatus = 0; // Get OBJECTDESCRIPTOR hObjDesc = _AfxOleGetObjectDescriptorData(clsid, dwDrawAspect, sizelHim, pointl, dwStatus, lpszFullUserTypeName, lpszSrcOfCopy); // Clean up CoTaskMemFree(lpszFullUserTypeName); if (bFreeSrcOfCopy) CoTaskMemFree((LPOLESTR)lpszSrcOfCopy); RELEASE(lpSrcMonikerOfCopy); RELEASE(lpOleLink); RELEASE(lpViewObj2); return hObjDesc; }
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; } }
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); } }