How to usefully set a breakpoint on the paint() method

Here is an annoying problem that I’m sure other people have faced and overcome before.

I’m finding that my paint() method is overloaded with redundant calls, probably due to my trigger-happy use of repaint() and other poor design choices. I’d like to examine the call stack to see what’s going on, but if I set a break-point in paint() it is immediately triggered and gets stuck in a loop when I press “continue”. I don’t quite understand it, but it’s something to do with the app window going in and out of focus as the “continue” button is pressed, which in turn calls paint() again.

Is there any way of using conditional break-points or something so that the program will ignore paint() calls from changes to the window focus? If not, is there some other way that I can examine the call stack for the paint() method?

I’m using Visual Studio Community.

I have two solutions that I apply as needed for this. My preferred method is to use two monitors, and on one I have the app/plugin being debugged, and on the other I have my debugger. The other method I use is to add logging statements to the app/plugin that tell me when it reaches certain points and what certain important values are.

Thanks @HowardAntares. Two monitors sounds great but I don’t have a spare, so I guess that logging is the way to go.

I’m looking at the FileLogger class for the first time. Logging a message seems like it should be easy enough, but how do I create messages that will be useful in debugging? Instead of knowing that a particular function was called, I want to know what called it, a bit like examining the Call Stack window in Visual Studio.

If too many calls are made to paint, due to you calling repaint too often, I think you should log your calls to repaint along with the reasons, or set a debugger breakpoint at repaint rather than paint.

How do you log the reasons?

Since paint() is always called asynchronously, your call stack will always be from the message queue, i.e. you don’t see, where repaint() was called to schedule the paint().
So you log where you call repaint(), and there you can add information to the log call:

DBG ("Repaint due to setFoo()");

There are even more clever ways to add automatic information.

But moving one step back, I would rather fix the painting performance than reducing the calls, since there will always be situations, where you can’t avoid it.

@daniel is right (as usual)–breaking paint() isn’t going to tell me very much, as the stack will just lead back to the message queue. Seems obvious now that I think about it!

But I also wanted to find a solution for the original problem, ie. how to view the stack when clicking on a breakpoint automatically triggers a breakpoint, because I’ve faced it on many occasions. And it turns out that there is a solution (for Visual Studio, at least).

  1. Create a breakpoint
  2. Right click on it and go to “Actions”
  3. In “Log a message to Output Window” write “$CALLSTACK”
  4. Select "Continue execution.

How cool is that?

1 Like