2014-11-19 11 views
0

나는 이것에 붙어있어.나가는 dispinterface 회원의 DISPID 검색

주어 세 개의 변수 :

  • 객체
  • 있는 dispinterface 의해 정의 멤버의 이름 발신있는 dispinterface의 접속 객체
  • IID (있었나요)에 IDispatch*

이름을 DISPID로 어떻게 해결할 수 있습니까?

  • pDispatch->GetIDsOfNames(...) 반환 내가 (발신 인터페이스가 연결 가능한 객체에 의해 구현되지 않음) I 0 클라이언트가 아직 나가는 인터페이스에 연결 한 시나리오를 지원해야
  • 기대, 그래서 할 수 없습니다로 DISP_E_UNKNOWNNAME, 그들 중 하나에 GetIDsOfNames을 호출하기 위해 기존의 연결 지점을 열거하십시오 (나는 이것이 작동 할 지조차 확신하지 못합니다).
  • 수동 반향을 수행하려면 dispinterface의 ITypeInfo이 필요합니다. 나는 코 쿠라스의 ITypeInfo에서 이것을 얻을 수 있습니다. 그러나 pDispatch->GetTypeInfo(0, ...)IDispatch 구현의 경우 ITypeInfo을 반환하며 (설명서에 따라) 코 클라스의 경우 ITypeInfo이 아닙니다. (그리고이 객체의 IDispatch 구현에 의해 노출 된 다른 ITypeInfo의이 없습니다.) 객체가 "매우 표준"인 경우
+0

내 첫번째 생각은 있었나요를 사용하여 다음 호출 QueryInteface하는 것입니다 : 나는 오래된 TLBINF32.DLL 닷컴 유틸리티 라이브러리 (불행하게도에만 86) 내가 지금 여기에이 질문에 대한 내 대답에 대해 이야기를 사용했습니다 반환 된 dispInterface의 GetIDsofNames() ... –

+0

나가는 인터페이스는 원본 개체에 의해 구현되지 않습니다. 나가는 인터페이스 IID의 QueryInterface는 E_NOINTERFACE를 반환합니다. –

+0

그럼, 많은 일을하고 있습니다.;) ITypeInfo :: GetContainingTypeLib()를 호출하여 형식 라이브러리를 얻은 다음 원하는 typeinfo를 찾고 해당 ID를 가져올 때까지 형식 라이브러리를 반복 해 보았습니다. 그것은 짐승 같은 종류의 것 같지만, 나는 그것이 효과가 있다고 생각할 것입니다 ... –

답변

0

, 그것은 수 있어야한다.

개체/IDispatch 인터페이스에서 TLB (형식 라이브러리)를 가져올 수 있어야합니다. 타입 라이브러리에서, 모든 coclass를 검색하고,이 coclass가 구현하는 인터페이스를 얻을 수 있어야합니다. 당신은 당신이 IID를 가지고 있고, 회원을 찾아보고 관심있는 것을 얻을 수있는 인터페이스가 필요합니다.

이 기능이 작동하지 않는 경우가 많습니다. 다음은 쉘 객체로 작동하는 콘솔 샘플입니다. 더 쉽기 때문에 C#으로 작성했습니다. 그러나 괜찮은 언어로는 할 수없는 일은 없습니다. How to read COM TypeLib with C# or C++?

static void Main(string[] args) 
    { 
     // create a sample object every one has 
     object o = Activator.CreateInstance(Type.GetTypeFromProgID("shell.application")); // for example 
     TLIApplication app = new TLIApplication(); 

     // not sure, but I believe in pure COM it's calling IDispatch::GetTypeInfo & ITypeInfo::GetContainingTypeLib 
     TypeLibInfo tli = app.InterfaceInfoFromObject(o).Parent; 

     // this is the guid for DShellFolderViewEvents 
     int dispid = GetDispId(tli, new Guid("{62112AA2-EBE4-11CF-A5FB-0020AFE7292D}"), "SelectionChanged"); 
     Console.WriteLine("dispid:" + dispid); // should display 200 
    } 

    public static int GetDispId(TypeLibInfo tlb, Guid diid, string memberName) 
    { 
     // browse all coclasses 
     // in pure COM this is ITypeLib::GetTypeInfo 
     foreach (CoClassInfo ti in tlb.CoClasses) 
     { 
      // browse all interfaces in those coclasses 
      // in pure COM this is ITypeInfo::GetRefTypeOfImplType 
      foreach (InterfaceInfo itf in ti.Interfaces) 
      { 
       // only select [source] interfaces (events) 
       // this test is optional since the diid is unique 
       // in pure COM this is ITypeInfo::GetImplTypeFlags 
       if (((ImplTypeFlags)itf.AttributeMask & ImplTypeFlags.IMPLTYPEFLAG_FSOURCE) != ImplTypeFlags.IMPLTYPEFLAG_FSOURCE) 
        continue; 

       if (new Guid(itf.GUID) == diid) 
       { 
        // in pure COM this is ITypeInfo::GetTypeAttr & ITypeInfo::GetFuncDesc 
        foreach (MemberInfo mi in itf.Members) 
        { 
         if (mi.Name == memberName) 
          return mi.MemberId; 
        } 
       } 
      } 
     } 
     return -1; 
    }