Introduction
When using Visual Studio's project wizard to create a new project, Microsoft uses templates
that are located in the
D:\Program Files\Microsoft Visual Studio\Common\MSDev98\Template\ATL
and
D:\Program Files\Microsoft Visual
Studio.NET\Vc7\VCWizards\ClassWiz\ATL\Control\Templates\1033
directories (of course the paths will vary on your installation choices.) These templates use tags to
include and exclude information in the resulting header and source files. Call me anal, but 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 which 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 Files\Microsoft Visual
Studio\Common\MSDev98\Template\ATLfor 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 Files\Microsoft Visual Studio\Common\MSDev98\Template\ATL
Visual Studio 7.0
D:\Program Files\Microsoft Visual Studio.NET\Vc7\VCWizards\ClassWiz\ATL\Control\Templates\1033
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 Files\Microsoft Visual Studio.NET\Vc7\VCWizards\ClassWiz\ATL\Control\Templates\1033
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 straightforward. 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 lined
up 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);
(Ed: These lines have been wrapped for display purposes - the author's
original intent is to have them unwrapped)
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 interface 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 the in the project I can delete
the cpp file from the project and disk and then have all implementation code
reside in the header only. This is good a practice for interface implementation
as it lets other people only include 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 This is 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. 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 probably 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.