Monthly Archives: January 2008

A handy macro for Visual C++ developers: BuildStartupProject

I can’t believe I did not know this before: it’s possible to set up Visual Studio to use F7 to build the startup project rather than the selected one!

As a matter of fact, that was the default behavior of the F7 key in Visual Studio 6.0, but then in Visual Studio .NET 2003 (or maybe even in 2002?) Microsoft decided to change it to build the selected project rather than the startup one. This change made the build process somewhat inconvenient: if I happened to work with a file that belonged to a DLL and pressed F7, that would build that particular DLL only, while I wanted to build the whole thing – the executable that links to the DLL. In order to do that, I would need to select the EXE project first, then press the F7 key. I don’t know how many microseconds I’ve wasted doing that.

I could have changed the behavior of the F7 key by binding it to the Build.BuildStartupProject command, but the problem was, Visual Studio did not have such a command! The only choices available were: BuildSelection, BuildSolution, and similar, but there was no command to build the startup project. That’s one more thing I cannot believe, that Microsoft has not added such a command for such a long time: it’s still not present in Visual Studio 2008, the latest version as of this writing.

Today, for some reason I got very annoyed by my inability to use the F7 key the way I wanted, so I decided to search for a solution on the Internet, and (miracle!) I’ve found it. I’ll kick myself for a long time for not trying to find it before.

Anyway, the solution is a simple three-line macro I found in the BorisJ’s blog:

Sub BuildStartupProject()

    Dim sb As SolutionBuild = DTE.Solution.SolutionBuild

    Dim projName As String = sb.StartupProjects(0)

    sb.BuildProject(sb.ActiveConfiguration.Name, projName, False)

End Sub

As soon as I added it to my custom macros list in Visual Studio, and assigned F7 to run that macro, I could build the current startup project no matter what file I was working with.

One problem I had with the macro was that it did not bring the output window to the foreground when starting the build process, so I added a line that does that.

Another problem was that when I wanted to build for a different platform (such as x64), the macro still compiled for Win32. So I fixed it a bit to make it compile for the correct platform.

Here is the resultant macro :

Sub BuildStartupProject()

    DTE.ExecuteCommand("View.Output")

    Dim sb As SolutionBuild = DTE.Solution.SolutionBuild

    Dim projName As String = sb.StartupProjects(0)

    sb.BuildProject(sb.ActiveConfiguration.Name + "|" + _
                    sb.ActiveConfiguration.PlatformName, projName, False)

End Sub

Hope this helps someone. Did I mention I can’t believe I have not found this solution long ago? :-)

Did you know? Our USB Encryption Software can protect any USB flash drive or any other external drive with a password and strong encryption. Try it free for 30 days! Read more…

WinUnit and Structured Exception Handling (SEH)

Recently I was working on a native C/C++ library, and I was searching for a good unit testing framework to use with it. I took a look at TUT, CppUnit, and a couple of others, and was trying to decide which one to choose, when a new issue (February 2008) of the MSDN Magazine arrived. Turned out it came just in time because of the little gem it contained: an article by Maria Blees describing WinUnit, a unit testing framework she developed.

I downloaded the code, compiled the WinUnit.exe program from it, gave it a try, and immediately liked what I saw. Most of all I was impressed by how easy it was to get started: all I needed to do was create an empty DLL project, specify WinUnit.exe in its command line for the debugging, and presto, I was ready to add unit tests to my library!

Of course, designing the unit tests themselves was not that easy, but WinUnit made the process painless and even fun (if unit tests can be fun at all :-) ) Let me give a small example: suppose that for some reason you want to have your own version of the strlen() function, let’s call it MyStrLen(). It should accept a pointer to a TCHAR string and return the number of characters it contains:

size_t 
MyStrLen( LPCTSTR psz ) 
{ 
    size_t nLen = 0;           

    if ( psz == NULL ) 
        throw _T("Null pointer!"); 

    while( *psz++ ) 
         nLen++;            

    return nLen; 
}

How would you test this function with WinUnit? Here is how I would do it:

#include <WinUnit.h> 
#include "MyStrLen.h"           

BEGIN_TEST( MyStrLen_ShouldReturnZeroForEmptyString ) 
{ 
    WIN_ASSERT_ZERO( MyStrLen( _T("") ) ); 
} 
END_TEST           

BEGIN_TEST( MyStrLen_ShouldReturnCorrectLengthForNotEmptyStrings ) 
{ 
    WIN_ASSERT_EQUAL( 1, MyStrLen( _T("a") ) ); 
    WIN_ASSERT_EQUAL( 2, MyStrLen( _T("ab") ) ); 
    WIN_ASSERT_EQUAL( 26, MyStrLen( _T("abcdefghijklmnopqrstuvwxyz") ) ); 
} 
END_TEST           

BEGIN_TEST( MyStrLen_ShouldThrowForNullPointer ) 
{ 
    WIN_ASSERT_THROWS( MyStrLen( NULL ), LPCTSTR ); 
} 
END_TEST

Pretty self-explanatory, isn’t it? Each test gets a name, starts with the macro BEGIN_TEST, and ends with the macro END_TEST. The tests call the function being tested and verify the results using various WIN_ASSERT… macros provided by WinUnit. For the more complex tests one can also use the “fixtures”, and the macros that go with them: FIXTURE, SETUP, TEARDOWN, BEGIN_TESTF, and END_TESTF. See the article for the details.

To run the tests, you just press the F5 key in Visual Studio IDE, and WinUnit.exe loads your test DLL, executes all the tests it finds in it, and sends the output directly to the output window of Visual Studio. If a test does not check, you can double click on the “failed” message in the output window and it takes you right to the line that failed the verification, letting you see what’s going on. In short, it works just the way I would expect it to work.

One problem I encountered was when trying to write tests for functions that were using the Structured Exception Handling (SEH) mechanism instead of the C++ exceptions. (Why did I need that? Because the library I’ve been writing contains quite a few of pure C code (not C++), and you cannot use C++ exceptions in the C files). When trying to compile tests for such C files, the compiler complained that it couldn’t mix the SEH and C++ exceptions in the same function. Having looked into the WinUnit.h file, I’ve come up with the following macros that can be used instead of the usual ones:

BEGIN_TEST_SEH( TestName ) 
END_TEST_SEH 
FIXTURE_SEH( FixtureName ) 
SETUP_SEH( FixtureName ) 
TEARDOWN_SEH( FixtureName ) 
BEGIN_TESTF_SEH( TestName, FixtureName ) 
END_TESTF_SEH( FixtureName ) 
WIN_ASSERT_THROWS_SEH( expression, ... )

(I’ve put them in a separate file, WinUnitSEH.h).

Now, if the MyStrLen() function were throwing a SEH exception, for example by calling the RaiseException() function instead of using the throw operator, the last test could be rewritten as follows:

#include <WinUnitSEH.h>          

BEGIN_TEST_SEH( MyStrLen_ShouldThrowForNullPointerSEH ) 
{ 
    WIN_ASSERT_THROWS_SEH( MyStrLen( NULL ) ); 
} 
END_TEST_SEH

Hope this helps someone. Download WinUnitSEH.h

Virtually everything

Being in the software business, I have to upgrade my main development machine rather often. When switching to a new computer, the most frustrating part of the process is setting it up just the way I like it. That means not only moving the source code and other files over, but also installing the applications I need, configuring their settings, fine-tuning their options to make they work just right. I used to spend at least a couple of days doing such tedious tasks, before I could start to actually work with the new computer.

A couple of years ago, when preparing to move to a yet another new computer, and remembering how depressing it was the previous time, I decided to try something new: instead of reinstalling all my development tools directly, I created a virtual machine in the new computer first, and then installed the applications and utilities inside of that virtual computer. From that time on, I work from within the virtual machine, using the real computer just as the host of the virtual one.

Now, a couple of years later, I can say that that was one of the best moves I’ve done that reduced my stress level and increased my productivity. I had to move to a new computer a couple of times after that, and when I did that, all I needed to do to recreate my familiar development environment was to install the virtual machine software, copy the virtual machine to the new computer, and presto – I was back in the game in no time at all. Another convenience was that whenever I went on a trip, all I needed to do to take my development shop with me was copy the virtual machine to the laptop, and I could keep working on my software projects while on the go!

Of course, going virtual for software development requires the host computer to have a fast processor and plenty of RAM (a fast hard drive does not hurt, too). My current host computer has 2 GB of RAM and uses a Core 2 Duo processor that provides hardware support for virtualization. That makes my software development application (Microsoft Visual Studio) to work within the virtual machine just as fast as within the real one. (At least that’s how it feels, I did not do any special timings).

I liked having an independent virtual machine for the software development so much that a bit later I’ve created a few more dedicated virtual machines to run other parts of my software business as well: one such machine contains all my web site development tools and applications, including a local web server running the local copy of my web sites. Another virtual machine is dedicated to keeping the database of the customers, bookkeeping software, and other related tools.

In case you’ve spent the last few years on the moon and are not familiar with the virtual machine software, you can get started by taking a look at Microsoft Virtual PC and/or VMWare Server: both are easy to set up and use, both are free, both have good performance. VMWare Server offers more flexibility in the virtual machine configuration, and it provides support for the USB devices, while Virtual PC is easier to setup and use. I use both Virtual PC and VMWare Server, but I could not get them both to work on the same computer at the same time: if one of them was running, then an attempt to start the other one caused the host computer to crash. However, using them one at a time or on different host computers caused no problems.

One drawback of setting up the virtual machines is that many software vendors treat them like separate physical computers, and if you have purchased a one-computer license, you may not be allowed to install separate copies of the software in several virtual machines, even if they operate on the same physical host computer. I find such restrictions quite annoying. (They are the relicts from the old pre-virtual computing days). If you have a software tool that you must install in more than one virtual machine, check its license agreement, and if you find that you are not allowed to use the software in several virtual machines, contact the vendor and ask them to reconsider their license terms. If enough of us start demanding it, they may actually do that.