Você está offline; aguardando reconexão
Entrar

Como obter o IDispatch de um documento Excel ou Word de um OCX

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

190985
Sumário
É comum para um controle OLE precisará IDispatch de seu recipiente. Você geralmente pode obter o IDispatch usando QueryInterface() de interfaces imediatamente acessíveis no servidor, como IOleClientSite. No entanto, para alguns servidores, como o Microsoft Excel, essa abordagem falha.

Outra maneira de obter o IDispatch é usando a API GetActiveObject() para obter o IDispatch do servidor do ROT. No entanto, este método requer que você deve poder obter CLSID ou ProgID do servidor. Além disso, ambíguas situações podem ocorrer onde você não pode distinguir entre várias instâncias do servidor.

Este artigo usa outra abordagem para obter o IDispatch, que funciona para o Microsoft Excel e Microsoft Word, mesmo quando estão executando várias instâncias.

As etapas listadas abaixo permitem que você criar um controle que pode obter o IDispatch do objeto de documento do recipiente.
Mais Informações

Exemplo da etapa por etapa

  1. Crie um novo aplicativo de MFC ActiveX WebAssistente chamado OffCntrDisp.
  2. Adicionar as seguintes variáveis membro à sua classe derivada de COleControl:
          char m_szDocName[512];      IDispatch *m_pDocDisp;					
    Observação : m_szDocName mantém o nome do documento que contém nosso controle e m_pDocDisp é a interface IDispatch para o documento.

  3. Adicione o seguinte ao final de sua definição de classe derivada 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();					
    este é adicionado ao substituir implementação de padrão da COleControl de IOleObject com seu MyOleObject personalizado.

  4. No construtor da classe seu derivado COleControl, adicione o seguinte:
          m_pDocDisp = NULL;
  5. Logo após a seguinte linha no OffCntrDispCtl.cpp:
          IMPLEMENT_OLECTLTYPE(COffCntrDispCtrl, IDS_OFFCNTRDISP,       _dwOffCntrDispOleMisc)					
    adicione o seguinte código:
          BEGIN_INTERFACE_MAP(COffCntrDispCtrl, COleControl)          INTERFACE_PART(COffCntrDispCtrl, IID_IOleObject, MyOleObject)      END_INTERFACE_MAP()					
    isso, junto com as modificações na etapa 3, substituir do COleControl IOleObject.

  6. Logo abaixo o código adicionado na etapa 5, adicione o seguinte:
          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);      }					
    são úteis rotinas usadas posteriormente para exibir mensagens.

  7. Colar todos os o código a seguir no final do seu OffCntrDispCtl.cpp arquivo:
          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);      }					
    esta é sua implementação do IOleObject, que delega todas suas chamadas para implementação de IOleObject do COleControl padrão, exceto para SetHostNames() principalmente. Você ajusta o registro SetHostNames() e armazena o nome do documento onde o controle é inserido.

    Infelizmente, o Microsoft PowerPoint não chamar esse método, para que este exemplo não trabalha com esse produto. No entanto, Microsoft PowerPoint é um servidor de single-instance, portanto, você poderia usar GetActiveObject() para obter o ponteiro IDispatch exclusivamente.
  8. Adicionar as seguintes funções de membro à sua classe derivada de 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. Compilação!
Siga estas etapas próxima para testar o controle no Microsoft Excel 97:
  1. Inicie o Microsoft Excel 97.
  2. Exibir a caixa de ferramentas de controle (no menu Exibir , clique em barras de ferramentas ).
  3. Clique no ícone extrema direita de martelo & chave inglesa na Ferramentas de controle e selecione o novo controle; ela deve ser chamada OffCntrDisp.
  4. Desenhe um retângulo na planilha para inserir o controle. resultados : você deve ver o controle aparecer e em breve posteriormente, uma caixa de mensagem com "Encontrado documento no ROT." Em seguida, você verá outra caixa de mensagem exibindo algo semelhante a "documento IDispatch = 0043bf8c." Finalmente, você verá uma caixa de mensagem informando do nome do documento onde ele foi inserido.
Siga estas etapas próxima para testar o controle no Microsoft Office Excel 2007:
  1. Inicie o Excel 2007.
  2. Clique na guia desenvolvedor . Se a guia desenvolvedor não estiver visível na faixa de opções, execute estas etapas para ativar a guia:
    1. Clique no Botão Microsoft Office e, em seguida, clique em Opções do Excel .
    2. Clique na guia popular e, em seguida, clique para selecionar a caixa de seleção Mostrar guia Desenvolvedor na faixa de opções .
    3. Clique em OK .
  3. No grupo de controles na guia Developer , clique em Inserir .
  4. Em controles ActiveX , clique em Mais controles .
  5. Na caixa de diálogo Mais controles , clique em OffCntrDisp .
  6. Desenhe um retângulo na planilha para inserir o controle. resultados O controle será exibida. Logo depois, será exibida uma caixa de mensagem que contém "Documento encontrado em ROT". Em seguida, você verá outra caixa de mensagem semelhante a "documento IDispatch = 0043bf8c." Finalmente, você verá uma caixa de mensagem que informa do nome do documento onde ele foi inserido.
GetObject XL2007

Aviso: Este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 190985 - Última Revisão: 03/30/2007 17:27:45 - Revisão: 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 KbMtpt
Comentários