How can I retrieve the comments from the top of a Class without having an open code window? In an add-in you can retrieve the comments from a class by combining the use of the FileCodeModel object with EditPoint objects. This negates the use of the very visible TextSelection object and the unwanted flash that goes along with it.
If you are adept at writing add-ins, you know that each ProjectItem has a FileCodeModel object. Each FileCodeModel object has CodeElements. One of the types of CodeElements is a CodeFunction. In a C# project, you can use the CodeFunction.DocComment property to get the comments preceding a function definition line. In VB, you need to use the Text Editor's EditPoint object to retrieve the comments. However, there is no direct method to retrieve the comments at the top of a ProjectItem code window. If you are writing a documentation add-in, you will want to retrieve the comments that generally document the class, in addition to retrieving the comments for each of the functions within the class.
I have written a function in C# to do this. To use it, you simply need to set up a loop through the project items, creating a FileCodeModel object for each one, and call the function shown below.
In C#, you will always have Namespaces, while in VB.NET, you may or may not use Namespaces. Consequently, you will see two sets of code in the function, that look like they are almost duplicates of each other, except that first set of code handles a ProjectItem with Namespaces in it and the second set handles code without Namespaces.
This function is straightforward, as add-in code goes. It use the FileCodeModel object passed into it to create an EditPoint object. With the EditPoint object, you can go up or down in code, all the while examining each line of code as you go through it. Since you are using the FileCodeModel and EditPoint objects, there is no requirement to have a code window open and consequently, it is very fast and the manipulation of the code is not visible to the user.
This function returns a string representing the comments, if any, that appear at the top of a ProjectItem. Since I am using this string to write an HTML document, each line of comment will be followed by the "
" HTML tag. If you want to print in a regular file format, you will need to replace the "
" with a newline character.
| private string GetClassLevelComments(FileCodeModel fileCM) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); // Loop thru the code elements of the projectitem foreach (CodeElement ce in fileCM.CodeElements) { if(ce.Kind==vsCMElement.vsCMElementNamespace) { // handle code with namespaces in it CodeNamespace cns = (CodeNamespace) ce; foreach(CodeClass cl in cns.Members) { CodeType celttype = (CodeType) cl; EditPoint ep = celttype.GetStartPoint (vsCMPart.vsCMPartHeader).CreateEditPoint(); string sText; // move to the top of the document while(!ep.AtStartOfDocument) ep.LineUp(1); // if any comment lines are found, place them in a string // builder until the end of comments is found while(!ep.AtEndOfDocument) { sText = ep.GetText(ep.LineLength).Trim(); if(sText.StartsWith("///") || sText.StartsWith("'''")) { // ignore xml comment tags if(sText.IndexOf("<summary>")==-1 && sText.IndexOf("</summary>")==-1) { sText = sText.Substring(3); sb.Append(sText + "<br>"); } if(ep.AtEndOfDocument) break; ep.LineDown(1); } else break; } } } else { // this code handles code without Namespaces CodeElement celt = fileCM.CodeElements.Item(1); CodeType celttype = (CodeType) celt; EditPoint ep = celttype.GetStartPoint (vsCMPart.vsCMPartHeader).CreateEditPoint(); string sText; while(!ep.AtStartOfDocument) ep.LineUp(1); while(!ep.AtEndOfDocument) { sText = ep.GetText(ep.LineLength).Trim(); if(sText.StartsWith("///") || sText.StartsWith("'''")) { if(sText.IndexOf("<summary>")==-1 && sText.IndexOf("</summary>")==-1) { sText = sText.Substring(3); sb.Append(sText + "<br>"); } if(ep.AtEndOfDocument) break; ep.LineDown(1); } else break; } } } return sb.ToString(); } } } |