現在オフラインです。再接続するためにインターネットの接続を待っています

お使いのブラウザーはサポートされていません

このサイトを利用するには、ブラウザーを更新する必要があります。

Internet Explorer を最新バージョンに更新する

Excel ファイルまたは Word 文書の IDispatch を OCX から取得する方法

Office 2003 のサポートは終了しました

マイクロソフトでは、2014 年 4 月 8 日に Office 2003 のサポートを終了しました。この変更は、ソフトウェアの更新プログラムおよびセキュリティ オプションに影響しています。 この変更の意味および保護された状態を維持する方法について説明します。

概要
OLE コントロールは自身のコンテナの IDispatch を必要とすることがよくあります。多くの場合、IDispatch を取得するには、サーバーにある IOleClientSite など、即座にアクセスできるインターフェイスから QueryInterface() を使用します。ただし、Microsoft Excel など、一部のサーバーでは、このアプローチは失敗します。

IDispatch を取得するもう 1 つの方法は、GetActiveObject() API を使用して、ROT からサーバーの IDispatch を取得する方法です。ただし、この方法を使用するには、サーバーの CLSID または ProgID を取得する必要があります。さらに、サーバーの複数のインスタンスを互いに区別できない、あいまいな状況が発生することがあります。

この資料では、別のアプローチを使用して IDispatch を取得します。このアプローチは、複数のインスタンスを実行している場合でも、Microsoft Excel と Microsoft Word のどちらでも機能します。

以下に記載されている手順を使用して、コンテナの Document オブジェクトの IDispatch を取得するコントロールをビルドできます。
詳細

手順の例

  1. OffCntrDisp という名前で新しい MFC ActiveX ControlWizard アプリケーションを作成します。
  2. 以下のメンバ変数を COleControl 派生クラスに追加します。
          char m_szDocName[512];      IDispatch *m_pDocDisp;					
    : m_szDocName はコントロールを含んでいるドキュメントの名前を保持します。m_pDocDisp はそのドキュメントの IDispatch インターフェイスです。

  3. 以下のコードを 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();					
    このコードは、COleControl の、IOleObject のデフォルトの実装を、ユーザーのカスタム MyOleObject でオーバーライドするために追加されます。

  4. COleControl 派生クラスのコンストラクタに、以下のコードを追加します。
          m_pDocDisp = NULL;
  5. OffCntrDispCtl.cpp の次の行のすぐ後にコードを追加します。
          IMPLEMENT_OLECTLTYPE(COffCntrDispCtrl, IDS_OFFCNTRDISP,       _dwOffCntrDispOleMisc)					
    上記のコードの後に次のコードを追加します。
          BEGIN_INTERFACE_MAP(COffCntrDispCtrl, COleControl)          INTERFACE_PART(COffCntrDispCtrl, IID_IOleObject, MyOleObject)      END_INTERFACE_MAP()					
    このコードは、手順 3. での変更と共に、COleControl の IOleObject をオーバーライドします。

  6. 手順 5. で追加したコードのすぐ下に、以下のコードを追加します。
          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);      }					
    これらのコードは、メッセージを表示するために後で使用する、便利なルーチンです。

  7. 以下のすべてのコードを OffCntrDispCtl.cpp ファイルの末尾に貼り付けます。
          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);      }					
    このコードは IOleObject の実装であり、多くの場合、呼び出しをデフォルトの COleControl の IOleObject の実装にデリゲートします。ただし、SetHostNames() は例外です。SetHostNames() をトラップし、コントロールの挿入先ドキュメント名を格納します。

    残念なことに、Microsoft PowerPoint はこのメソッドを呼び出さないので、この例は Microsoft PowerPoint では機能しません。ただし、Microsoft PowerPoint は単一インスタンスのサーバーなので、GetActiveObject() を使用して一意に IDispatch ポインタを取得できます。
  8. 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. コンパイルを行います。
Microsoft Excel 97 で、以下の手順に従ってコントロールをテストします。
  1. Excel 97 を起動します。
  2. [コントロール ツールボックス] ツール バーを表示します ([表示] メニューで、[ツール バー] をクリックします)。
  3. [コントロール ツールボックス] ツール バーの右端にあるハンマーとレンチのアイコンをクリックし、OffCntrDisp という名前の新しいコントロールを選択します。
  4. シートに四角形を描画し、コントロールを挿入します。

    結果 : コントロールが表示され、その後間もなく、"Found document in ROT" というメッセージを示すメッセージ ボックスが表示されます。次に、もう 1 つのメッセージ ボックスが表示され、"Document IDispatch = 0043bf8c." に近いメッセージが表示されます。最後に、コントロールを挿入したドキュメントの名前を知らせるメッセージ ボックスが表示されます。
Microsoft Office Excel 2007 で、以下の手順に従ってコントロールをテストします。
  1. Excel 2007 を起動します。
  2. [開発] タブをクリックします。[開発] タブがリボンに表示されない場合は、次の手順を実行してタブを表示します。
    1. Microsoft Office ボタンをクリックし、[Excel のオプション] をクリックします。
    2. [基本設定] タブをクリックし、[[開発] タブをリボンに表示する] チェック ボックスをオンにします。
    3. [OK] をクリックします。
  3. [開発] タブの [コントロール] で、[挿入] をクリックします。
  4. [ActiveX コントロール] で、[コントロールの選択] をクリックします。
  5. [コントロールの選択] ダイアログ ボックスで、[OffCntrDisp] をクリックし、[OK] をクリックします。
  6. シートに四角形を描画し、コントロールを挿入します。

    結果 : コントロールが表示され、その後間もなく、"Found document in ROT" というメッセージが記載されたメッセージ ボックスが表示されます。次に、もう 1 つのメッセージ ボックスが表示され、"Document IDispatch = 0043bf8c." に近いメッセージが表示されます。最後に、コントロールを挿入したドキュメントの名前を知らせるメッセージ ボックスが表示されます。
getobject XL2007
プロパティ

文書番号:190985 - 最終更新日: 06/14/2007 02:16:00 - リビジョン: 5.0

  • 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
  • Microsoft Word 2000
  • 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
  • kbhowto kbautomation KB190985
フィードバック
0&did=1&t=">t" src="https://c.microsoft.com/ms.js"> + (window.location.protocol) + "//c.microsoft.com/ms.js'><\/script>");