Did you know... A lot of tips go back to Visual C++ 2.0? - #162

For leap year, we’re going to leap all the way back to Visual C++ 2.0.

When I started collecting tips for tip of the day, Rico and I shared an office wall, so he forwarded me his list of tips for Visual C++ 2.0.  Of course, having never used VC++ 2.0, I put the doc on my desk, which quickly got buried.  It became a running joke for Rico to ask me if I read the tips yet, since he knew the answer.  So yes, Rico, i have finally read all the tips!

And oh yes rob caron, i’m counting this as a tip of the day, since i didn’t realize it was a leap year when i sign up to write a new tip every day.  =P

Visual C++ 2.0 Debugging Tips & Tricks by Rico Mariani (posted with his permission)

This is my list of things that I find really handy about Visual C++. Although this list is geared towards Visual C++ 2.0 some of the tips apply to previous versions as well. Hopefully there’s a little something in here that will make you a little bit more productive. I believe all of this is documented some place or another but with such a complex product it’s no wonder that not everyone finds every piece of information. So in no particular order…

Tip #1: “That edit item on the toolbar is really handy”

You can do all manner of cool stuff from up there. In fact, most commands that work on the current word or selection also work up there. For instance, to get on-line help on an API name you can hit Ctrl+F (or Alt+A for PWB converts) to put the focus there, (or click on it) type the name of interest, and hit F1. But the fun doesn’t stop there, you can also browse to definitions or references of a symbol by hitting F11 or Shift+F11 respectively, or use any of the browser queries by hitting the appropriate key, or set a breakpoint by hitting F9. Then there’s also quickwatch (Shift+F9) to quickly see the value of an expression (this works even if you’re not debugging so you can use it has a quick calculator). Of course the original function of that field was to do searching so F3 (search) works as well. The edit-field is like a mini-command window.

Tip #2: “You can type in the darndest places”

There’s some not so obvious items that are fully editable – for instance the watch window lets you edit the value of variables after the fact, as does the locals window. The memory window lets you type in the address field to set a new viewing location (if you know this you can turn off the toolbar and get a little space back), and you can type in the display area to edit the bytes/words/etc. that you are viewing. All of these windows are fully functional text windows so you can copy their contents to the clipboard and paste them in a spare document for later comparison or to ship to a friend. Ditto for callstack, ditto for disassembly.

Tip #3: “You can do more stuff in that callstack window…”

Callstacks aren’t just for looking at, you can use F9 to set breakpoints on places you’ll return to (this is great for setting a safety-net of checkpoints) or you can use F7 to run until you return to a particular frame, plus copy and paste to send those callstacks to needy developers.

Generating a callstack is quite computationally expensive so keep the window up only when you need it, or keep it small so that just a few frames need to be computed otherwise you’ll slow down stepping significantly. The little callstack dropdown in the locals window isn’t as loaded with goodies as the window but it’s cheap, takes up only a little space, and lets you change frames as easy as the old callstack menu in Codeview did – use it when it’s all you need.

Tip #4: “Debuggers can drag & drop too.”

You can save yourself a lot of typing with drag & drop. Drag from the source window to the watch window to add watches. Drag from the watch window to see the value of a variable as memory. Drag the address that a pointer points to to see that as memory. Drag a function name into the disassembly window to see the code for it. Note: people often drag a pointer variable into the memory window to see what it points to and then are confused because Visual C++ instead shows the pointer variable itself instead of what the pointer points to – avoid this problem by dragging the value of the pointer instead of the pointer variable.

Tip #5: “Quickwatch does more than just watch quickly”

Because quickwatch is a modal dialog it is possible to do a couple of useful things that don’t work in the watch window.

· you can evaluate an expression that includes a function call. This is a great way to get your application to help you debug it – write some useful dumping functions that use OutputDebugString() to emit intestine information about your program and then call those functions from the debugger.

· if you are looking a pointer to a C++ class, the debugger will automatically show you the actual type of the class. For instance, if you have a CWnd* and the CWnd is actually a CListBox (a class derived from CWnd) this will be indicated in the window by an extra item which you can expand to show the members of the CListBox. In many cases the actual type of the class is even more important than the data members (CWnds are a classic example of this, knowing what kind of window it is is more useful than knowing the value of say m_hWnd)

The default accelerator for quickwatch is Shift+F9 and don’t forget you can type expressions in that little edit item and then watch them. The thing I quickwatch most often is “this”, so I can see the derived-most type.

Tip #6: “Play it again (or not), Sam”

A classic problem that people run into is that they’ve stepped one statement too far (usually over a function call). You can easily move the EIP back to where you want it to be by right-clicking on the source line and picking “Set Next Statement” from the popup menu (or move the cursor to the line with the keyboard and then hit Ctrl+Shift+F7). In addition to seeing function calls or loops or whatever happen a second time (many times you can run a loop over again if you also run the initialization step) you can force the debugger to step out of a function without running it all by moving the cursor to the ending curly-brace. Or you can skip over code that is faulting to let you get back up a frame or two where the real source of the problem is (so that maybe you can repeat a call up there!). If you try to move the EIP out of the current function you’ll be warned because this probably isn’t a good thing (the stack is likely to be messed up, no destructors will be run etc.), but sometimes even this can be useful.

Tip #7: “Where’s the remote?”

Remote debugging is back with Visual C++ 2.0 and you no longer need a Ph.D. to get it configured correctly, in fact, now it’s very simple to get it working. We currently only support Serial communications on the Intel platforms (thanks for all your feedback asking for network support, I got the message <g>) but even at 57600 baud it’s not as fast as local.

Here’s two important tips to improve your performance:

· Try 38400 baud. Yes I’m serious. Depending on how long the cable is, and how fast your machine is, and maybe the alignment of Venus and Jupiter you might get enough additional transmission errors sending at 57600 baud that you’ll actually be faster at 38400.

· Keep the callstack window closed when you don’t need it. It’s obvious to everyone that having lots of watches or a giant memory window will cause a whole lot of data to have to be transmitted but the callstack window looks really small and innocent. Well it turn out that that to do decent callstacks the debugger has to grovel through all kinds of memory and all that has to be transmitted when remotely debugging.

Remote debugging is a great way to get around problems where having the debugger and the debuggee share the same keyboard or monitor makes it impossible to create the problem scenario. Remote debugging also makes it possible for you to get a debugger on a system where the whole IDE might not fit (like if the problem only reproduces on a 4M installation).

Tip #8: “There’s a browser toolbar y’know”

If you like the browser (or even if you didn’t before but think you might) turn on the browser toolbar. It’s the best way to get at the browser queries. Check out the tooltips for each button (just move the cursor over top of the button) to see what they all do, then click on what you want to browse and press the appropriate button. Don’t forget you can browse from the toolbar edit item. Try putting wildcards in there and then doing browser queries – my favorite is doing a file outline on “*.cpp”. My second favorite is doing a goto definition on “CMyClass::On*” to see all the message handlers I’ve defined for my class.

Well, I don’t want to turn this into another big document that nobody reads so I’ll end with…

Tip #9: “There’s gold in them thar hills”

All kinds of thought went into making the IDE a productive place to work with easy to discover features, but modern development environments have a wealth of functions comparable to any major application – it just can’t all be on the main menu. Take some time to check out the popup menus and the toolbars, drive through the options pages, look at the property pages. You’ll be pleasantly surprised by something. I’m just sure of it.

Projects, Editors, and Resources

The following is a summary of a talk that I gave at SD’95 called “Advanced Visual C++”. The talk seems to have been very popular and various folks have been asking for my slides, even though they are barely suitable for human consumption. So instead I’ve put together this set of tips which includes all the content of the talk minus the bits about the debugger which have already been published. As with my previous tips, the information is geared towards Visual C++ 2.0 but many of the tips also apply to v1.0. So without futher delay…

#1. Wrap external makefiles for added goodness

The project facility in Visual C++ is actually quite general and you can make it run any command to do your build (it doesn’t have to be nmake that does the work). So no matter how tricky it is to build your product you can make an external makefile that will build it. Doing this has lots of advantages: the output will be captured in the output window and you walk through your errors using F4/Shift+F4, the debugger will know what .exe to run when you debug and the browser will know what browser database to use. Lastly many Visual C++ settings are remembered on a per-project basis — so you can have custom options for the project if you wrap it. To actually create the external makefile, just use the File.Open command on the primary file that does the build (usually a makefile) and select “Open As Makefile” from the list it the bottom right.

#2. Change compile flags for more than one file at a time

One of the most under-used features in the project system is multiple selection in the tree control of the project settings dialog. By selecting multiple files you can see what flags they have in common and you can change flags for them all at once. This works even across groups or targets — selecting a group or target node in the tree is the same as selecting all the files in the group or target. This is a great way to see exactly what flags change from one target to another.

#3. There’s hidden goodies in the project system user interface

The project system is for more than just building. You can double click resource files to open the appropriate resource editor, you can drag and drop files from the file manager to add them to the project, you can even add random non-source files to the project and use the project system to launch the associated application. Very handy for updating for design documents (you do have design documents, don’t you? <g>)

#4. The text editor is getting way cool

The much-maligned Visual C++ Text Editor has actually gotten a whole lot better. Here’s the Top 10 things you probably didn’t think the Visual C++ editor could do:

10. Ctrl+Alt+T makes your tab characters visible.

9. Shift+Esc closes the active dockable window (output, watch, locals, etc.)

8. Ctrl+F3 finds the next occurrence of the current word

7. Ctrl+M finds the matching paren

6. Ctrl+> and Ctrl+< find the next/prev #ifdef, #else, or #endif

5. Ctrl+Shift+R starts/stops macro recording

4. Ctrl+Shift+P plays the recorded macro

3. Right click on #include lines to open the included file

2. Tab/Shift+Tab indent or unindent selected lines (when selection spans a line)

1. Holt Alt key down while dragging to select columns

#5. Sometimes resources aren’t the same as other times

You can cause resources to be compiled conditionally by using “magic” alternate Ids for them. For instance if you want one version of your Foo dialog for debug and another for other builds, you would do so by creating resources for IDD_FOO and IDD_FOO$(DEBUG). The resource editors use the trick to provide Macintosh specific versions of dialogs etc. in the cross platform version of the product but you can do so whenever you need to.

#6. Class Wizard is just a Control-Double-Click away

You can do the normal Class Wizard operation on any dialog control just by Ctrl+Double clicking on it. If the control is a button then a click handler will be added and you’ll be in position to type in the code, otherwise you’ll be set up to add a suitable member variable. This is particularly useful for data aware controls where you have to bind the control to some field in your data table.

#7. The bitmap editor has a keyboard interface that doesn’t quit

Just about all of the editing features are on some key or another (there’s a handy table in the documentation — in fact there’s keyboard mapping tables for just about all the features that you might get a lot of mileage out of). What’s really interesting is that some of the keys are best used while you’re in the middle of a drag operation. For instance, suppose you’re trying to draw a line from one point to another, you might zoom in to get a good look at the starting point but now you’re stuck in zoom mode as you’re in the middle of dragging, right? Wrong. You can hit ‘M’ in the middle of dragging (M is for Magnify) to unzoom, then get close to the end point and hit ‘M’ again for precise placement. Another favorite of mine is Ctrl+B which turns the current selection into a brush you can draw with, this has dozens of useful applications not the least of which is making copies of those 3d engaved look lines which are otherwise quite painful to draw over and over. Check out the key bindings, if you use this editor at all you’ll find them very handy.