Zum Abrufen der IDispatch eines Excel oder Word-Dokuments aus einer OCX

SPRACHE AUSWÄHLEN SPRACHE AUSWÄHLEN
Artikel-ID: 190985 - Produkte anzeigen, auf die sich dieser Artikel bezieht
Alles erweitern | Alles schließen

Auf dieser Seite

Zusammenfassung

Es ist üblich für ein OLE-Steuerelement die IDispatch des zugehörigen Containers benötigen. Sie können die IDispatch häufig unter Verwendung von QueryInterface() sofort zugegriffen werden Schnittstellen auf dem Server wie IOleClientSite abrufen. Schlägt jedoch bei einigen Servern, wie z. B. Microsoft Excel diesen Ansatz.

Eine weitere Möglichkeit zum Abrufen der IDispatch besteht mithilfe der GetActiveObject()-API zum Abrufen des Servers IDispatch aus der ROT. Diese Methode erfordert jedoch, dass Sie die CLSID oder ProgID des Servers abrufen sein müssen. Darüber hinaus können mehrdeutige Situationen, in dem Sie mehrere Instanzen des Servers unterscheiden können nicht auftreten.

Diesem Artikel wird ein anderer Ansatz verwendet, um die IDispatch erhalten die für Microsoft Excel und Microsoft Word funktioniert, auch wenn mehrere Instanzen ausgeführt werden.

Die unten aufgeführten Schritte ermöglichen Sie ein Steuerelement erstellen, die die IDispatch des dem Container Document-Objekts abrufen können.

Weitere Informationen

Schritt nach Beispiel

  1. Erstellen Sie eine neue MFC-ActiveX-Assistent-Anwendung mit dem Namen OffCntrDisp.
  2. Fügen Sie die folgenden Membervariablen COleControl abgeleiteten Klasse hinzu:
          char m_szDocName[512];
          IDispatch *m_pDocDisp;
    					
    Hinweis : M_szDocName enthält den Namen des Dokuments mit unserem Steuerelement, und M_pDocDisp ist die IDispatch-Schnittstelle für das Dokument.

  3. Fügen Sie die folgenden am Ende ihrer Definition COleControl abgeleiteten Klasse:
          // 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();
    					
    das wird hinzugefügt, überschreiben Sie COleControl der Standardimplementierung der IOleObject mit Ihrer benutzerdefinierten MyOleObject.

  4. Fügen Sie im Konstruktor Ihrer COleControl abgeleiteten Klasse den folgenden:
          m_pDocDisp = NULL;
  5. Nur nach der folgenden Zeile in OffCntrDispCtl.cpp:
          IMPLEMENT_OLECTLTYPE(COffCntrDispCtrl, IDS_OFFCNTRDISP,
    
           _dwOffCntrDispOleMisc)
    					
    fügen Sie folgenden Code hinzu:
          BEGIN_INTERFACE_MAP(COffCntrDispCtrl, COleControl)
              INTERFACE_PART(COffCntrDispCtrl, IID_IOleObject, MyOleObject)
          END_INTERFACE_MAP()
    					
    dieser, zusammen mit den Änderungen in Schritt 3, überschreiben die COleControl IOleObject.

  6. Fügen Sie unterhalb der in Schritt 5 hinzugefügten Code Folgendes:
          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);
          }
    					
    diese nützliche Routinen, die später zum Anzeigen von Nachrichten verwendet werden.

  7. Fügen Sie den folgenden Code am Ende der OffCntrDispCtl.cpp-Datei:
          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);
          }
    					
    Dies ist Ihre Implementierung von IOleObject, größtenteils alle seine Aufrufe an die Standard-COleControl IOleObject Implementierung außer für SetHostNames() delegiert. Sie SetHostNames() auffangen und speichern den Dokumentnamen, an dem das Steuerelement eingefügt wird.

    Leider Aufrufen nicht Microsoft PowerPoint diese Methode, damit in diesem Beispiel wird mit dem Produkt funktionieren nicht. Microsoft PowerPoint ist jedoch ein Einzelinstanz-Server, so dass Sie GetActiveObject() verwenden, konnte um den IDispatch-Zeiger eindeutig zu erhalten.
  8. Fügen Sie die folgenden Memberfunktionen COleControl abgeleiteten Klasse hinzu:
          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. Kompilieren Sie!
Gehen Sie folgendermaßen nächsten So testen Sie Ihr Steuerelement in Microsoft Excel 97 vor:
  1. Starten Sie Microsoft Excel 97.
  2. Rufen Sie die Symbolleiste Steuerelement-Toolbox (klicken Sie im Menü Ansicht auf Symbolleisten ).
  3. Klicken Sie auf das ganz rechts Hammer- und Schraubenschlüsselsymbol Symbol in derSymbolleiste Steuerelement-Toolbox , und wählen Sie das neue Steuerelement; muss OffCntrDisp aufgerufen werden.
  4. Zeichnen Sie ein Rechteck in der Tabelle um das Steuerelement einzufügen. Ergebnisse : sollte das Steuerelement angezeigt werden, angezeigt und kurz danach ein Meldungsfeld mit "Dokument in ROT gefunden." Anschließend sollte ein weiteres Meldungsfeld mit ungefähr angezeigt "Dokument IDispatch = 0043bf8c." Schließlich müsste ein Meldungsfeld informiert Sie den Namen der dem Dokument, wo Sie eingefügt wurde.
Gehen Sie folgendermaßen nächsten um das Steuerelement in Microsoft Office Excel 2007 Testen vor:
  1. Starten Sie Excel 2007.
  2. Klicken Sie auf die Registerkarte Entwicklertools . Gehen Sie wenn die Registerkarte Entwickler nicht auf der Multifunktionsleiste angezeigt wird, folgendermaßen vor um die Registerkarte aktivieren
    1. Klicken Sie auf die Microsoft Office-Schaltfläche , und klicken Sie dann auf Excel-Optionen .
    2. Klicken Sie auf die Registerkarte häufig verwendet , und aktivieren Sie dann das Kontrollkästchen Developer-Registerkarte in der Multifunktionsleiste anzeigen .
    3. Klicken Sie auf OK .
  3. Klicken Sie in der Gruppe Steuerelemente auf der Registerkarte Entwickler auf Einfügen .
  4. Klicken Sie unter ActiveX-Steuerelemente auf Weitere Steuerelemente .
  5. Klicken Sie im Dialogfeld Weitere Steuerelemente auf OffCntrDisp .
  6. Zeichnen Sie ein Rechteck in der Tabelle um das Steuerelement einzufügen. Ergebnisse Das Steuerelement wird angezeigt. Kurz danach wird ein Meldungsfeld, das "Found Dokument in ROT" enthält. Anschließend sollte ein anderes Meldungsfeld, das ähnelt angezeigt "Dokument IDispatch = 0043bf8c." Schließlich müsste ein Meldungsfeld, das Sie darüber informiert den Namen der dem Dokument, wo Sie eingefügt wurde.

Eigenschaften

Artikel-ID: 190985 - Geändert am: Freitag, 30. März 2007 - Version: 5.1
Die Informationen in diesem Artikel beziehen sich auf:
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 6.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual C++ 6.0 Professional Edition
  • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft Office Word 2007
  • Microsoft Office Word 2003
  • Microsoft Word 2002 Standard Edition
  • Microsoft Word 2000 Standard Edition
  • Microsoft Word 97 Standard Edition
  • Microsoft Office Excel 2007
  • Microsoft Office Excel 2003
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
Keywords: 
kbmt kbautomation kbhowto KB190985 KbMtde
Maschinell übersetzter Artikel
Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.
Den englischen Originalartikel können Sie über folgenden Link abrufen: 190985
Microsoft stellt Ihnen die in der Knowledge Base angebotenen Artikel und Informationen als Service-Leistung zur Verfügung. Microsoft übernimmt keinerlei Gewährleistung dafür, dass die angebotenen Artikel und Informationen auch in Ihrer Einsatzumgebung die erwünschten Ergebnisse erzielen. Die Entscheidung darüber, ob und in welcher Form Sie die angebotenen Artikel und Informationen nutzen, liegt daher allein bei Ihnen. Mit Ausnahme der gesetzlichen Haftung für Vorsatz ist jede Haftung von Microsoft im Zusammenhang mit Ihrer Nutzung dieser Artikel oder Informationen ausgeschlossen.

Ihr Feedback an uns

 

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