internal static ComMemberInfo MakeComMemberInfo(BasicInfo parent,
                                                        TYPEKIND typeKind,
                                                        UCOMITypeInfo typeInfo,
                                                        int index,
                                                        bool dispatch,
                                                        bool dual)
        {
            IntPtr        funcDescPtr;
            FUNCDESC      funcDesc;
            ComMemberInfo comMemberInfo = null;

            typeInfo.GetFuncDesc(index, out funcDescPtr);
            funcDesc = (FUNCDESC)Marshal.PtrToStructure(funcDescPtr, typeof(FUNCDESC));
            // from http://www.opengroup.org/onlinepubs/009899899/toc.htm
            // Table 25-43:  MEMBERID Format
            //
            // Bits Value
            // 0 - 15 Offset. Any value is permissible.
            // 16 - 21 The nesting level of this type information
            //   in the inheritance hierarchy. For example:
            //   interface mydisp : IDispatch.
            //   The nesting level of IUnknown() is 0,
            //   IDispatch is 1, and MyDisp is 2.
            // 22 - 25 Reserved. Must be zero.
            // 26 - 28 Value of the DISPID.
            // 29 TRUE if this is the member ID for a FUNCDESC; otherwise FALSE.
            // 30 - 31 Must be 01.
            // For a dispatch interface, show only those members that are
            // part of the user's definition, which is bits 16-17 == 2
            // (as above); also only if this is a MEMBERID format (bit 30 on)
            // (some members just use the low order bits and the rest
            // are empty); also show any negative member Id.
            if (!dispatch ||
//				((Int16)funcDesc.memid < 0) ||
                (funcDesc.memid & 0xFFFF) < 0 ||
                (funcDesc.memid & 0x40000000) == 0 ||
                (funcDesc.memid & 0x30000) == 0x20000)
            {
                comMemberInfo = new ComMemberInfo(parent,
                                                  typeKind,
                                                  typeInfo,
                                                  index,
                                                  dispatch,
                                                  funcDesc);
            }
            else
            {
                if (TraceUtil.If(null, TraceLevel.Verbose))
                {
                    Trace.WriteLine("MemberInfo: SKIPPING index: "
                                    + index + " memid: 0x"
                                    + funcDesc.memid.ToString("X"));
                }
            }
            typeInfo.ReleaseFuncDesc(funcDescPtr);
            return(comMemberInfo);
        }
		internal static ComMemberInfo MakeComMemberInfo(BasicInfo parent,
			TYPEKIND typeKind,
			UCOMITypeInfo typeInfo,
			int index,
			bool dispatch,
			bool dual)
		{
			IntPtr funcDescPtr;
			FUNCDESC funcDesc;
			ComMemberInfo comMemberInfo = null;
			typeInfo.GetFuncDesc(index, out funcDescPtr);
			funcDesc = (FUNCDESC)Marshal.PtrToStructure(funcDescPtr, typeof(FUNCDESC));
			// from http://www.opengroup.org/onlinepubs/009899899/toc.htm
			// Table 25-43:  MEMBERID Format
			//
			// Bits Value
			// 0 - 15 Offset. Any value is permissible.
			// 16 - 21 The nesting level of this type information
			//   in the inheritance hierarchy. For example: 
			//   interface mydisp : IDispatch. 
			//   The nesting level of IUnknown() is 0, 
			//   IDispatch is 1, and MyDisp is 2.
			// 22 - 25 Reserved. Must be zero.
			// 26 - 28 Value of the DISPID.
			// 29 TRUE if this is the member ID for a FUNCDESC; otherwise FALSE.
			// 30 - 31 Must be 01.
			// For a dispatch interface, show only those members that are
			// part of the user's definition, which is bits 16-17 == 2 
			// (as above); also only if this is a MEMBERID format (bit 30 on)
			// (some members just use the low order bits and the rest 
			// are empty); also show any negative member Id.
			if (!dispatch || 
//				((Int16)funcDesc.memid < 0) ||
			    (funcDesc.memid & 0xFFFF) < 0 ||
				(funcDesc.memid & 0x40000000) == 0 ||
				(funcDesc.memid & 0x30000) == 0x20000) {
				comMemberInfo = new ComMemberInfo(parent,
												  typeKind,
												  typeInfo,
												  index,
												  dispatch,
												  funcDesc);
			} else {
				if (TraceUtil.If(null, TraceLevel.Verbose)) {
					Trace.WriteLine("MemberInfo: SKIPPING index: " 
									+ index + " memid: 0x" 
									+ funcDesc.memid.ToString("X"));
				}
			}
			typeInfo.ReleaseFuncDesc(funcDescPtr);
			return comMemberInfo;
		}
        // Constructor from creating withing a typelib
        internal override void Setup(TypeLibrary typeLib,
                                     TYPEKIND typeKind,
                                     int index)
        {
            base.Setup(typeLib, typeKind, index);
            Init();
            _container = typeLib;
            TYPEATTR typeAttr;
            IntPtr   typeAttrPtr;

            _typeInfo.GetTypeAttr(out typeAttrPtr);
            typeAttr =
                (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr,
                                                 typeof(TYPEATTR));
            if (typeKind == TYPEKIND.TKIND_DISPATCH)
            {
                _infoType = "Dispatch Interface";
                _dispatch = true;
            }
            else
            {
                _infoType = "Interface";
            }
            if ((typeAttr.wTypeFlags & TYPEFLAGS.TYPEFLAG_FDUAL) != 0)
            {
                _infoType = "Dual Interface";
                _dispatch = true;
                _dual     = true;
            }
            // Members
            for (int i = 0; i < typeAttr.cFuncs; i++)
            {
                // Some members for a dispatch interface are not added
                // because they are the inherited members from the
                // IDispatch interface
                ComMemberInfo mi = ComMemberInfo.
                                   MakeComMemberInfo(this,
                                                     typeKind,
                                                     _typeInfo,
                                                     i,
                                                     _dispatch,
                                                     _dual);
                if (mi != null)
                {
                    _members.Add(mi);
                    _memberNames.Add(mi.NameKey, mi);
                }
            }
            // Inherited interfaces
            for (int i = 0; i < typeAttr.cImplTypes; i++)
            {
                int           href;
                int           refTypeIndex;
                UCOMITypeInfo refTypeInfo;
                UCOMITypeLib  refITypeLib;
                TypeLibrary   refTypeLib;
                try
                {
                    _typeInfo.GetRefTypeOfImplType(i, out href);
                    _typeInfo.GetRefTypeInfo(href, out refTypeInfo);
                    refTypeInfo.GetContainingTypeLib(out refITypeLib,
                                                     out refTypeIndex);
                    refTypeLib = TypeLibrary.GetTypeLib(refITypeLib);
                    ComInterfaceInfo mi =
                        ComInterfaceInfo.GetInterfaceInfo(refTypeLib,
                                                          typeAttr.typekind,
                                                          refTypeIndex);
                    if (TraceUtil.If(this, TraceLevel.Verbose))
                    {
                        Trace.WriteLine("  inherit: " + mi);
                    }
                    _members.Add(mi);
                    _parentCount += 1 + mi.ParentCount;
                    // Don't set the typelib on the member as multiple
                    // typelibs may refer to the same interface
                    mi._container = this;
                }
                catch (Exception ex)
                {
                    ErrorDialog.Show
                        (ex,
                        "Warning - this error was detected when attempting "
                        + "to find an ancestor of the interface "
                        + _name
                        + ".  This is normal in the case where the type "
                        + "library containing that interface "
                        + "is not available.  "
                        + "In other situations this might be a bug and "
                        + "should be reported.",
                        "Warning - Cannot Access Inherited Interface",
                        MessageBoxIcon.Warning);
                }
            }
            if (_dual)
            {
                _printName  = (String)_name.Clone();
                _printName += " (Dual)";
            }
            else
            {
                _printName = _name;
            }
            _typeInfo.ReleaseTypeAttr(typeAttrPtr);
        }