A few weeks back, I ran into some issues related to tab stops for certain controls on a windows form not behaving as expected (e.g. a TabStop is set to false but the tab seems to still be trapped in the control somewhere). Typically, this issue is easy to diagnose, because we know what controls we have put on the form and we can inspect the TabStop property of each individual control and figure out the problem. Things become a lot more complicated however when composite custom controls are used however, since the TabStop behavior is no longer solely determined by the setting on the container control, but on the children controls as well. And finding the exact spot where the TabStop is trapped can be challenging. It turned out that Spy++ that comes with almost all Microsoft development suites can be extremely helpful in debugging various tabbing issues. As an example, I created a simple WinForm application (note, you can use Spy++ to debug any applications that run on Windows. Here I am using .Net). It is nothing fancy but just some buttons (in a real world scenario the controls themselves might be composite, of course). When I run the application (see image below), I want to find out whether button3 receives tab or not (this is a trivial test since we can visually see what is happening. It never the less illustrate the method).
Sample Application
Launch Spy++ and select log message.
Spy++
A message options dialog will appear, drag the “target” on the find control icon to the control you are going to inspect and then click OK (you can also filter out what type of messages you want to spy on, but for simplicity we leave the option as default, which will show all messages originated from the control we selected).
Message Options
Now, we can tab trough the controls on our form and watch the messages logged in Spy++. If the control indeed receives the tab stop, you will be able to see two messages like
WM_KEYUP nVirtKey:VK_TAB….
WM_KEYDOWN nVirtKey:VK_TAB…
Logged Message
If you don’t see these messages then your control does not receive tab stop. Using this method, I was able to detect several “non-visible” controls that received focus but really should not.