Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Comments Workbench for C++ - A Visual Studio .NET Add-in

0.00/5 (No votes)
8 Jun 2004 1  
Comments workbench for C++ - a Visual Studio .NET add-in.

Main screen

Introduction

So, you have written all the code and are chilling out while a peer team member is reviewing it. You call your girl asking her to meet you in the evening as all your work is finally over. You are just about to leave the office when your reviewer calls up telling you that he can't understand even a word of your code, and whether you did attend the high school, and if so you should know that a code needs to be well commented before being sent for a review? You finally open up you favorite editor which shows you all the functions, classes etc. in a tree view, and you create a basic template of the comment. Now, you move function by function first pasting your template, and then function by function editing that template to fit the code and explains it well. After doing it all, you wonder if it was the best possible approach or could you have done it faster (without canceling your date)? Well, I guess we all understand the importance of commenting even without this made up story (I did it to fill this intro section ;)).

What really goes behind the scene?

Well, before taking the complete credit of the code, I must thank Microsoft Visual Studio 7 architects for exposing the code structure to the add-in writers without which this project would not have been possible. Those of you who have seen or worked with C++ grammar would agree with me - it's Huge and Confusing! I have seen many macros which do a similar job but they guesstimate the parameters, their types etc., and each of them enforces a particular style of commenting.

Another purpose for implementing this add-in was to learn more about the ATL, and the way Microsoft exposes its interfaces using COM for writing add-ins that work seamlessly with the product. Those who have experience with COM/ATL will, after seeing the code, immediately recognize that I am just a beginner of the subject, and that the code has still to go far to be called as stable.

Now to cut the long story short, let's see what exactly goes behind the scene.

What we already have?

When you create a new project using Wizard, you get the following things:

  • A predefined and semi-implemented class by the name CConnect which has the following declaration:
    class ATL_NO_VTABLE <CODE>CConnect : 
        public CComObjectRootEx<CComSingleThreadModel>,
        public CComCoClass<CConnect, &CLSID_Connect>,
        public IDispatchImpl<EnvDTE::IDTCommandTarget, \
        &EnvDTE::IID_IDTCommandTarget, &EnvDTE::LIBID_EnvDTE, 7, 0>,
        public IDispatchImpl<AddInDesignerObjects::_IDTExtensibility2, \
        &AddInDesignerObjects::IID__IDTExtensibility2, 
        &AddInDesignerObjects::LIBID_AddInDesignerObjects, 1, 0>

    Functions of each class that the CConnect derives from are explained below:

    1. CComObjectRootEx - is to expose your interfaces using the Query interface mechanism. You just need to enter your code in the BEGIN_COM_MAP and END_COM_MAP macros using COM_INTERFACE_ENTRY, and the rest will be taken care by this class.
    2. CComCoClass - This class helps in creating the instances of the class and obtaining its properties. That in short means it helps you to declare a class factory, and declares your class can be aggregated. Another macro OBJECT_ENTRY_AUTO helps in updating the registry and instantiating the object of the class as soon as the DLL is invoked.
    3. IDispatchImpl - This class provides a default implementation of IDispatch portion of the EnvDTE::IDTCommandTarget interface. So, we are implementing EnvDTE::IDTCommandTarget so as to be able to add the named commands and let the host know that we have commands that can be executed. We also implement IDispatch for AddInDesignerObjects::_IDTExtensibility2 so that the host can inform us of the various operations like startup, connection, and shutdown.

    Well, most of the above material is either copied or derived from MSDN, since the details go beyond the scope of the article. All I wanted to mention here was that the wizard does most of the work and we need not worry about how our add-in is going to be loaded or destroyed. Below, we see what needs to be done to achieve our objective.

  • We also have stub implementations of following functions which are exposed by various interfaces from which our class CConnect derives.
    1. CConnect::OnConnection - Invoked when the hosts connect to the add-in. This is a good time to add your command and toolbar objects to the host. For this, we use an instance of EnvDTE::_DTE where EnvDTE is the type library and the _DTE is the class interface which provides us the access to the code structures and various items that the host exposes.
    2. CConnect::OnDisconnection - We can release whatever resources were acquired on connection time. Generally because we store the reference to the EnvDTE::_DTE in our add-in on connection, we can release it here.
    3. CConnect::QueryStatus - is called by the host to get the name of the command that is supported by the add-in.
    4. CConnect::Exec - is called by the host to execute a command inside the add-in. This is where all the action takes place.

What we have to do?

If you have studied carefully the section above you, will immediately figure out that EnvDTE::_DTE object will provide us with various code structure details. Now, here onwards, it's a piece of cake for any C++ junkie. Here is, in short, what I did:

  1. Created main dialog which displays a code tree and two edit boxes (one for comments and one for code part).
  2. The main dialog obviously uses the _DTE object to populate the code tree.
  3. As and when you click on a particular item in the tree, it again uses the _DTE object to fetch the positioning of code item inside the editor, and then makes a lookup for the comments preceding it. If found, it checks up whether they are in consistent with the template configured. If they are, it displays the accurate comments, else it displays whatever is there inside "/*" and "*/".
  4. The template dialog can be invoked from the main dialog from which you can configure the templates to be used for configuring each item comment format.

Known Issues

  1. Drop downs don't drop :). You will have to use the keyboard to change the dropdown selected values.
  2. Reversing of the comments (based on style) is not yet perfect.
  3. In no means is it perfect or safe yet, and may end up screwing up your code. So, please use with caution!

Support for other Languages

This is a beta version and as such just implemented to test the demand of this kind of a tool. If requested in good numbers, I may think of supporting this tool for various languages. Though, currently it's not easy (due to some design decisions that were taken).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here