Bạn hiện đang ngoại tuyến, hãy chờ internet để kết nối lại

Làm thế nào để có được IDispatch của một tài liệu Word hoặc Excel từ một OCX

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
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ạnthường có thể nhận được IDispatch bằng cách sử dụng QueryInterface() từ ngay lập tứccó thể truy cập giao diện trên máy chủ, chẳng hạn như IOleClientSite. Tuy nhiên, đối vớimộ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() APInhận được các máy chủ IDispatch từ FC. Tuy nhiên, phương pháp này đòi hỏi rằngbạ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ềutrườ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 chocả Microsoft Excel và Microsoft Word, thậm chí khi nhiều instanceschạ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ácIDispatch 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.
getobject XL2007

Cảnh báo: Bài viết này được dịch tự động

Thuộc tính

ID Bài viết: 190985 - Xem lại Lần cuối: 08/20/2011 06:57:00 - Bản sửa đổi: 2.0

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

  • kbautomation kbhowto kbmt KB190985 KbMtvi
Phản hồi
>