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; }