HOWTO: Find the URL of ActiveX Document from Inside the Server

Last reviewed: March 5, 1998
Article ID: Q178059
The information in this article applies to:
  • Microsoft Internet Explorer (Programming), versions 3.0, 3.01, 3.02, 4.0
  • Internet Client SDK, versions 4.0, 4.01
  • Microsoft ActiveX SDK, version 1.0

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:

  1. 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 <comdef.h>
   #include <afxconv.h>
   #include <urlmon.h>

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

    REFERENCES

    In some sample code, this article uses Visual C++ 5.0 Smart Pointers (IxxxPtr). For more information on Visual C++ 5.0 Smart Pointers and other COM compiler features available in Visual C++ 5.0, please review the following documentation:

       Visual C++ Books Online: Visual C++; Visual C++ Programmer's Guide;
       Adding Program Functionality; Overviews; Compiler COM Support: Overview
    
    
    Keywords          : AXSDKDocObjects kbcode
    Technology        : kbInetDev
    Version           : WINDOWS:3.0,3.01,3.02,4.0
    Platform          : WINDOWS
    Issue type        : kbhowto

  • ================================================================================


    THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

    Last reviewed: March 5, 1998
    © 1998 Microsoft Corporation. All rights reserved. Terms of Use.