Microsoft KB Archive/178059

= How To Find the URL of an ActiveX Document from Inside the Server =

Article ID: 178059

Article Last Modified on 8/18/2005

-

APPLIES TO


 * Microsoft Internet Explorer 3.0
 * Microsoft Internet Explorer 3.01
 * Microsoft Internet Explorer 3.02
 * Microsoft Internet Explorer 4.0 128-Bit Edition
 * Microsoft Internet Client Software Development Kit 4.0
 * Microsoft Internet Client Software Development Kit 4.01
 * Microsoft ActiveX SDK

-



This article was previously published under Q178059



SUMMARY
This article describes how to find the URL of an ActiveX document from inside the server.



MORE INFORMATION
ActiveX document servers often need to know the full URL of the currently open document file. For example, when an ActiveX document is hosted inside the Internet Explorer frame, Internet Explorer downloads the data for the document from the World Wide Web, invokes the server for that particular document type, and then passes the data to the ActiveX document. Specifically, the server may need to know that the data was actually pulled from "http://example.microsoft.com/test.doc."

In most cases, an ActiveX document server needs the moniker that represents the current document source. You can use the IMoniker::GetDisplayName method to determine the correct URL or file path of the document. This information is especially important to ActiveX document servers that need to access additional supporting data files from locations relative to the URL of the current ActiveX document file. Once the ActiveX document has retrieved the URL from GetDisplayName, it can determine a new absolute URL for any extra data files it may need.

This article discusses two possible ways of obtaining a moniker to the document source. Implement the IPersistMoniker Interface IPersistMoniker is one of the newest OLE/COM persistence mechanisms. It allows an ActiveX document server (or other OLE server) to decide how it persists itself into data, and it gives the server complete control over how that data is obtained. As a result, the server will have a moniker that represents the source of the data.

When navigating to an ActiveX document structured storage file, Internet Explorer first reads a piece of the data file to determine the CLSID of the ActiveX document. If the CLSID is available, Internet Explorer will have enough information to load the document's server. Because Web documents may take a long time to download completely, the server is usually created before all of the data is available.

After the server is created, Internet Explorer performs a QueryInterface on the server's document object for IPersistMoniker. If IPersistMoniker is not supported, Internet Explorer reverts to the standard IPersistFile loading mechanism. If IPersistMoniker is supported, Internet Explorer calls the IPersistMoniker::Load method with the moniker it used to begin downloading the data file. The ActiveX document server can then use the same moniker to re-bind to the data file, which usually does not result in a second download. Note that the server can retrieve the data from the supplied moniker using whatever method it chooses.

The following sample code demonstrates the implementation of IPersistMoniker::Load in a Visual C++ 5.0 MFC-based ActiveX document:

Sample Code: // Necessary INCLUDES #include   #include    #include 

// BEGIN_INTERFACE_MAP section for CPP file: BEGIN_INTERFACE_MAP(CAxDoc, COleServerDoc) // Other entries... INTERFACE_PART(CAxDoc, IID_IPersistMoniker, PersistMoniker) END_INTERFACE_MAP

STDMETHODIMP CAxDoc::XPersistMoniker::Load(BOOL fFullyAvailable,                                     IMoniker __RPC_FAR *pimkName,                                          LPBC pibc, DWORD grfMode) {     USES_CONVERSION; METHOD_PROLOGUE_EX_(CAxDoc, PersistMoniker)

if (NULL == pimkName) return E_FAIL;

// This is not efficient, but all data must be available // If S_FALSE is returned, then a call back is made // when the data is available if (!fFullyAvailable) return S_FALSE;

LPOLESTR strDisplayName; pimkName->GetDisplayName(NULL, NULL, &strDisplayName); pThis->m_strDataURL = OLE2T(strDisplayName);

try { // Use the moniker to download the persisted data // and obtain an IStorage on that data IStoragePtr pStorage; pimkName->BindToStorage(pibc, NULL, IID_IStorage,                                (void**)&pStorage);

// Now use the default MFC implementation of IPersistStorage // From this point forward, assume that // IPersistStorage was used to persist the data. IPersistStoragePtr pPersistStorage; pThis->InternalQueryInterface(&IID_IPersistStorage,                                     (void**)&pPersistStorage); pPersistStorage->Load(pStorage); }     catch(...) {        return E_FAIL; }

return S_OK; } Use the IOleClientSite::GetMoniker Method OLE/COM servers have used this method for some time and it is also available to ActiveX document servers.

The following sample code demonstrates the implementation of IOleClientSite::GetMoniker in a Visual C++ 5.0 MFC-based ActiveX document:

Sample Code: LPMONIKER CAxDoc::GetMoniker {     LPMONIKER pmkThis = NULL; if (m_lpClientSite &&         m_lpClientSite->GetMoniker(OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_OBJFULL, &pmkThis) != S_OK) {        // To be safe, always set moniker to NULL on failure pmkThis = NULL; }

return pmkThis; }

