Tips & Tricks using Visual Studio .NET
Following are a few tips and neat things to do that will help you developing software with wxWidgets and Microsofts Visual Studio C++.
wxWidgets is an open source, crossplatform GUI library of high quality. And its completely free, even for commercial use. Click here to read more about wxWidgets...
If you have never heard of wxWidgets before, these tips may still be useful to you.
Precompiled headers - revisited
The wxWidgets documentation suggest, that you use wx/wxprec.h as the precompiled header file.The way I show here has the following advantages:
- You can use more than just the wx/wxprec.h header as precompiled header files.
- You have a place where you can add the neccessary statements for the “debug memory allocation enhancement” (see below).
Follow these steps to set your project to precompiled headers:
- Create a header file stdwx.h
- Include all headers you want precompiled in this header file. My stdwx.h usually looks like this:
#include "wx/wxprec.h" // wxWidgets precompiled / standard headers
#include "wx/notebook.h" // other headers I need #include "wx/statline.h" #include "wx/tglbtn.h"
// debug memory allocation enhancement (see next tip) #ifdef _DEBUG #include <crtdbg.h> #define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__) #else
#define DEBUG_NEW new #endif
#pragma warning (disable:4786) #include <map> #include <vector>
using namespace std;
- Create a C++ file stdwx.cpp and add the following statement
#include “stdwx.h”
- Include both, stdwx.h and stdwx.cpp to your project file.
- Open the settings for your projects.
- Select ‘all configurations’
- Select ‘C++ / Precompiled Headers’
- Set ‘Use precompiled headerfile (.pch) ... through’ to stdwx.h
- Select stdwx.cpp in the list of project files.
- Set ‘Create precompiled headerfile (.pch) ... through’ to stdwx.h
That’s it, your done.
Including file and linenumber in the debug memory allocation (memory leak dump)
wxWidgets has debug memory allocation turned on by default, if you use Microsoft Visual C++. If your program has a memory leak, it will dump all leaked memory blocks, when you close the program.
Dumping objects -> {5641} normal block at 0x00BB30A0, 100 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD
CD CD CD CD CD
This is nice, but you still have to find the exact location where this leak occurs. You can either call _CrtSetBreakAlloc(5641), where 5641 is the allocation index shown in brackets of the allocation dump (see example above).
But there is a much easier way.
- Include the following statements in your standard, precompiled headerfile:
#ifdef _DEBUG #include <crtdbg.h> #define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__) #else
#define DEBUG_NEW new #endif
- In every CPP file, include these statements immediately after the last #include statement (before the first malloc/new statement):
#ifdef _DEBUG #define new DEBUG_NEW #endif
The example above will now print:
Dumping objects -> P:\SBKService\SBKMainFrame1.cpp(1036) : {5645} normal block at 0x00BB30F0
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
The sourcefile and linenumber where the memory leak occurred are now included and you can double click on the line in the debug output window.
Automatically showing wxStrings contents in debug windows
If you are debugging your program, wxString variables show up in the debug windows in the form: [+] Variable {...}
You first have to click on the [+] sign to expand the structure. Then you see the m_pchData variable, which is the pointer to the actual data.
I found this to be annoying and looked for a solution. There is a very interesting file called AUTOEXP.DAT, which does exactly what I wanted.
- Locate and open a file called AUTOEXP.DAT. Its in the \Program Files\Microsoft Visual Studio\Common\MSDev98\Bin directory, if you are using Version 6. Search for it if you are using .NET Studio.
- Add the following line to the [autoexpand] section (or the bottom of the file). With .NET 2003 be careful not to put it in the [hresult] section!:
wxString=<m_pchData,st>
- Restart Visual Studio.
That’s all. Now, when you are debugging and displaying a string, the wxString variable shows up in the form: [+] Variable {“Contents of the string”}
This will save you many mouseclicks, especially when you want to watch the changes to this variable. And while you are at it, read the comments in AUTOEXP.DAT. I am sure you can think of more
variables you’d like to handle this way.
While you are at it editing autoexp.dat...
Preventing the debugger from stepping into trivial functions.
When you are single stepping in the debugger (using F11) and you want to step into a function that has strings as a parameter, the debugger will first step into the string constructor. This is correct but
annoying. You don’t want to debug the string constructor. The same applies to many other functions, e.g. new(), malloc(), wxString::c_str(). There is a way to tell the debugger to step over these functions even if you use ‘Step Into’.
Create a ‘NoStepInto’ entry for every function you do not want to step into. Note: Visual Studio uses the regular expression syntax to specify the function names. regexp is much more powerful than
wildcards such as ? and *. Search the usenet and read the wx documentation for more information.
Note: Don’t forget - you have to ‘escape’ special characters with ‘\’. If you want to step over wxString::c_str*, you need to write wxString\:\:c_str.* There is a lot of confusion in the newgroups and
other examples if you need to write \\:\\: or simply \:\:. My personal view is, \: is enough (as is correct with regexp) and the other expression came from pasting a C string to a newgroup post.
If you are using MS Visual Studio 6, add these lines to autoexp.dat under
If you are using Visual Studio .NET 2003 or 2002, modify the registry.
- Add the Key NativeDE\StepOver under HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.1 (or 7.0 if you are using .NET 2002)
- For every function you want to skip, add a new key/string value under the StepOver key.
- The keys must be numerical. Think of them as linenumbers like in the old Basic days. Due to a bug in the Debugger, these numbers will get evaluated in reverse order.
- The string contains the regular expression I have described above.
Example: HKCU\Software\Microsoft\VisualStudio\7.1\NativeDE\StepOver\10 = wxString\:\:c_str.*
This will prevent the debugger from stepping into these functions when you press F11 or choose “step into”. Other useful expressions are:
|
wxString Constructor
|
wxString\:\:wxString
|
|
wxString Destructor
|
wxString\:\:~wxString
|
|
There is a lot more you can do with it. This article in microsoft.public.vsnet.debugging was written by
the guy who coded this and it lists the debugger source snippet.
Or search google groups for NoStepInto.
Useful links...
|