예제 #1
0
        public int GetMemberNavigationPoint(string pszClassName, string pszUniqueMemberID, TextSpan[] pSpanNavPoint, out uint pItemID)
        {
            // Validate the parameters
            if (string.IsNullOrEmpty(pszClassName))
            {
                throw new System.ArgumentNullException("pszClassName");
            }
            if (string.IsNullOrEmpty(pszUniqueMemberID))
            {
                throw new System.ArgumentNullException("pszUniqueMemberID");
            }
            if ((null == pSpanNavPoint) || (0 == pSpanNavPoint.Length))
            {
                throw new ArgumentNullException("pSpanNavPoint");
            }
            // Get the implementation class
            CodeClassInfo implInfo = ImplementationClass(pszClassName);

            if ((null == implInfo) || (null == implInfo.CodeClass))
            {
                throw new System.ArgumentException("pszClassName");
            }
            EnvDTE.CodeClass implClass = implInfo.CodeClass;

            // Verify that the unique id is valid.
            string memberName = MemberNameFromUniqueId(pszUniqueMemberID);

            if (string.IsNullOrEmpty(memberName))
            {
                throw new System.ArgumentException();
            }
            // Remove the '_' added by the file code model
            if (memberName[0] == '_')
            {
                memberName = memberName.Substring(1);
            }

            // Get the code element for the member.
            EnvDTE.CodeElement member = GetClassMember(implClass, memberName);
            if (null == member)
            {
                throw new System.ArgumentException();
            }

            // Set the output variables.
            pSpanNavPoint[0] = CodeElementSpan(member);
            pItemID          = implInfo.ItemId;

            return(VSConstants.S_OK);
        }
예제 #2
0
        public int CreateUniqueEventName(string pszClassName, string pszObjectName, string pszNameOfEvent, out string pbstrEventHandlerName)
        {
            // Get the class that will contain the actual implementation of the event handler.
            CodeClassInfo implInfo = ImplementationClass(pszClassName);

            if ((null == implInfo) || (null == implInfo.CodeClass))
            {
                throw new System.ArgumentException("pszClassName");
            }
            EnvDTE.CodeClass implClass = implInfo.CodeClass;

            // Build the default name for the event handler.
            string baseName = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}_{1}", pszObjectName, pszNameOfEvent);

            pbstrEventHandlerName = baseName;

            // Now we have to check if the implementation class contains another member with the same name.
            for (int i = 1; ; ++i)
            {
                if (null == GetClassMember(implClass, pbstrEventHandlerName))
                {
                    // No member with this name.
                    break;
                }
                else
                {
                    // The name is in use. Change it adding a numeric identifier at the end of it.
                    pbstrEventHandlerName = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}_{1}", baseName, i);
                }
            }

            // Add one underscore at the beginning of the function name because this is what the
            // file code model will add.
            pbstrEventHandlerName = "_" + pbstrEventHandlerName;

            // All done, return.
            return(VSConstants.S_OK);
        }
예제 #3
0
        public int EnsureEventHandler(string pszClassName, string pszObjectTypeName, string pszNameOfEvent, string pszEventHandlerName, uint itemidInsertionPoint, out string pbstrUniqueMemberID, out string pbstrEventBody, TextSpan[] pSpanInsertionPoint)
        {
            if (string.IsNullOrEmpty(pszClassName))
            {
                throw new System.ArgumentNullException("pszClassName");
            }
            if ((null == pSpanInsertionPoint) || (pSpanInsertionPoint.Length == 0))
            {
                throw new System.ArgumentNullException("pSpanInsertionPoint");
            }
            if (string.IsNullOrEmpty(pszEventHandlerName))
            {
                throw new System.ArgumentNullException("pszEventHandlerName");
            }
            // The file code model will create a function name that starts with '_', so we must make
            // sure that the name of the event handler matches it.
            if (pszEventHandlerName[0] != '_')
            {
                throw new System.ArgumentException("pszEventHandlerName");
            }
            // Given the fact that the file code model will add _ at the beginning of the name,
            // we have to remove the underscore from the name passed to AddFunction.
            string handlerName = pszEventHandlerName.Substring(1);

            // Initialize the out parameters.
            pbstrUniqueMemberID = null;
            pbstrEventBody      = null;

            // Get the implementation class.
            CodeClassInfo implInfo = ImplementationClass(pszClassName);

            if ((null == implInfo) || (null == implInfo.CodeClass))
            {
                // According with the documentation this method must return E_FAIL if the class does not
                // exist in this scope.
                return(VSConstants.E_FAIL);
            }
            EnvDTE.CodeClass implClass = implInfo.CodeClass;

            // Check if the method exists.
            EnvDTE.CodeElement member = GetClassMember(implClass, handlerName);
            if (null != member)
            {
                // If the member exists this function must return its unique id and insertion point, but the
                // event body must be null.
                pbstrUniqueMemberID    = ClassMemberUniqueId(implClass, pszEventHandlerName);
                pSpanInsertionPoint[0] = CodeElementSpan(member);
                return(VSConstants.S_OK);
            }

            // There is no event handler, so we have to create it.
            EnvDTE.CodeFunction eventHandler =
                implClass.AddFunction(handlerName, EnvDTE.vsCMFunction.vsCMFunctionFunction,
                                      EnvDTE.vsCMTypeRef.vsCMTypeRefVoid, -1, EnvDTE.vsCMAccess.vsCMAccessPrivate, null);

            eventHandler.AddParameter("sender", EnvDTE.vsCMTypeRef.vsCMTypeRefObject, 1);
            eventHandler.AddParameter("args", "System.EventArgs", 2);

            // Make sure that the right document is visible.
            if (null != eventHandler.ProjectItem)
            {
                eventHandler.ProjectItem.Open(System.Guid.Empty.ToString("B"));
                if (null != eventHandler.ProjectItem.Document)
                {
                    eventHandler.ProjectItem.Document.Activate();
                }
            }

            // Set the navigation point
            pSpanInsertionPoint[0] = CodeElementSpan(eventHandler as EnvDTE.CodeElement);
            pbstrUniqueMemberID    = ClassMemberUniqueId(implClass, pszEventHandlerName);

            // The HTML editor will remove the initial spaces on the string returned by this function, but
            // this will break the indentation and the file will not compile. To work around the problem
            // we create a first line that is a comment, so that its indentation is not a problem.
            StringBuilder eventBody = new StringBuilder();

            eventBody.AppendLine("#");
            // Add the actual body of the event handler.
            eventBody.Append(stringMerger.GetTextFromLine(pSpanInsertionPoint[0].iStartLine - 1));
            pbstrEventBody = eventBody.ToString();

            return(VSConstants.S_OK);
        }