Excel 또는 Word 문서의 IDispatch에서 OCX 얻는 방법을

기술 자료 번역 기술 자료 번역
기술 자료: 190985 - 이 문서가 적용되는 제품 보기.
모두 확대 | 모두 축소

이 페이지에서

요약

OLE 컨트롤을 해당 컨테이너의 IDispatch 하는 데 사용됩니다. IOleClientSite 같은 서버에 즉시 액세스할 인터페이스에서 QueryInterface() 사용하여 있는 IDispatch 자주 볼 수 있습니다. 그러나 Microsoft Excel과 같은 서버에 대해 이 방법은 오류가 발생합니다.

해당 IDispatch 얻는 다른 방법은 GetActiveObject() API를 사용하여 서버의 IDispatch에서 ROT 얻을 수 있습니다. 그러나 이 방법을 사용하면 CLSID 또는 서버의 ProgID가 얻을 수 있어야 한다는 합니다. 또한, 모호한 상황에서는 간에 서버의 여러 인스턴스를 구별할 수 없는 발생할 수 있습니다.

이 문서에서는 다른 방법을 사용하여 여러 인스턴스가 실행 중인 경우에도 Microsoft Excel 및 Microsoft Word 작동하는 있는 IDispatch 가져옵니다.

아래 단계를 사용하여 컨테이너 문서 개체의 IDispatch 얻을 수 있는 컨트롤을 빌드할 수 있습니다.

추가 정보

단계 단계는 예제

  1. OffCntrDisp 라는 새 MFC ActiveX ControlWizard 응용 프로그램을 만듭니다.
  2. COleControl 파생된 클래스에 다음 멤버 변수 추가:
          char m_szDocName[512];
          IDispatch *m_pDocDisp;
    					
    참고: 우리의 컨트롤이 있는 문서의 이름을 m_szDocName 보유하고 있으며 해당 문서에 대한 IDispatch 인터페이스를 m_pDocDisp 것입니다.

  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();
    					
    이 IOleObject 사용자 지정 MyOleObject 함께 COleControl의 기본 구현을 재정의할 추가됩니다.

  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()
    					
    COleControl의 이, 3단계에서 수정 함께 재정의할 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);
          }
    					
    주로 모든 기본 COleControl IOleObject 구현 SetHostNames() 제외하고 해당 호출을 위임하는 IOleObject 구현을 입니다. SetHostNames() 트랩 및 컨트롤을 삽입할 위치를 문서 이름을 저장합니다.

    불행하게도, 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. Microsoft Excel 97 시작하십시오.
  2. 도구 위로 상태로 보기 메뉴에서 도구 모음 을 클릭합니다.
  3. 오른쪽 망치 & 렌치 아이콘을 클릭하여 해당컨트롤 도구 상자 도구 및 새 컨트롤을 선택하고, OffCntrDisp 호출해야 합니다.
  4. 시트에서 컨트롤을 삽입하려면 사각형을 그립니다. 결과: 나타나는 컨트롤이 표시되어야 합니다 및 곧 나중에 메시지 상자에 "문서 ROT에 없습니다." 그런 다음, 비슷한 무언가를 표시하는 다른 메시지 상자가 나타납니다 "문서 IDispatch 0043bf8c =." 마지막으로, 알리는 메시지 상자가 나타나야 합니다 삽입할 위치를 문서 이름.
Microsoft Office Excel 2007에서 컨트롤을 테스트하려면 다음 단계를 수행하십시오.
  1. Excel 2007을 시작하십시오.
  2. 개발 도구 탭을 클릭하십시오. 개발 도구 탭을 리본 메뉴에 표시되지 않으면 탭을 사용하려면 다음과 같이 하십시오.
    1. Office 단추 를 클릭한 다음 Excel 옵션 을 클릭하십시오.
    2. 개인 설정 탭을 클릭하고 리본 메뉴에 개발 도구 탭 표시 확인란을 선택하십시오.
    3. 확인 을 클릭하십시오.
  3. 개발 도구 탭의 컨트롤 그룹에서 삽입 을 클릭하십시오.
  4. ActiveX 컨트롤 을 에서 기타 컨트롤 을 클릭하십시오.
  5. 기타 컨트롤 대화 상자에서 OffCntrDisp 을 클릭하십시오.
  6. 시트에서 컨트롤을 삽입하려면 사각형을 그립니다. 결과 컨트롤이 나타납니다. 곧 나중에 ROT 문서의 Found 들어 있는 메시지 상자가 나타납니다. 그런 다음, 유사한 다른 메시지 상자가 나타나야 합니다 "문서 IDispatch 0043bf8c =." 마지막으로, 알리는 메시지 상자가 나타납니다 삽입할 위치를 문서 이름.

속성

기술 자료: 190985 - 마지막 검토: 2007년 3월 30일 금요일 - 수정: 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 KbMtko
기계 번역된 문서
중요: 본 문서는 전문 번역가가 번역한 것이 아니라 Microsoft 기계 번역 소프트웨어로 번역한 것입니다. Microsoft는 번역가가 번역한 문서 및 기계 번역된 문서를 모두 제공하므로 Microsoft 기술 자료에 있는 모든 문서를 한글로 접할 수 있습니다. 그러나 기계 번역 문서가 항상 완벽한 것은 아닙니다. 따라서 기계 번역 문서에는 마치 외국인이 한국어로 말할 때 실수를 하는 것처럼 어휘, 구문 또는 문법에 오류가 있을 수 있습니다. Microsoft는 내용상의 오역 또는 Microsoft 고객이 이러한 오역을 사용함으로써 발생하는 부 정확성, 오류 또는 손해에 대해 책임을 지지 않습니다. Microsoft는 이러한 문제를 해결하기 위해 기계 번역 소프트웨어를 자주 업데이트하고 있습니다.

피드백 보내기

 

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