Reformatting Microsoft’s Wizard/Template Generated Project Files

Environment: eg VC6 & VC7, ATL, WTL

When using Visual Studio’s project wizard to create a new project, Microsoft
uses templates that are located in the D:Program FilesMicrosoft Visual
StudioCommonMSDev98TemplateATL and D:Program FilesMicrosoft Visual
Studio.NETVc7VCWizardsClassWizATLControlTemplates1033 directories. (These paths will obviously vary based on your installation choices). These templates use
tags to include and exclude information in the resulting header and source
files. I really hate the way the Microsoft builds these
files. The MAPS are lacking indentation, the member variables (in 7.0) are
declared directly above the method that uses them and they contain no useful
comments or debugging code. I know that I am nit-picky but, I like my code
formatted so that it is readable and so there are no nasty, unreadable curly
braces on the end of ‘if’ and ‘while’ statements, and that all of the Member
variables reside in one ‘// Attributes’ section.

All of this is easily configurable through Wizard template header files.

There is a pretty good help file under the following directory:
D:Program FilesMicrosoft Visual StudioCommonMSDev98TemplateATL

for Visual Studio 6.0. To view it, rename the Template.txt file to Template.HTML.





Visual Studio wizard template directories.

Visual Studio 6.0
    D:Program FilesMicrosoft Visual StudioCommonMSDev98TemplateATL

Visual Studio 7.0
    D:Program FilesMicrosoft Visual Studio.NETVc7VCWizardsClassWizATLControlTemplates1033

The following is some information on how to modify the template files to make
VC++ generate headers as you would like to have them generated. The main file
used for generating headers is Control.h. Search for this file under your VS
install folder and you will see this file and other files which can be
modified. VS 6 and 7 use different template files so you will have to make your
modifications for both platforms’ files.

Here is a brief list of files that I found useful to modify. Again, either
search for these files or look in a path similar to the ones I mentioned in the
first paragraph. For this example I will mainly use the VS 7 templates under

D:Program FilesMicrosoft Visual
Studio.NETVc7VCWizardsClassWizATLControlTemplates1033 control.h

control.h, control.rgs, ctlco.idl and ctlint.idl.


control.cpp connpt.h control.rgs ctlco.idl ctlint.idl cmposite.rc are modifiable, too, although I have not made changes to them.

Before modifying any of these file(s) I would HIGHLY suggest making a backup of them or having the installs disks near you. NOTE: any changes you make to the java script are exact. Spaces, tabs, etc all show up your header/source files exactly as you enter them in the script.



VS’s use of Variable tags in the java script.

When looking in any of the above files you will notice statements like [!if AUTOSIZE] #include “[!output PROJECT_NAME].h” and uuid(“[!output OBJECT_UI_GUID]”), These are (I believe) Java tags. When going through the wizard setup, the wizard sets these values depending on your choices. The [!if SOME_TAG] is straighforward. If the VS wizard has set the flag SOME_TAG then this statement does or does not get compiled.

The #include line above takes whatever name you named your header file and
replaces the [!output PROJECT_NAME] with it. i.e. #include “[!output
PROJECT_NAME].h” becomes #include “MyProject.h”. Simple enough.

The third line above is basically the same. [!output OBJECT_UI_GUID] uses the generated GUID as a replacement for this line. You will see many variations of the [!output …] in the files, but most of the tags are self explanatory.

Onto the modifications… Let’s start with the IDL file and my rants. I hate the way Microsoft generates the properties and methods in your class/interface definition in the IDL file. The standard generated properties look like this

[propput, bindable, requestedit, id(DISPID_AUTOSIZE)]
HRESULT AutoSize([in]VARIANT_BOOL vbool);
[propget, bindable, requestedit, id(DISPID_AUTOSIZE)]
HRESULT AutoSize([out,retval]VARIANT_BOOL* pbool);

Whoever added that code must never modify the IDL by hand. When you opt to include numerous inherited properties for your class, the IDL section becomes unreadable. I personally would rather see it in a readable fashion like the following (in case these were wrapped in your web page, in the IDL file each
[propput… and [propget… would be on one line and each section would be linedup nicely.)

[propput, bindable, requestedit, id(DISPID_AUTOSIZE)] HRESULT
    AutoSize([in]VARIANT_BOOL vbool);
[propget, bindable, requestedit, id(DISPID_AUTOSIZE)] HRESULT
    AutoSize([out,retval]VARIANT_BOOL* pbool);

Simply edit the ‘ctlint.idl’ file and move the HRESULT lines up to the end of the [propput and [propget lines. The above line is really more for VS 6.0 since in 7.0 the interace definitions are generated in your class header file. Hence, for 7.0 you will have to modify the Control.h file to see the above changes.


The Control.h header template file.

This file composes the bulk of work that the wizard generates. Remember any changes that you make inside of a [!if …], [!endif] pair is going to be exactly what is generated in the Header file. The majority of the work for me was indenting the BEGIN_ and END_ MACROS and every MACRO line in between them. I know, I’m anal.

OK, beyond formatting. I moved the InterfaceSupportsErrorInfo implementation for the cpp file to the header. I do this so that I can delete the cpp file from the project and disk and then have all implementation code reside only in the header. This is good a practice for interface implementation as it lets other people include only the header and not the cpp. Now, when you add a Method or Property, the new method and properties implementation will be added to the header instead of the cpp file. WARNING: I think that under 6.0 you will get an error from the wizard when generating methods and properties if the cpp file does not exist, so the previous statement might be a 7.0 only suggestion.

Another thing that I found useful to change here is to add any debug and try/catch statements to each of the methods in the Control.h file. I like to see TRACES when I enter a function in the designated output debug app. You might also find it useful to add try/catch handlers in here so you do not have to add them in manually later on. Anything that you tend to add to every project that you generate is a candidate for addition here. Remember to add any include files in the header, depending on what dependencies that the code that you add needs. I remove the /*uMsg*/ parameters as well (personal preference.)

Ctlco.idl is an IDL file for the Connection points. Not much of anything to do here. Control.cpp I simply remove the InterfaceSupportsErrorInfo from this file and move it to the header. Connpt.h I did not have a need to modify this file.

Control.rgs, like all Registry (‘.RGS’) files can be modified too, although these are pretty specific and I have not taken the time to look into what advantages would exist in modifying them.

VS 6.0 has a great many other files that I have not looked into modifying as I do not use VS 6.0 any longer. You should be able to reformat the MFC files for both 6 and 7.0 as well but, as I use only ATL and no MFC, I have not looked into any of these files, either.

Downloads

Example project. – 184 kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read