rulururu

post Deleting objects in the heap with wxWidgets

June 26th, 2008

Filed under: C++ — Kai @ 8:33 pm

For private use I often prefer wxWidgets to MFC, even thougth there’s no wide difference except of that wxWidgets runs on almost every platform.

I recently noticed that wxWidgets offers two nice macros wxDELETE and wxDELETEA, which you definitly should prefer using when deleting objects:

#define wxDELETE(p)   if ( (p) != NULL ) { delete p; p = NULL; }
#define wxDELETEA(p) if ( (p) ) { delete [] (p); p = NULL; }

It deletes pointer if it is not NULL and NULL it afterwards.

It’s not really a smart innovation, but as so many things it saves time and brain cells. According to my opinion it can be regarded as useful when detecting memory leaks because you can easily search your code for those macros.

post Do not step into trivial functions

June 26th, 2008

Filed under: C++, Visual Studio — Kai @ 11:00 am

Today I’d like to explain to you how you can prevent the debugger from stepping into trivial functions. In my examples I use wxWidgets and its wxString. It should be almost the same if you use MFC and its CStrings.

If you do a lot of debugging (and who doesn’t?), you’ve probably encountered many function calls that you’d really like to step into. In particular, if the code makes function calls to produce arguments for the function:

call_me( new foo( "a", 1 ), my_vector.begin(), my_vector.end() );

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 - especially when you are absolutely certain that you don’t need to. 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 *.

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 CString to a newgroup post.

If you are using Visual Studio 6, add these lines to autoexp.dat under

[ExecutionControl]
wxString\:\:c_str.*=NoStepInto
operator new=NoStepInto

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.

For instance, this is a good idea:

HKEY_CURRENT_USER\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

Visual Studio 8 has the same basic functionality as Visual Studio 7 with a few improvements. In addition, you should be aware that the key you must modify is now:

HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\NativeDE\StepOver

You’ll need an account with Admin privileges to set this up.

In addition to the ability to match regular expressions provided in Visual Studio 7, a few new escape sequences have been added to the regular expressions you can use, including '\funct' to match the name of a function, '\scope' to match a scope (e.g., std::my_namespace::etc::so::forth), and '\oper', which matches any operator.

Note: When using these escape sequences, you must indicate the end of the escape sequence with a colon. So you might write '\scope:' followed by the rest of the expression to match.

For example, you could avoid stepping into any overloaded operators by using the expression

\scope:operator\oper:=NoStepInto

which might be useful if you are using a lot of classes with simple operators whose behaviors you can trust to be correct.

There is a lot more you can do with it. Once done it saves time and energy ;)

post Shorten a Path

June 25th, 2008

Filed under: .NET — Kai @ 7:36 pm

Sometimes you need a long path to be short because the field that displays the text doesn’t have enought space for the whole path.

This in .NET written function does cut “C:\Windows\System32\Test\Test.dll” to “C:\Windows\…\Test.dll”.

First parameter is the path that has to be shorten.
Second parameter is the maximum length of the new string.
Third parameter is the Font that is used.
Return value is the new storten string.

public string PathShorten(string Path, int Length, Font TextFont)
{
    string[] PathParts = Path.Split('\\');
    StringBuilder PathBuild = new StringBuilder(Path.Length);
    string LastPart = PathParts[PathParts.Length - 1];
    string PrevPath = "";
 
    //check if path is already shorter than max. length
    if (TextRenderer.MeasureText(Path, TextFont).Width < Length)
        return Path;
 
    for (int i = 0; i < PathParts.Length - 1; i++)
    {
        PathBuild.Append(PathParts[i] + @"\");
        if (TextRenderer.MeasureText(PathBuild.ToString() + @"...\" 
              + LastPart, TextFont).Width >= Length)
            return PrevPath;
        else
            PrevPath = PathBuild.ToString() + @"...\" + LastPart;
    }
    return PrevPath;
}

Just a simple snipped but I guess that it can often be valuable. I hope it can be used widely.

post Top 25 Explanations

June 22nd, 2008

Filed under: Nonsense — Kai @ 1:00 pm

Those are the top 25 explanations by programmers when their programs don’t work.

1. Strange…
2. I’ve never heard about that.
3. It did work yesterday.
4. Well, the program needs some fixing.
5. How is this possible?
6. The machine seems to be broken.
7. Has the operating system been updated?
8. The user has made an error again.
9. There is something wrong in your test data.
10. I have not touched that module!
11. Yes yes, it will be ready in time.
12. You must have the wrong executable.
13. Oh, it’s just a feature.
14. I’m almost ready.
15. Of course, I just have to do these small fixes.
16. It will be done in no time at all.
17. It’s just some unlucky coincidense.
18. I can’t test everything!
19. THIS can’t do THAT.
20. Didn’t I fix it already?
21. It’s already there, but it has not been tested.
22. It works, but it’s not been tested.
23. Somebody must have changed my code.
24. There must be a virus in the application software.
25. Even though it does not work, how does it feel?

I guess some of them are familiar to almost every programmer. I really had to smile when reading them :D

post Force all non-zero values to 1

June 20th, 2008

Filed under: C++ — Kai @ 11:56 am

Let’s assume that you want to set all non-zero values to 1.
Usually, I’d prefer the simple and understandable way:

if(a != 0)
   a = 1;

or

a = (a==0) ? a : 1;

I found out a cool trick that I didn’t want to keep back from you:

a = !!a;

Funny, but too adventurous to use it in real life ;)

post Starting an application minimized without flickering

June 20th, 2008

Filed under: C++, MFC — Kai @ 11:31 am

To start an application minimized (e.g. appearing directly in the tray area), the common way to do this is calling ShowWindow(SW_HIDE) as soon as possible, preferably directly after the call to CDialog::OnInitDialog().

This surely does the trick, but every now and then, you will see your main dialog window flickering for a fraction of a second before it is finally hidden or sent to the tray area.

This is because the basic window has already been created when CDialog::OnInitDialog() returns, and its default behaviour is to appear on screen (in fact, this is what windows were made for).

Maybe in a few years, when computers operate much more faster than they do now, you’ll get rid of this annoying flickering automatically, because your Operating System will then hide your window before you even start the corresponding application.

But for now, just add this OnWindowPosChanging() handler to your application:

void CTestDlg::OnWindowPosChanging(WINDOWPOS* lpwndpos) 
{
    if(m_bDlgVisible == false)
        lpwndpos->flags &= ~SWP_SHOWWINDOW;
 
    CDialog::OnWindowPosChanging(lpwndpos);
}

You can also declare an optional boolean member variable (m_bDlgVisible in this example), which is initialized to true in the constructor and gets toggled in the corresponding SendToTray() and RestoreFromTray() functions. This way, I can track the current window state (IsWindowVisible() would also work) for different purposes.

ruldrurd
Next Page »
Powered by WordPress, Content and Design by Kai Bellmann
Entries (RSS) and Comments (RSS)