Làm th? nào đ? có đư?c IDispatch c?a m?t tài li?u Word ho?c Excel t? m?t OCX

D?ch tiêu đ? D?ch tiêu đ?
ID c?a bài: 190985 - Xem s?n ph?m mà bài này áp d?ng vào.
Bung t?t c? | Thu g?n t?t c?

? Trang này

TÓM T?T

Nó đư?c ph? bi?n cho m?t đi?u khi?n OLE c?n IDispatch c?a thùng ch?a c?a nó. B?n thư?ng có th? nh?n đư?c IDispatch b?ng cách s? d?ng QueryInterface() t? ngay l?p t?c có th? truy c?p giao di?n trên máy ch?, ch?ng h?n như IOleClientSite. Tuy nhiên, đ?i v?i m?t s? máy ch?, ch?ng h?n như Microsoft Excel, cách ti?p c?n này không thành công.

M?t cách khác đ? có đư?c IDispatch là b?ng cách s? d?ng GetActiveObject() API nh?n đư?c các máy ch? IDispatch t? FC. Tuy nhiên, phương pháp này đ?i h?i r?ng b?n ph?i có kh? năng đ? có đư?c CLSID ho?c ProgID c?a máy ch?. Hơn n?a, không r? t?nh hu?ng có th? x?y ra mà b?n không th? phân bi?t gi?a nhi?u trư?ng h?p c?a máy ch?.

Bài vi?t này s? d?ng m?t cách ti?p c?n đ? có đư?c IDispatch, mà làm vi?c cho c? Microsoft Excel và Microsoft Word, th?m chí khi nhi?u instances ch?y.

Các bư?c đư?c li?t kê dư?i đây cho phép b?n xây d?ng m?t đi?u khi?n mà có th? có đư?c các IDispatch c?a các thùng ch?a tài li?u đ?i tư?ng.

THÔNG TIN THÊM

Ví d? t?ng bư?c

  1. T?o ra m?t ?ng d?ng MFC ActiveX ControlWizard m?i tên là OffCntrDisp.
  2. Thêm các bi?n thành viên sau đây đ? l?p COleControl b?t ngu?n c?a b?n:
          char m_szDocName[512];
          IDispatch *m_pDocDisp;
    					
    LƯU ?: m_szDocName gi? tên tài li?u có ch?a ki?m soát c?a chúng tôi, và m_pDocDisp là giao di?n IDispatch cho tài li?u đó.

  3. Thêm sau đây vào cu?i c?a b?n COleControl có ngu?n g?c l?p h?c đ?nh ngh?a:
          // 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();
    					
    Đi?u này s? đư?c thêm đ? ghi đè lên th?c hi?n m?c đ?nh c?a COleControl IOleObject v?i MyOleObject tùy ch?nh c?a b?n.

  4. Trong COleControl b?t ngu?n l?p c?a b?n c?a nhà xây d?ng, thêm dư?i đây:
          m_pDocDisp = NULL;
  5. Ch? sau khi d?ng sau trong OffCntrDispCtl.cpp:
          IMPLEMENT_OLECTLTYPE(COffCntrDispCtrl, IDS_OFFCNTRDISP,
    
           _dwOffCntrDispOleMisc)
    					
    thêm m? sau đây:
          BEGIN_INTERFACE_MAP(COffCntrDispCtrl, COleControl)
              INTERFACE_PART(COffCntrDispCtrl, IID_IOleObject, MyOleObject)
          END_INTERFACE_MAP()
    					
    Ghi đè đi?u này, cùng v?i nh?ng s?a đ?i trong bư?c 3, lên c?a COleControl IOleObject.

  6. Ngay bên dư?i các m? đư?c thêm vào trong bư?c 5, thêm dư?i đây:
          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);
          }
    					
    Đây là nh?ng thói quen h?u ích đư?c s? d?ng sau này cho hi?n th? tin nh?n.

  7. Dán t?t c? các m? sau đây vào cu?i c?a b?n OffCntrDispCtl.cpp t?p tin:
          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);
          }
    					
    Đi?u này là c?a b?n th?c hi?n các IOleObject, mà ch? y?u delegates t?t c? các cu?c g?i c?a nó đ? th?c hi?n IOleObject COleControl m?c đ?nh, ngo?i tr? SetHostNames(). B?n b?y SetHostNames() và lưu tr? tài li?u tên nơi đi?u khi?n đư?c đưa vào.

    Th?t không may, Microsoft PowerPoint không g?i phương pháp này, do đó, ví d? này s? không làm vi?c v?i các s?n ph?m đó. Tuy nhiên, Microsoft Powerpoint là m?t máy ch? đơn-trư?ng h?p, do đó, b?n có th? s? d?ng GetActiveObject() đ? duy nh?t nh?n đư?c con tr? IDispatch.
  8. Thêm ch?c năng thành viên sau đây đ? l?p COleControl b?t ngu?n c?a b?n:
          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. Biên d?ch!
Làm theo các bư?c ti?p theo đ? th? nghi?m ki?m soát c?a b?n trong Microsoft Excel 97:
  1. B?t đ?u Microsoft Excel 97.
  2. Đưa lên các H?p công c? ki?m soát thanh công c? (trên các Xem tr?nh đơn, nh?p vào Thanh công c?).
  3. Nh?p vào bên ph?i búa & ch?a khoá bi?u tư?ng trong các H?p công c? ki?m soát thanh công c?, và ch?n đi?u khi?n m?i c?a b?n; nó nên đư?c g?i là OffCntrDisp.
  4. V? m?t h?nh ch? nh?t trong b?ng đ? chèn s? ki?m soát.K?T QU?: B?n s? th?y các ki?m soát xu?t hi?n, và không lâu sau đó, m?t h?p thư v?i "Found tài li?u trong LR." Ti?p theo, b?n s? th?y m?t thông đi?p h?p hi?n th? m?t cái g? đó tương t? như "tài li?u IDispatch = 0043bf8c." Cu?i cùng, b?n s? th?y m?t h?p thư thông báo cho b?n v? nh?ng tên c?a các tài li?u mà nó đ? đư?c n?p.
Làm theo các bư?c ti?p theo đ? th? nghi?m ki?m soát c?a b?n trong Microsoft Office Excel 2007:
  1. B?t đ?u Excel 2007.
  2. B?m vào các Nhà phát triển tab. Nếu Nhà phát triển th? không ph?i là có th? nh?n th?y trên Ribbon, làm theo các bư?c sau đ? kích ho?t tính năng tab:
    1. B?m vào các Microsoft Office Button, và sau đó nh?p vào Excel tùy ch?n.
    2. B?m vào các Ph? bi?n tab, và sau đó b?m vào đ? ch?n các Hi?n th? các nhà phát tri?n Tab trong Ribbon h?p ki?m.
    3. Nh?p vào Ok.
  3. Trong các Các điều khiển nhóm vào các Nhà phát triển tab, b?m vào Chèn.
  4. Dư?i Đi?u khi?n ActiveX, b?m B? đi?u khi?n.
  5. Trong các B? đi?u khi?n h?p tho?i h?p, b?m vào OffCntrDisp.
  6. V? m?t h?nh ch? nh?t trong b?ng đ? chèn s? ki?m soát. K?T QU? B? đi?u khi?n s? xu?t hi?n. Không lâu sau đó, m?t h?p thư có ch?a "T?m th?y tài li?u trong LR" s? xu?t hi?n. Ti?p theo, b?n s? th?y m?t h?p thư khác tương t? v?i "tài li?u IDispatch = 0043bf8c." Cu?i cùng, b?n s? th?y m?t h?p thư đó s? cho b?n bi?t tên c?a các tài li?u mà nó đ? đư?c n?p.

Thu?c tính

ID c?a bài: 190985 - L?n xem xét sau cùng: 20 Tháng Tám 2011 - Xem xét l?i: 2.0
Áp d?ng
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Office Word 2007
  • Microsoft Word 2002 Standard Edition
  • Microsoft Word 2000 Standard Edition
  • Microsoft Word 97 Standard Edition
  • Microsoft Office Excel 2007
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
T? khóa: 
kbautomation kbhowto kbmt KB190985 KbMtvi
Máy d?ch
QUAN TRỌNG: Bài vi?t này đư?c d?ch b?ng ph?n m?m d?ch máy c?a Microsoft ch? không ph?i do con ngư?i d?ch. Microsoft cung c?p các bài vi?t do con ngư?i d?ch và c? các bài vi?t do máy d?ch đ? b?n có th? truy c?p vào t?t c? các bài vi?t trong Cơ s? Ki?n th?c c?a chúng tôi b?ng ngôn ng? c?a b?n. Tuy nhiên, bài vi?t do máy d?ch không ph?i lúc nào c?ng hoàn h?o. Lo?i bài vi?t này có th? ch?a các sai sót v? t? v?ng, cú pháp ho?c ng? pháp, gi?ng như m?t ngư?i nư?c ngoài có th? m?c sai sót khi nói ngôn ng? c?a b?n. Microsoft không ch?u trách nhi?m v? b?t k? s? thi?u chính xác, sai sót ho?c thi?t h?i nào do vi?c d?ch sai n?i dung ho?c do ho?t đ?ng s? d?ng c?a khách hàng gây ra. Microsoft c?ng thư?ng xuyên c?p nh?t ph?n m?m d?ch máy này.
Nh?p chu?t vào đây đ? xem b?n ti?ng Anh c?a bài vi?t này:190985

Cung cấp Phản hồi

 

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