internal static Object MakeLinkModifier(BasicInfo basicInfo)
		{
			if (basicInfo._helpFile == null)
				return null;
			
			return new HelpLinkItem(basicInfo._helpFile, basicInfo._helpContext);
		}
        internal ComCatTreeNode(BasicInfo category) : base()
		{
            _catInfo = category;
            _allClasses = new SortedList();
            SetPresInfo(PresentationMap.COM_FOLDER_CLASS);
            PostConstructor();
		}
        internal ComMemberTreeNode(BasicInfo memberInfo) : base()
		{
            _memberInfo = memberInfo;
            _memberInfo.TreeNode = this;

            SetPresInfo(_memberInfo.PresInfo);

            PostConstructor();
		}
		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;
		}
 // Used to get the basic info that is used by this type
 // of node
 protected override Object ProcessChild(RegistryKey key,
                                           String subKeyName)
 {
     BasicInfo info = new BasicInfo(key, subKeyName);
     foreach (String valueName in key.GetValueNames())
         {
             if (valueName != null && 
                 !valueName.Equals("") && 
                 info.Name == null)
                 info.Name = (String)key.GetValue(valueName);
         }
     if (info.Name == null)
     {
         info.Name = subKeyName;
         info.PrintName = subKeyName + " (guid)";
     }
     info._infoType = "Category";
     return info;
 }
        internal ComTypeTreeNode(BasicInfo basicInfo,
                                 String progId) : base(basicInfo)
		{
            _progId = progId;

            // We only allow classes to be dragged
            if (_memberInfo._typeKind == TYPEKIND.TKIND_COCLASS)
                _isDragSource = true;

            _onDesignSurface = true;

            if (_memberInfo.PresInfo != null)
            {
                _intermediateNodeTypes = new ArrayList();
                _intermediateNodeTypes.Add
                    (_memberInfo.PresInfo._intermediateNodeType);
            }

            PostConstructor();
		}
        internal ComMemberInfo(BasicInfo parent,
                               TYPEKIND typeKind,
                               UCOMITypeInfo typeInfo,
                               int index,
                               bool dispatch,
                               FUNCDESC funcDesc) :
            base(typeInfo)
        {
            int actLen;

            String[] memberNames = new String[100];
            _typeInfo.GetNames(funcDesc.memid, memberNames,
                               memberNames.Length,
                               out actLen);

            _memberId = funcDesc.memid;
            // the high order part of the memberId is flags
            // for a dispatch interface
            if (dispatch)
            {
                _memberId &= 0xffff;
                // Make sure we get a 16 bit integer so that negative
                // DISPIDs show up correctly
                _memberId = (Int16)_memberId;
            }
            String docString;

            // Note, use the original unmasked memberId
            _typeInfo.GetDocumentation(funcDesc.memid, out _name,
                                       out docString, out _helpContext,
                                       out _helpFile);
            // Set using property so that nulls are checked
            DocString   = docString;
            _parameters = new ArrayList();
            _typeLib    = parent.TypeLib;
            _index      = index;
            _container  = parent;
            _printName  = _name;
            _nameKey    = (String)_name;
            // Add the DISPID to the dispatch interfaces
            if (dispatch)
            {
                _dispatch   = true;
                _printName += " - " + _memberId;
            }
            if (TraceUtil.If(this, TraceLevel.Verbose))
            {
                Trace.WriteLine("MemberInfo: " + _name);
            }
            _type = TypeLibUtil.TYPEDESCToString
                        (_typeLib,
                        _typeInfo,
                        funcDesc.elemdescFunc.tdesc,
                        TypeLibUtil.COMTYPE);
            if (funcDesc.invkind == INVOKEKIND.INVOKE_FUNC)
            {
                _infoType = "Function";
                _property = false;
                if (funcDesc.cParams > 0)
                {
                    AddParams(funcDesc, memberNames, funcDesc.cParams);
                }
            }
            else
            {
                if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYGET)
                {
                    _printName += " (get)";
                    _nameKey   += NAMEKEY_GET;
                }
                else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUT)
                {
                    _printName += " (put)";
                    _nameKey   += NAMEKEY_SET;
                }
                else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUTREF)
                {
                    _printName += " (put ref)";
                    _nameKey   += NAMEKEY_SETREF;
                }
                _infoType = "Property";
                _property = true;
            }
            _flagsString = FlagsString((FUNCFLAGS)funcDesc.wFuncFlags);
            if (_property)
            {
                _presInfo = PresentationMap.
                            GetInfo(PresentationMap.COM_PROPERTY);
            }
            else
            {
                _presInfo = PresentationMap.
                            GetInfo(PresentationMap.COM_METHOD);
            }
        }
		// Applies to classes and interface, and since we don't have
		// a common superclass, just put it here and make it static
		internal static CodeTypeDeclaration CreateTypeCodeDom
			(BasicInfo basicInfo,
			ArrayList interfaces,
			bool doClass)
		{
			CodeTypeDeclaration codeDom = new CodeTypeDeclaration();
			Guid useGuid = basicInfo._guid;
			if (basicInfo is ComClassInfo && doClass)
			{
				codeDom.Name = basicInfo.Name + "Class";
				codeDom.IsInterface = false;
			}
			else
			{
				// Use the default interface's class if we are generating
				// the interface for the class
				if (basicInfo is ComClassInfo)
					useGuid = ((ComClassInfo)basicInfo).DefaultInterface._guid;
				codeDom.Name = basicInfo.Name;
				codeDom.IsInterface = true;
				if (basicInfo is ComInterfaceInfo)
				{
					ComInterfaceInfo ifaceInfo = (ComInterfaceInfo)basicInfo;
					ComInterfaceType ifaceType;
					if (ifaceInfo._dual)
						ifaceType = ComInterfaceType.InterfaceIsDual;
					else if (ifaceInfo._dispatch)
						ifaceType = ComInterfaceType.InterfaceIsIDispatch;
					else 
						ifaceType = ComInterfaceType.InterfaceIsIUnknown;
					// Add InterfaceType attribute
					CodeAttributeArgument ifaceTypeArg = new CodeAttributeArgument();
					ifaceTypeArg.Value = new CodeSnippetExpression
						("(System.Runtime.InteropServices.ComInterfaceType)" 
						+ (int)ifaceType);
					codeDom.CustomAttributes.Add
						(new CodeAttributeDeclaration
							("System.Runtime.InteropServices.InterfaceType",
							new CodeAttributeArgument[] { ifaceTypeArg }));
				}
			}
			// Add Guid attribute
			CodeAttributeArgument guidArg = new CodeAttributeArgument();
			// The _guidStr has braces which the attribute can't handle
			guidArg.Value = new CodePrimitiveExpression
				(useGuid.ToString());
			codeDom.CustomAttributes.Add
				(new CodeAttributeDeclaration
					("System.Runtime.InteropServices.Guid",
					new CodeAttributeArgument[] { guidArg }));
			if (basicInfo is ComClassInfo)
			{
				ComClassInfo classInfo = (ComClassInfo)basicInfo;
				if (doClass)
				{
					codeDom.TypeAttributes |= TypeAttributes.Abstract;
					// Class inherits from the interface of the same name
					codeDom.BaseTypes.Add
						(new CodeTypeReference(basicInfo.Name));
					// Add TypeLibType attribute
					CodeAttributeArgument typeLibTypeArg = new CodeAttributeArgument();
					typeLibTypeArg.Value = new CodePrimitiveExpression
						((int)classInfo._typeFlags);
					codeDom.CustomAttributes.Add
						(new CodeAttributeDeclaration
							("System.Runtime.InteropServices.TypeLibType",
							new CodeAttributeArgument[] { typeLibTypeArg }));
					// Add ClassInterface attribute
					CodeAttributeArgument classIfaceArg = new CodeAttributeArgument();
					classIfaceArg.Value = new CodeSnippetExpression("(short)0");
					codeDom.CustomAttributes.Add
						(new CodeAttributeDeclaration
							("System.Runtime.InteropServices.ClassInterface",
							new CodeAttributeArgument[] { classIfaceArg }));
					// Make the no-arg constructor public (default cons 
					// visibility is family)
					CodeConstructor cons = new CodeConstructor();
					cons.Attributes = MemberAttributes.Public;
					codeDom.Members.Add(cons);
				}
				else
				{
					// Add CoClass attribute
					CodeAttributeArgument typeArg = new CodeAttributeArgument();
					typeArg.Value = new CodeTypeReferenceExpression
						(new CodeTypeReference("typeof("
											  + basicInfo.GetCLRTypeName()
											   + ")"));
					codeDom.CustomAttributes.Add
						(new CodeAttributeDeclaration
							("System.Runtime.InteropServices.CoClass",
							new CodeAttributeArgument[] { typeArg }));
				}
			}
			if (TraceUtil.If(basicInfo, TraceLevel.Info))
			{
				Trace.WriteLine(basicInfo, "CG - " 
								+ basicInfo.Name);
			}
			bool firstTime = true;
			// Add inherited interfaces
			foreach (BasicInfo member in interfaces)
			{
				if (member is ComInterfaceInfo)
				{
					// FIXME - should probably compare these by GUID
					if (member.Name.Equals("IUnknown") ||
						member.Name.Equals("IDispatch"))
						continue;
					codeDom.BaseTypes.Add
						(new CodeTypeReference(member.Name));
					// Add the members for the class or interface, 
					// its all of the members
					// of each implemented interface
					if ((!codeDom.IsInterface && doClass) || 
						codeDom.IsInterface)
					{
						// Qualify subsequent interfaces with the
						// interface name
						// Unless this is an interface, then just
						// leave the name alone
						if (firstTime || codeDom.IsInterface)
						{
							AddMembers(codeDom, member.Members, null);
						}
						else
						{
							AddMembers(codeDom, member.Members, 
									  member.Name + "_");
						}
					}
					firstTime = false;
				}
			}
			// Don't add the members for the class interface
			if (basicInfo is ComClassInfo && !doClass)
				return codeDom;
			// Add members for this interface (a class has none)
			AddMembers(codeDom, basicInfo.Members, null);
			return codeDom;
		}
		internal ComMemberInfo(BasicInfo parent,
							   TYPEKIND typeKind,
							   UCOMITypeInfo typeInfo,
							   int index,
							   bool dispatch,
							   FUNCDESC funcDesc) :
				base(typeInfo)
		{
			int actLen;
			String[] memberNames = new String[100];
			_typeInfo.GetNames(funcDesc.memid, memberNames, 
							   memberNames.Length, 
							   out actLen);
						
			_memberId = funcDesc.memid;
			// the high order part of the memberId is flags
			// for a dispatch interface
			if (dispatch)
			{
				_memberId &= 0xffff;
				// Make sure we get a 16 bit integer so that negative
				// DISPIDs show up correctly
				_memberId = (Int16)_memberId;
			}
			String docString;
			// Note, use the original unmasked memberId
			_typeInfo.GetDocumentation(funcDesc.memid, out _name, 
									   out docString, out _helpContext, 
									   out _helpFile);
			// Set using property so that nulls are checked
			DocString = docString;
			_parameters = new ArrayList();
			_typeLib = parent.TypeLib;
			_index = index;
			_container = parent;
			_printName = _name;
			_nameKey = (String)_name;
			// Add the DISPID to the dispatch interfaces
			if (dispatch)
			{
				_dispatch = true;
				_printName += " - " + _memberId;
			}
			if (TraceUtil.If(this, TraceLevel.Verbose))
				Trace.WriteLine("MemberInfo: " + _name);
			_type = TypeLibUtil.TYPEDESCToString
				(_typeLib,
				 _typeInfo,
				 funcDesc.elemdescFunc.tdesc,
				 TypeLibUtil.COMTYPE);
			if (funcDesc.invkind == INVOKEKIND.INVOKE_FUNC)
			{
				_infoType = "Function";
				_property = false;
				if (funcDesc.cParams > 0)
				{
					AddParams(funcDesc, memberNames, funcDesc.cParams);
				}
			}
			else
			{
				if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYGET)
				{
					_printName += " (get)";
					_nameKey += NAMEKEY_GET;
				}
				else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUT)
				{
					_printName += " (put)";
					_nameKey += NAMEKEY_SET;
				}
				else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUTREF)
				{
					_printName += " (put ref)";
					_nameKey += NAMEKEY_SETREF;
				}
				_infoType = "Property";
				_property = true;
			}
			_flagsString = FlagsString((FUNCFLAGS)funcDesc.wFuncFlags);
			if (_property)
			{
				_presInfo = PresentationMap.
					GetInfo(PresentationMap.COM_PROPERTY);
			}
			else
			{
				_presInfo = PresentationMap.
					GetInfo(PresentationMap.COM_METHOD);
			}
		}
Exemple #10
0
        internal ComVariableInfo(BasicInfo parent,
                                 TYPEKIND typeKind,
                                 UCOMITypeInfo typeInfo,
                                 int index) : base(typeInfo)
        {
            IntPtr          varDescPtr;
            CORRECT_VARDESC varDesc;

            _typeKind  = typeKind;
            _typeLib   = parent.TypeLib;
            _container = parent;
            _index     = index;

            _typeInfo.GetVarDesc(_index, out varDescPtr);
            varDesc = (CORRECT_VARDESC)
                      Marshal.PtrToStructure(varDescPtr,
                                             typeof(CORRECT_VARDESC));

            int actLen;

            String[] memberNames = new String[100];
            _typeInfo.GetNames(varDesc.memid, memberNames,
                               memberNames.Length,
                               out actLen);

            Name = memberNames[0];

            if (TraceUtil.If(this, TraceLevel.Verbose))
            {
                Trace.WriteLine("VariableInfo: " + _name);
            }
            if (_typeKind == TYPEKIND.TKIND_ENUM)
            {
                _infoType = "Constant";
                try
                {
                    Object value = Marshal.GetObjectForNativeVariant
                                       (varDesc.u.lpvarValue);
                    _enumValue = value.ToString();
                }
                catch (Exception ex)
                {
                    _enumValue = "Unknown variant: 0x"
                                 + varDesc.u.lpvarValue.ToInt32().ToString("X");
                    TraceUtil.WriteLineWarning(this,
                                               "Exception reading enum value: " + ex);
                }
            }
            else
            {
                _infoType = "Variable";
            }

            TYPEDESC typeDesc = varDesc.elemdescVar.tdesc;

            _varType = TypeLibUtil.TYPEDESCToString
                           (_typeLib,
                           _typeInfo,
                           typeDesc,
                           TypeLibUtil.COMTYPE);

            _typeInfo.ReleaseVarDesc(varDescPtr);

            _presInfo = PresentationMap.
                        GetInfo(PresentationMap.COM_VARIABLE);
        }
        // Returns the index of this object's type in the typelib
        protected int GetTypeLib(IntPtr dispPtr)
        {
            if (TraceUtil.If(this, TraceLevel.Info))
            {
                Trace.WriteLine("ComObjInfo::GetTypeLib: "
                                + _obj + " type: " + _obj.GetType());
            }
            if (_typeLib != null)
            {
                return(-1);
            }
            UCOMITypeLib iTypeLib;
            int          index = -1;

            try
            {
                IDispatch idisp = (IDispatch)
                                  Marshal.GetObjectForIUnknown(dispPtr);
                int count;
                int result = idisp.GetTypeInfoCount(out count);
                if (result != 0)
                {
                    TraceUtil.WriteLineWarning
                        (typeof(ComObjectInfo),
                        "ComObjInfo - "
                        + "GetTypeInfoCount failed: 0x"
                        + result.ToString("x") + " obj: " + _obj);
                    throw new COMException("(probably a bug, please report) "
                                           + "Failed on GetTypeInfoCount",
                                           result);
                }
                if (count == 0)
                {
                    TraceUtil.WriteLineWarning
                        (typeof(ComObjectInfo),
                        "ComObjInfo - "
                        + " typeinfo count = 0: " + _obj);
                    throw new Exception("This object has no type information "
                                        + "(GetTypeInfoCount returned 0).  ");
                }
                result = idisp.GetTypeInfo(0, 0, out _typeInfo);
                if (result != 0)
                {
                    TraceUtil.WriteLineWarning(typeof(ComObjectInfo),
                                               "ComObjInfo - "
                                               + "typeInfo not found:" + _obj);
                    throw new COMException("(probably a bug, please report) "
                                           + "Failed to get ITypeInfo",
                                           result);
                }
                if (_typeInfo == null)
                {
                    TraceUtil.WriteLineWarning(typeof(ComObjectInfo),
                                               "ComObjInfo - "
                                               + "typeInfo not found:" + _obj);
                    throw new Exception("(probably a bug, please report) "
                                        + "Null TypeInfo pointer returned");
                }
                // Now we can get the type library information using these
                // nice interfaces provided as part of the interop services
                _typeInfo.GetContainingTypeLib(out iTypeLib, out index);
                _typeLib = TypeLibrary.GetTypeLib(iTypeLib);
            }
            catch (Exception ex)
            {
                if (_typeInfo != null)
                {
                    Guid guid = BasicInfo.GuidFromTypeInfo(_typeInfo);
                    TraceUtil.WriteLineWarning(typeof(ComObjectInfo),
                                               "ComObjInfo (type "
                                               + guid + ")");
                }
                TraceUtil.WriteLineWarning(typeof(ComObjectInfo),
                                           "Containing typelib not found:"
                                           + ex);
                throw new Exception("Cannot get TypeLib for object.  "
                                    + "Getting the TypeLib information for "
                                    + "an object is required as this contains "
                                    + "the type information used to display "
                                    + "the object. ", ex);
            }
            if (TraceUtil.If(this, TraceLevel.Info))
            {
                Trace.WriteLine("ComObjInfo - containing typelib index: "
                                + index);
            }
            return(index);
        }
		internal ComVariableInfo(BasicInfo parent,
								 TYPEKIND typeKind,
								 UCOMITypeInfo typeInfo,
								 int index) : base(typeInfo)
		{
			IntPtr varDescPtr;
			CORRECT_VARDESC varDesc;

			_typeKind = typeKind;
			_typeLib = parent.TypeLib;
			_container = parent;
			_index = index;

			_typeInfo.GetVarDesc(_index, out varDescPtr);
			varDesc = (CORRECT_VARDESC)
				Marshal.PtrToStructure(varDescPtr, 
									   typeof(CORRECT_VARDESC));

			int actLen;
			String[] memberNames = new String[100];
			_typeInfo.GetNames(varDesc.memid, memberNames, 
							   memberNames.Length, 
							   out actLen);
						
			Name = memberNames[0];

			if (TraceUtil.If(this, TraceLevel.Verbose))
				Trace.WriteLine("VariableInfo: " + _name);
			if (_typeKind == TYPEKIND.TKIND_ENUM)
			{
				_infoType = "Constant";
				try
				{
					Object value = Marshal.GetObjectForNativeVariant
						(varDesc.u.lpvarValue);
					_enumValue = value.ToString();
				}
				catch (Exception ex)
				{
					_enumValue = "Unknown variant: 0x" 
						+ varDesc.u.lpvarValue.ToInt32().ToString("X");
					TraceUtil.WriteLineWarning(this,
											   "Exception reading enum value: " + ex);
				}
			}
			else
			{
				_infoType = "Variable";
			}

			TYPEDESC typeDesc = varDesc.elemdescVar.tdesc;
			_varType = TypeLibUtil.TYPEDESCToString
				(_typeLib,
				 _typeInfo,
				 typeDesc,
				 TypeLibUtil.COMTYPE);

			_typeInfo.ReleaseVarDesc(varDescPtr);

			_presInfo = PresentationMap.
				GetInfo(PresentationMap.COM_VARIABLE);
		}
        internal ComTypeTreeNode(BasicInfo basicInfo) : 
                this(basicInfo, null)
		{
        }
        // Applies to classes and interface, and since we don't have
        // a common superclass, just put it here and make it static
        internal static CodeTypeDeclaration CreateTypeCodeDom
            (BasicInfo basicInfo,
            ArrayList interfaces,
            bool doClass)
        {
            CodeTypeDeclaration codeDom = new CodeTypeDeclaration();
            Guid useGuid = basicInfo._guid;

            if (basicInfo is ComClassInfo && doClass)
            {
                codeDom.Name        = basicInfo.Name + "Class";
                codeDom.IsInterface = false;
            }
            else
            {
                // Use the default interface's class if we are generating
                // the interface for the class
                if (basicInfo is ComClassInfo)
                {
                    useGuid = ((ComClassInfo)basicInfo).DefaultInterface._guid;
                }
                codeDom.Name        = basicInfo.Name;
                codeDom.IsInterface = true;
                if (basicInfo is ComInterfaceInfo)
                {
                    ComInterfaceInfo ifaceInfo = (ComInterfaceInfo)basicInfo;
                    ComInterfaceType ifaceType;
                    if (ifaceInfo._dual)
                    {
                        ifaceType = ComInterfaceType.InterfaceIsDual;
                    }
                    else if (ifaceInfo._dispatch)
                    {
                        ifaceType = ComInterfaceType.InterfaceIsIDispatch;
                    }
                    else
                    {
                        ifaceType = ComInterfaceType.InterfaceIsIUnknown;
                    }
                    // Add InterfaceType attribute
                    CodeAttributeArgument ifaceTypeArg = new CodeAttributeArgument();
                    ifaceTypeArg.Value = new CodeSnippetExpression
                                             ("(System.Runtime.InteropServices.ComInterfaceType)"
                                             + (int)ifaceType);
                    codeDom.CustomAttributes.Add
                        (new CodeAttributeDeclaration
                            ("System.Runtime.InteropServices.InterfaceType",
                            new CodeAttributeArgument[] { ifaceTypeArg }));
                }
            }
            // Add Guid attribute
            CodeAttributeArgument guidArg = new CodeAttributeArgument();

            // The _guidStr has braces which the attribute can't handle
            guidArg.Value = new CodePrimitiveExpression
                                (useGuid.ToString());
            codeDom.CustomAttributes.Add
                (new CodeAttributeDeclaration
                    ("System.Runtime.InteropServices.Guid",
                    new CodeAttributeArgument[] { guidArg }));
            if (basicInfo is ComClassInfo)
            {
                ComClassInfo classInfo = (ComClassInfo)basicInfo;
                if (doClass)
                {
                    codeDom.TypeAttributes |= TypeAttributes.Abstract;
                    // Class inherits from the interface of the same name
                    codeDom.BaseTypes.Add
                        (new CodeTypeReference(basicInfo.Name));
                    // Add TypeLibType attribute
                    CodeAttributeArgument typeLibTypeArg = new CodeAttributeArgument();
                    typeLibTypeArg.Value = new CodePrimitiveExpression
                                               ((int)classInfo._typeFlags);
                    codeDom.CustomAttributes.Add
                        (new CodeAttributeDeclaration
                            ("System.Runtime.InteropServices.TypeLibType",
                            new CodeAttributeArgument[] { typeLibTypeArg }));
                    // Add ClassInterface attribute
                    CodeAttributeArgument classIfaceArg = new CodeAttributeArgument();
                    classIfaceArg.Value = new CodeSnippetExpression("(short)0");
                    codeDom.CustomAttributes.Add
                        (new CodeAttributeDeclaration
                            ("System.Runtime.InteropServices.ClassInterface",
                            new CodeAttributeArgument[] { classIfaceArg }));
                    // Make the no-arg constructor public (default cons
                    // visibility is family)
                    CodeConstructor cons = new CodeConstructor();
                    cons.Attributes = MemberAttributes.Public;
                    codeDom.Members.Add(cons);
                }
                else
                {
                    // Add CoClass attribute
                    CodeAttributeArgument typeArg = new CodeAttributeArgument();
                    typeArg.Value = new CodeTypeReferenceExpression
                                        (new CodeTypeReference("typeof("
                                                               + basicInfo.GetCLRTypeName()
                                                               + ")"));
                    codeDom.CustomAttributes.Add
                        (new CodeAttributeDeclaration
                            ("System.Runtime.InteropServices.CoClass",
                            new CodeAttributeArgument[] { typeArg }));
                }
            }
            if (TraceUtil.If(basicInfo, TraceLevel.Info))
            {
                Trace.WriteLine(basicInfo, "CG - "
                                + basicInfo.Name);
            }
            bool firstTime = true;

            // Add inherited interfaces
            foreach (BasicInfo member in interfaces)
            {
                if (member is ComInterfaceInfo)
                {
                    // FIXME - should probably compare these by GUID
                    if (member.Name.Equals("IUnknown") ||
                        member.Name.Equals("IDispatch"))
                    {
                        continue;
                    }
                    codeDom.BaseTypes.Add
                        (new CodeTypeReference(member.Name));
                    // Add the members for the class or interface,
                    // its all of the members
                    // of each implemented interface
                    if ((!codeDom.IsInterface && doClass) ||
                        codeDom.IsInterface)
                    {
                        // Qualify subsequent interfaces with the
                        // interface name
                        // Unless this is an interface, then just
                        // leave the name alone
                        if (firstTime || codeDom.IsInterface)
                        {
                            AddMembers(codeDom, member.Members, null);
                        }
                        else
                        {
                            AddMembers(codeDom, member.Members,
                                       member.Name + "_");
                        }
                    }
                    firstTime = false;
                }
            }
            // Don't add the members for the class interface
            if (basicInfo is ComClassInfo && !doClass)
            {
                return(codeDom);
            }
            // Add members for this interface (a class has none)
            AddMembers(codeDom, basicInfo.Members, null);
            return(codeDom);
        }