IDispatch van een Excel- of Word-document ophalen uit een OCX

Vertaalde artikelen Vertaalde artikelen
Artikel ID: 190985 - Bekijk de producten waarop dit artikel van toepassing is.
Alles uitklappen | Alles samenvouwen

Op deze pagina

Samenvatting

Het is gebruikelijk voor een OLE-besturingselement moet de IDispatch van de container. U vind de IDispatch vaak met QueryInterface() uit onmiddellijk toegankelijke interfaces op de server, zoals IOleClientSite. Echter, voor Sommige servers, zoals Microsoft Excel, mislukt deze methode.

Een andere manier om de IDispatch is met behulp van de API voor GetActiveObject() de server IDispatch ophalen uit de ROT. Deze methode vereist echter dat u moet de CLSID of ProgID van de server verkrijgen. Voorts Dubbelzinnige situaties kunnen zich voordoen wanneer u geen onderscheid maken tussen meerdere exemplaren van de server.

In dit artikel wordt een andere benadering de IDispatch die werkt voor Microsoft Excel en Microsoft Word, zelfs als meerdere exemplaren uitgevoerd.

De onderstaande stappen kunnen u een besturings element dat u kunt bouwen de IDispatch van het container Document-object.

Meer informatie

Stap voor stap voorbeeld

  1. Maak een nieuwe MFC ActiveX-ControlWizard-toepassing met de naam OffCntrDisp.
  2. Het volgende lid variabelen toevoegen aan uw klasse die is afgeleid van COleControl:
          char m_szDocName[512];
          IDispatch *m_pDocDisp;
    					
    OPMERKING: m_szDocName bevat de naam van het document met onze controle en m_pDocDisp de IDispatch-interface voor dat document.

  3. Voeg het volgende toe aan het einde van de COleControl afgeleid klasse definitie:
          // Interface Maps.
          protected:
             // IoleObject.
             BEGIN_INTERFACE_PART(MyOleObject, IOleObject)
                INIT_INTERFACE_PART(COffCtlDispCtrl, MyOleObject)
                STDMETHOD(SetClientSite)(LPOLECLIENTSITE);
                STDMETHOD(GetClientSite)(LPOLECLIENTSITE*);
                STDMETHOD(SetHostNames)(LPCOLESTR, LPCOLESTR);
                STDMETHOD(Close)(DWORD);
                STDMETHOD(SetMoniker)(DWORD, LPMONIKER);
                STDMETHOD(GetMoniker)(DWORD, DWORD, LPMONIKER*);
                STDMETHOD(InitFromData)(LPDATAOBJECT, BOOL, DWORD);
                STDMETHOD(GetClipboardData)(DWORD, LPDATAOBJECT*);
                STDMETHOD(DoVerb)(LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND,
                LPCRECT);
                STDMETHOD(EnumVerbs)(IEnumOLEVERB**);
                STDMETHOD(Update)();
                STDMETHOD(IsUpToDate)();
                STDMETHOD(GetUserClassID)(CLSID*);
                STDMETHOD(GetUserType)(DWORD, LPOLESTR*);
                STDMETHOD(SetExtent)(DWORD, LPSIZEL);
                STDMETHOD(GetExtent)(DWORD, LPSIZEL);
                STDMETHOD(Advise)(LPADVISESINK, LPDWORD);
                STDMETHOD(Unadvise)(DWORD);
                STDMETHOD(EnumAdvise)(LPENUMSTATDATA*);
                STDMETHOD(GetMiscStatus)(DWORD, LPDWORD);
                STDMETHOD(SetColorScheme)(LPLOGPALETTE);
            END_INTERFACE_PART(MyOleObject)
    
            DECLARE_INTERFACE_MAP();
    					
    Dit wordt toegevoegd aan de standaard implementatie van de COleControl overschrijven Gegevens met uw aangepaste MyOleObject.

  4. In uw COleControl afgeleide klasse constructor toevoegen de volgende:
          m_pDocDisp = NULL;
  5. Direct na de volgende regel in OffCntrDispCtl.cpp:
          IMPLEMENT_OLECTLTYPE(COffCntrDispCtrl, IDS_OFFCNTRDISP,
    
           _dwOffCntrDispOleMisc)
    					
    Voeg de volgende code:
          BEGIN_INTERFACE_MAP(COffCntrDispCtrl, COleControl)
              INTERFACE_PART(COffCntrDispCtrl, IID_IOleObject, MyOleObject)
          END_INTERFACE_MAP()
    					
    Dit, samen met de wijzigingen die u in stap 3 vervangen van COleControl Gegevens.

  6. Voeg het volgende toe onder de code in stap 5 hebt toegevoegd:
          static char buf[8192];
          static void DoMsg(char *msg) {
             ::MessageBox(NULL, msg, "Message", MB_SETFOREGROUND);
          }
    
          static void DoErr(char *msg, long err) {
             static char errBuf[8192];
             sprintf(errBuf, "%s, Error: %ld (%08lx)", msg, err,err);
             ::MessageBox(NULL, errBuf, "Error", MB_SETFOREGROUND);
          }
    					
    Dit zijn nuttige routines die later worden gebruikt voor het weer geven van berichten.

  7. Plak alle van de volgende code aan het einde van de OffCntrDispCtl.cpp bestand:
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::SetHostNames(LPCOLESTR
          pwApp, LPCOLESTR pwObj)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
    
              // Convert OLESTR into ASCII string.
    
              WideCharToMultiByte(CP_ACP, 0, pwObj, -1, pThis->m_szDocName,
              512, NULL, NULL);
    
              // Get IDispatch.
              pThis->GetDocDispatch();
    
              // Test it out by getting the document name.
              pThis->TestDispatch();
    
              return S_OK;
          }
    
          STDMETHODIMP
          COffCntrDispCtrl::XMyOleObject::SetClientSite(LPOLECLIENTSITE
          pClientSite)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.SetClientSite(pClientSite);
          }
    
          STDMETHODIMP
          COffCntrDispCtrl::XMyOleObject::SetColorScheme(LPLOGPALETTE plp)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.SetColorScheme(plp);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::GetMiscStatus(DWORD
          dwAspect, DWORD* pdwStatus)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.GetMiscStatus(dwAspect, pdwStatus);
          }
    
          STDMETHODIMP
          COffCntrDispCtrl::XMyOleObject::EnumAdvise(LPENUMSTATDATA*
          ppenumAdvise)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.EnumAdvise(ppenumAdvise);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::Unadvise(DWORD
          dwConnection)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.Unadvise(dwConnection);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::Advise(LPADVISESINK
          pAdvSink, DWORD* pdwConnection)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.Advise(pAdvSink, pdwConnection);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::GetExtent(DWORD
          dwDrawAspect, LPSIZEL lpsizel)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.GetExtent(dwDrawAspect, lpsizel);
          }
    
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::SetExtent(DWORD
          dwDrawAspect, LPSIZEL lpsizel)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.SetExtent(dwDrawAspect, lpsizel);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::GetUserType(DWORD
          dwFormOfType, LPOLESTR* ppszUserType)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
    
              return pThis->m_xOleObject.GetUserType(dwFormOfType,
              ppszUserType);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::GetUserClassID(CLSID*
          pClsid)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.GetUserClassID(pClsid);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::IsUpToDate()
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
    
              return pThis->m_xOleObject.IsUpToDate();
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::Update()
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.Update();
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::EnumVerbs(LPENUMOLEVERB*
          ppenumOleVerb)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
    
              return pThis->m_xOleObject.EnumVerbs(ppenumOleVerb);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::DoVerb(LONG iVerb, LPMSG
          lpmsg, LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent,
          LPCRECT lprcPosRect)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.DoVerb(iVerb, lpmsg, pActiveSite,
              lindex, hwndParent, lprcPosRect);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::GetClipboardData(DWORD
          dwReserved, LPDATAOBJECT *ppDataObject)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.GetClipboardData(dwReserved,
              ppDataObject);
          }
    
          STDMETHODIMP
          COffCntrDispCtrl::XMyOleObject::InitFromData(LPDATAOBJECT
          pDataObject, BOOL fCreation, DWORD dwReserved)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.InitFromData(pDataObject, fCreation,
              dwReserved);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::GetMoniker(DWORD
          dwAssign, DWORD dwWhichMoniker, LPMONIKER *ppmk)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.GetMoniker(dwAssign, dwWhichMoniker,
              ppmk);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::SetMoniker(DWORD
          dwWhichMoniker, LPMONIKER pmk)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.SetMoniker(dwWhichMoniker, pmk);
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::Close(DWORD
          dwSaveOption)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.Close(dwSaveOption);
          }
    
          STDMETHODIMP
          COffCntrDispCtrl::XMyOleObject::GetClientSite(LPOLECLIENTSITE*
          ppClientSite)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.GetClientSite(ppClientSite);
    
          }
    
          STDMETHODIMP_(ULONG) COffCntrDispCtrl::XMyOleObject::Release()
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.Release();
          }
    
          STDMETHODIMP_(ULONG) COffCntrDispCtrl::XMyOleObject::AddRef()
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.AddRef();
          }
    
          STDMETHODIMP COffCntrDispCtrl::XMyOleObject::QueryInterface(REFIID
          iid, LPVOID* ppvObj)
          {
              METHOD_MANAGE_STATE(COffCntrDispCtrl, MyOleObject)
              ASSERT_VALID(pThis);
              return pThis->m_xOleObject.QueryInterface(iid, ppvObj);
          }
    					
    Dit is de implementatie van gegevens, meestal alle van de implementatie van de standaard-COleControl gegevens, met uitzondering van SetHostNames() aanroepen delegeert. U SetHostNames() trap en opslaan van de naam van het document waar u het besturings element wordt ingevoegd.

    Helaas aanroepen geen Microsoft PowerPoint deze methode, zodat dit voorbeeld niet met dit product werkt. Microsoft Powerpoint is echter een single-instance server, zodat u GetActiveObject() gebruiken kan om unieke IDispatch-pointer.
  8. Het volgende lidfuncties toevoegen aan uw klasse die is afgeleid van COleControl:
          void COffCntrDispCtrl::GetDocDispatch()
          {
              // No need, if we already have it.
              if(m_pDocDisp != NULL) return;
    
              // Get a BindCtx.
              IBindCtx *pbc;
              HRESULT hr = CreateBindCtx(0, &pbc);
              if(FAILED(hr)) {
                  DoErr("CreateBindCtx()", hr);
                  return;
              }
    
              // Get running-object table.
              IRunningObjectTable *prot;
              hr = pbc->GetRunningObjectTable(&prot);
              if(FAILED(hr)) {
                  DoErr("GetRunningObjectTable()", hr);
                  pbc->Release();
                  return;
              }
    
              // Get enumeration interface.
              IEnumMoniker *pem;
              hr = prot->EnumRunning(&pem);
              if(FAILED(hr)) {
                  DoErr("EnumRunning()", hr);
                  prot->Release();
                  pbc->Release();
                  return;
              }
    
              // Start at the beginning.
              pem->Reset();
    
              // Churn through enumeration.
              ULONG fetched;
              IMoniker *pmon;
              int n = 0;
              while(pem->Next(1, &pmon, &fetched) == S_OK) {
    
                  // Get DisplayName.
                  LPOLESTR pName;
                  pmon->GetDisplayName(pbc, NULL, &pName);
                  // Convert it to ASCII.
                  char szName[512];
                  WideCharToMultiByte(CP_ACP, 0, pName, -1, szName, 512, NULL,
                  NULL);
    
                  // Compare it against the name we got in SetHostNames().
                  if(!strcmp(szName, m_szDocName)) {
    
                      DoMsg("Found document in ROT!");
    
                      // Bind to this ROT entry.
                      IDispatch *pDisp;
                      hr = pmon->BindToObject(pbc, NULL, IID_IDispatch, (void
                      **)&pDisp);
                      if(!FAILED(hr)) {
                          // Remember IDispatch.
                          m_pDocDisp = pDisp;
    
                          // Notice...
                          sprintf(buf, "Document IDispatch = %08lx",
                          m_pDocDisp);
                          DoMsg(buf);
                      }
                      else {
                          DoErr("BindToObject()", hr);
                      }
                  }
    
                  // Release interfaces.
                  pmon->Release();
    
                  // Break out if we obtained the IDispatch successfully.
                  if(m_pDocDisp != NULL) break;
              }
    
              // Release interfaces.
              pem->Release();
              prot->Release();
              pbc->Release();
          }
    
          void COffCntrDispCtrl::TestDispatch()
          {
              ASSERT(m_pDocDisp);
    
              COleDispatchDriver doc(m_pDocDisp);
              DISPID dispID = 0;
              unsigned short *ucPtr = L"Name";
    
              // Get DISPID for Name.
              HRESULT hr = m_pDocDisp->GetIDsOfNames(IID_NULL, &ucPtr, 1,
              LOCALE_USER_DEFAULT, &dispID);
              ASSERT(!FAILED(hr));
    
    
              // Get Name property.
              CString name;
              doc.GetProperty(dispID, VT_BSTR, &name);
    
              AfxMessageBox(
                  CString("Document name is ") + name,
                  MB_SETFOREGROUND
              );
          }
    					
  9. Compilatie!
Voer de volgende stappen voor uw besturings element testen in Microsoft Excel 97:
  1. Start Microsoft Excel 97.
  2. Brengen van deWerkset besturings elementenwerkbalk (op deWeergavemenu, klikt u opWerk balken).
  3. Klik op het uiterst rechts hamer & moer sleutel pictogram in deWerkset besturings elementenwerkbalk en selecteer het nieuwe besturings element; het moet OffCntrDisp worden aangeroepen.
  4. Teken een rechthoek in het werk blad invoegen van het besturings element.RESULTATEN: U ziet de besturings element wordt weer gegeven, en kort daarna een berichtvenster met gevonden" document in ROT." Vervolgens moet er een ander bericht vak weer iets dergelijks te "Document IDispatch = 0043bf8c." Tot slot, als u verschijnt een berichtvenster waarin u de naam van het document waarbij deze is ingevoegd.
Volgende stappen volgen om te testen uw controle in Microsoft Office Excel 2007:
  1. Excel 2007 start.
  2. Klik op deOntwikkelaartabblad. Als deOntwikkelaartabblad niet wordt weer gegeven op het lint, volgt het tabblad inschakelen:
    1. Klik op deMicrosoft Office-knop, en klik vervolgens opOpties voor Excel.
    2. Klik op dePopulairetabblad en klik vervolgens op deTabblad ontwikkelaars op het lint weer gevenselectie vakje.
    3. Klik opOK.
  3. In deBesturings elementengroep op deOntwikkelaaren klik opInvoegen.
  4. OnderActiveX-besturingselementen, klik opMeer besturings elementen.
  5. In deMeer besturings elementenhet dialoog venster, klikt u opOffCntrDisp.
  6. Teken een rechthoek in het werk blad invoegen van het besturings element.RESULTATENHet besturings element wordt weer gegeven. Kort daarna een berichtvenster met "Document gevonden in ROT" wordt weer gegeven. Vervolgens moet er een ander berichtvenster dat lijkt op "Document IDispatch = 0043bf8c." Ten slotte ziet u een berichtvenster waarin wordt gemeld dat u de naam van het document waarin deze is ingevoegd.

Eigenschappen

Artikel ID: 190985 - Laatste beoordeling: zaterdag 26 februari 2011 - Wijziging: 2.0
De informatie in dit artikel is van toepassing op:
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Office Word 2007
  • Microsoft Word 2000 Standard Edition
  • Microsoft Office Excel 2007
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
Trefwoorden: 
kbautomation kbhowto kbmt KB190985 KbMtnl
Automatisch vertaald artikel
BELANGRIJK: Dit artikel is vertaald door de vertaalmachine software van Microsoft in plaats van door een professionele vertaler. Microsoft biedt u professioneel vertaalde artikelen en artikelen vertaald door de vertaalmachine, zodat u toegang heeft tot al onze knowledge base artikelen in uw eigen taal. Artikelen vertaald door de vertaalmachine zijn niet altijd perfect vertaald. Deze artikelen kunnen fouten bevatten in de vocabulaire, zinsopbouw en grammatica en kunnen lijken op hoe een anderstalige de taal spreekt en schrijft. Microsoft is niet verantwoordelijk voor onnauwkeurigheden, fouten en schade ontstaan door een incorrecte vertaling van de content of het gebruik ervan door onze klanten. Microsoft past continue de kwaliteit van de vertaalmachine software aan door deze te updaten.
De Engelstalige versie van dit artikel is de volgende:190985

Geef ons feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com