Al momento sei offline in attesa che la connessione Internet venga ristabilita

Come ottenere IDispatch di un documento di Excel o Word da un OCX

Il presente articolo è stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell’utente. Tuttavia, un articolo tradotto in modo automatico non è sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, più o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non è la sua. Microsoft non è responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell’utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.

Clicca qui per visualizzare la versione originale in inglese dell’articolo: 190985
Sommario
È pratica comune per un controllo OLE necessario IDispatch del relativo contenitore. È possibile ottenere spesso IDispatch utilizzando le interfacce immediatamente accessibili sul server, ad esempio IOleClientSite QueryInterface(). Tuttavia, per alcuni server, ad esempio Microsoft Excel, questo approccio grado.

Un altro modo per ottenere IDispatch consiste nell'utilizzare l'API GetActiveObject() per ottenere IDispatch del server da tabella ROT. Tuttavia, questo metodo richiede che è necessario ottenere il CLSID o ProgID del server. Inoltre, situazioni ambigue possono verificarsi in cui non è possibile distinguere tra più istanze del server.

In questo articolo viene utilizzato un altro approccio per ottenere il IDispatch, che funziona per Microsoft Excel e Microsoft Word, anche quando sono in esecuzione più istanze.

La procedura descritta di seguito consentono di creare un controllo che è possibile ottenere IDispatch dell'oggetto Document del contenitore.
Informazioni

Esempio di Step By Step

  1. Consente di creare una nuova applicazione della creazione guidata controllo ActiveX di MFC denominata OffCntrDisp.
  2. Aggiungere le seguenti variabili membro alla classe derivata da COleControl:
          char m_szDocName[512];      IDispatch *m_pDocDisp;					
    Nota : m_szDocName contiene il nome del documento contenente il controllo e m_pDocDisp è l'interfaccia IDispatch per il documento.

  3. Aggiungere quanto segue alla fine della definizione di classe derivata da COleControl:
          // 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();					
    questo viene aggiunto a eseguire l'override di implementazione predefinita di COleControl di IOleObject con il MyOleObject personalizzato.

  4. Nel costruttore della classe derivata da COleControl, aggiungere quanto segue:
          m_pDocDisp = NULL;
  5. Subito dopo la riga seguente in OffCntrDispCtl.cpp:
          IMPLEMENT_OLECTLTYPE(COffCntrDispCtrl, IDS_OFFCNTRDISP,       _dwOffCntrDispOleMisc)					
    aggiungere il seguente codice:
          BEGIN_INTERFACE_MAP(COffCntrDispCtrl, COleControl)          INTERFACE_PART(COffCntrDispCtrl, IID_IOleObject, MyOleObject)      END_INTERFACE_MAP()					
    questa, insieme con le modifiche nel passaggio 3, override di COleControl IOleObject.

  6. Sotto il codice aggiunto nel passaggio 5, aggiungere quanto segue:
          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);      }					
    i sono routine utile utilizzate in seguito per la visualizzazione dei messaggi.

  7. Incollare tutto il codice seguente alla fine di OffCntrDispCtl.cpp il file:
          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);      }					
    questa è dell'implementazione di IOleObject, che delega principalmente tutte le chiamate all'implementazione di IOleObject di COleControl predefinito, ad eccezione di SetHostNames(). È possibile intercettare SetHostNames() e memorizzare in cui il controllo viene inserito il nome del documento.

    Sfortunatamente, Microsoft PowerPoint non chiamare questo metodo, in modo che in questo esempio non funziona con tale prodotto. Tuttavia, Microsoft PowerPoint è un server a istanza singola, pertanto è Impossibile utilizzare GetActiveObject() per ottenere in modo univoco il puntatore IDispatch.
  8. Aggiungere le seguenti funzioni membro alla classe derivata da 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. Compilazione!
Attenersi alla seguente procedura successiva per testare il controllo in Microsoft Excel 97:
  1. Avviare Microsoft Excel 97.
  2. Visualizzare la barra degli strumenti Strumenti di controllo (scegliere barre degli strumenti dal menu Visualizza ).
  3. Fare clic sull'icona di martello e una chiave inglese estrema destra nel Strumenti di controllo, selezionare il nuovo controllo e deve essere chiamato OffCntrDisp.
  4. Disegnare un rettangolo nella pagina per inserire il controllo. i risultati : È necessario visualizzare il controllo visualizzato e poco successivamente, una finestra di messaggio con "Trovato documento nella tabella ROT." Successivamente, verrà visualizzata un'altra finestra di messaggio visualizzato qualcosa di simile a "documento IDispatch = 0043bf8c." Infine, verrà visualizzata una finestra di messaggio che informa del nome del documento in cui è stato inserito.
Attenersi alla seguente procedura successiva per testare il controllo in Microsoft Office Excel 2007:
  1. Avviare Excel 2007.
  2. Fare clic sulla scheda Developer . Se la scheda sviluppo non è visibile sulla barra multifunzione, attenersi alla seguente procedura per attivare la scheda:
    1. Fare clic sul Pulsante Microsoft Office e quindi fare clic su Opzioni di Excel .
    2. Fare clic sulla scheda Impostazioni generali e quindi fare clic su per selezionare la casella di controllo Mostra Developer scheda della barra multifunzione .
    3. Fare clic su OK .
  3. Nel gruppo controlli nella scheda Developer , fare clic su Inserisci .
  4. Nella sezione controlli ActiveX , fare clic su Altri controlli .
  5. Nella finestra di dialogo Altri controlli , fare clic su OffCntrDisp .
  6. Disegnare un rettangolo nella pagina per inserire il controllo. risultati Il controllo verrà visualizzato. Al più presto in seguito, verrà visualizzata una finestra di messaggio che contiene "Documento trovato nella tabella ROT". Successivamente, è visualizzata un'altra finestra di messaggio analogo a "documento IDispatch = 0043bf8c." Infine, verrà visualizzata una finestra di messaggio che informa del nome del documento in cui è stato inserito.
GetObject XL2007

Warning: This article has been translated automatically

Proprietà

ID articolo: 190985 - Ultima revisione: 03/30/2007 17:27:45 - Revisione: 5.1

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

  • kbmt kbautomation kbhowto KB190985 KbMtit
Feedback