Debugging Mouse Clicks and Dragging in C++
Debugging mouse events is especially confusing, because when the debugger stops the code, most of the events go away! What tactics can we use in these situations?
- By Bartlomiej Filipek
When you work on an editor-style application, you might often want to debug code after mouse clicks (on a button, or a document/canvas), or when a user drags objects on the screen. Sometimes you don't know the exact handler for a mouse event, so it's not easy to just set a debugger breakpoint.
Mouse clicks are usually easy if you know onClick/onMouseDown methods for a given object: Just set a breakpoint there and wait.
If you don't know the event handlers, here's what you look for:
- If it happens on a button, you might find a particular ID/name of that button and track it through the code. That should usually point you to the exact event handler.
- When it happens on an object on the screen, if you set a breakpoint too early -- like in a generic Message() method -- then it will usually take you some time to dig into the code path and finally find if you're target object's method was called. There's probably some common virtual method (like obj->Prepare() - that prepares for the operation) ... you could set a breakpoint there. Then, when it stops, you'll see a call stack that should include your target object somewhere and a relevant event handler.
What about mouse dragging? If the debugger stops, then the drag state is lost. In those situations I try to do the following things:
- Use good old trace/printf output. While dragging, I get a lot of messages that lead to a better understanding what's going on, without breaking the execution. You probably want to have short drags operations; otherwise, you'll end up with tons of output to filter out. You can isolate the most important place and focus on that part later by using the captured logger output.
- Use conditional breakpoints in places that you really want to check. For example you rotate an object, and you're interested in why it unexpectedly changes position. You can set a breakpoint on the position members and you'll get a chance to see what's going on there. The state after stopping is lost, but at least you can play with the rotation for a while and you'll eventually get into the potential place in the code.
- Even if you don't have initial condition for a conditional breakpoint you can try stopping not immediately after dragging starts but later. For example you can try to set a condition when obj_rot > some_meaningful_value (or similar). Or even set a breakpoint Hit count to 100 or 1000.
- Dragging often happens on a copy of objects. Then after the dragging the real objects are transformed once into the proper state. Maybe you can set breakpoint to look only at the original objects? Maybe there is a separate state in the app that tells you when this drag operation is happening? Then the debugger will stop at the end of drag operation.
- Similarly, to the previous statement, you can search for the start of the dragging operation.
I hope you found these tips for debugging of mouse events to be helpful. By using conditional expressions, logging and narrowing down the initial problem, you could catch mouse actions faster.
Bartlomiej Filipek is a software developer in Poland who specializes in C++, Windows and graphics programming. He worked for a number of companies developing multimedia, document editors, games, graphics drivers and flight planning systems, and has taught game development at local university. Follow Bart's blog at http://www.bfilipek.com and on Twitter @fenbf.