Tech Talk

This post is something a little out of the ordinary, one that most of our readers will want to skip: it’s a Javascript hack for Microsoft Visual Studio that solves a problem I had at work today. I couldn’t find anything about this online, and once I’d got it sorted out I thought I’d make it available here, so that the next poor wretch who wants to know how to do this won’t have to puzzle it out for himself.

One thing we Windows programmers sometimes need to do is to generate C++ files representing the classes exported by a type library. Visual Studio 2010 has a tool for doing this, called the MFC Class Wizard. (You launch it from the menu bar: Project -> Class Wizard…)

When you use the Class Wizard to create these files, it does two things. First, it renames the exported classes according to the MFC naming convention, by dropping any ‘I’ or ‘_’ prefix and replacing it with a ‘C’. (E.g., an exported class called IBaseClass will be called CBaseClass in the output file.)

The other thing it does is to generate a separate header file for each exported class — so that two exported classes IBaseClass and IUtilityClass will end up in two files, CBaseClass.h and CUtilityClass.h.

But what if you want to keep the class names the same, and merge all the declarations and definitions into a single header file? You have to go through the classes one at a time, in each case explicitly changing the auto-generated class name back to the original class name, and replacing the auto-generated file name with name of the single file you want as the output. (The Wizard is smart enough to merge the code, Dieu merci, but you still have to tell it specifically what to do every time, one class at a time.)

Yesterday I needed to generate a wrapper file for the Outlook Redemption type library, which exposes zillions of classes and methods. I was retrofitting the wrapper classes into some legacy code, created long ago, so I wanted all the class names to match the names in the type library — and I wanted it all in a single header file. To munch through these classes one at a time would have taken me many, many hours, and would have been inexpressibly tedious. I knew that if I could somehow get the Wizard to skip the automatic renaming of the classes, and to generate the same output-file name each time, it would do the whole conversion in just a minute or two. But where was this configured? I looked online for a while, but couldn’t find what I needed. So I dug into the Visual Studio installation directory, and finally found what I was looking for: an HTML file that defines both the Wizard’s UI and the Javascript that does the actual work. A few quick hacks, and the problem was solved.

The file is here:

C:\Program Files\Microsoft Visual Studio 10.0\VC\VCWizards\CodeWiz\MFC\Typelib\HTML\1033\default.htm.

All of this auto-generation work is done in the function AddClass, which starts at line 527.

The per-class filename generation is done at line 590:

Files_Array[oGeneratedClasses.options.length-1] = strClass + “.h”;

To force the Wizard to merge all the classes into the single file ‘YourFileName.h’, just change this to:

Files_Array[oGeneratedClasses.options.length-1] = “YourFileName.h”;

To prevent the renaming of the generated classes, look at these lines, starting at 559:

var strInterfaceName = oInterfaces.options[i].value;
var strClass;
if( strInterfaceName.charAt(0) == ‘_’ || strInterfaceName.charAt(0) == ‘I’ || strInterfaceName.charAt(0) ==’i’)
       strClass = “C” + strInterfaceName.substr(1);
else
       strClass = “C” + strInterfaceName;

if (IsInGeneratedList(strInterfaceName))

Change this to:

var strInterfaceName = oInterfaces.options[i].value;
var strClass = strInterfaceName;

if (IsInGeneratedList(strInterfaceName))

And that’s it! Don’t forget to put it all back, or at least to change the hard-coded filename next time you want to use it. (What would be even better would be to add some new code to expose all of these as options accessible directly from the UI, but I haven’t bothered.)

I hope this saves somebody out there a little time someday.

8 Comments

  1. “I hope this saves somebody out there a little time someday.”

    Not in my case, but I did save some time by skimming the post. On the other hand, you could say that I lost some time looking at a post I can neither use nor understand.

    To top it off, I’m now wasting time composing a silly comment when I could be doing something more useful . . . like . . . well, like not posting a silly comment.

    This is getting too ‘meta’, so I’ll stop now.

    Jeffery Hodges

    * * *

    Posted January 12, 2012 at 4:41 pm | Permalink
  2. Malcolm says

    You feeling OK, Jeffery?

    Posted January 12, 2012 at 4:44 pm | Permalink
  3. Doin’ a hunnert! My brain’s on ‘meta’ this morning . . .

    Jeffery Hodges

    * * *

    Posted January 12, 2012 at 4:53 pm | Permalink
  4. “My brain’s on ‘meta’ this morning . . .”

    Is that like an extra-bold roast at Starbucks, HJH?

    BTW, I’ve tried the new “Blonde” roast (extra light) and I like it … it might help your brain become less self-referential.

    Posted January 12, 2012 at 9:49 pm | Permalink
  5. When I visit Starbucks (which isn’t too often), I get a Grande cappuccino with four shots of espresso. That’s rather ‘meta’ itself!

    My brain seems to need those extra jolts. One might call this self-medication. Or more precisely, assisted suicide . . .

    Jeffery Hodges

    * * *

    Posted January 13, 2012 at 12:19 am | Permalink
  6. Sounds like Joltin’ Joe, HJH.

    Posted January 13, 2012 at 2:28 am | Permalink
  7. Where have you gone Joe Dimaggio,
    A nation turns its lonely eyes to you . . .

    Jeffery Hodges

    * * *

    Posted January 14, 2012 at 4:31 pm | Permalink
  8. “What’s that you say, Mrs. Robinson
    Joltin’ Joe has left and gone away
    (Hey, hey, hey…hey, hey, hey)”

    Posted January 14, 2012 at 5:51 pm | Permalink

Post a Comment

Your email is never shared. Required fields are marked *

*
*