views:

97

answers:

1

My application has a tree of type CTreeCtrl. One of the nodes of the tree is CComboBox control created as a child of this tree structure.

c_combo->Create( WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_HASSTRINGS | CBS_DROPDOWNLIST, myrect, m_pTree, IDD_OBTC_COMBO );

In essence, the ComboBox gets created when clicked on the tree node and we destroy it in the ::OnComboKillFocus() method (which basically handles the ON_CBN_KILLFOCUS message).

Windows does not fire the WM_SETFOCUS message when navigating from one node of the tree to the other UNLESS when one of the node is a control like in our case we have the combobox. So when I select an option from the ComboBox dropdown list and then left click on a different node of the tree, a WM_SETFOCUS is fired. This is the behavior in Windows XP.

However, apparently in Windows 7, after selecting an option from the ComboBox drop down list, sigle clicking on a different node does not fire a WM_SETFOCUS message. So, the focus remains with the ComboBox though the new node is highlighted! And scrolling the mouse wheel or using the arrow keys would still result in the options of the ComboBox being changed.

Is this a known problem or an expected behavior of Windows 7 (different than Windows Xp)?

Is there a way I can get Windows 7 to fire the WM_SETFOCUS message when I switch from one node (like a ComboBox) to a different node?

To add more detail -

We handle TVN_SELCHANGED message for the tree control and handle the ON_CBN_KILLFOCUS message for the Combo box control so that we can do some logic in ::OnComboKillFocus() method and then destroy the Combo box and revert the node to a simple tree item. The ::OnSelChanged() gets hit but not the ::OnComboKillfocus()

In essence, Win 7 notifies a change in selection of the node but does not notify a change of focus (from a Combo box node to another node of the tree). I also used Spy++ and confirmed that Win 7 does not fire the WM_SETFOCUS upon selecting (single clicking) a different tree node with the initial focus on a Combo box (which is another node of the same tree). Win XP fires the message.

Also, the following work arounds help Win 7 to trigger the WM_SETFOCUS

  1. Doing a SetFocus() on the tree (CTreeCtrl) control within the ::OnSelChanged()

  2. Handling the ON_CBN_CLOSEUP message of the Combo box

  3. Or handling the ON_CBN_SELENDOK message of the Combo box

New findings -

My application is built with the directive to 'Enable Visual Styles'. Apparently, the XP style ComCtl32.dll does not cause this problem but the ComCtl32.dll on Windows Vista and Windows 7 do cause the above problem.

Not enabling the visual styles and running the application on a Windows 7 does not cause the above problem.

+1  A: 

This is expected behavior. Or better: you're using an undocumented behavior. WM_SETFOCUS is sent if a control gets/loses the focus. The tree control is one single control - it might be built using different other controls, but that's not fixed - and as you can see in Win7 that has changed: the tree control is now one single control and the tree items are drawn directly, not built from different other controls.

use the TVN_BEGINLABELEDIT notification instead. Or if you want something similar as WM_SETFOCUS, use the TVN_ITEMCHANGED notification and check for a change in the selection state.

Stefan
I appreciate your input. Thank you very much.For the purpose of documenting our software change (to change the way we currently use the tree control), can you point me to any documentation that addresses something along these lines?
maverick
Since you're depending on an undocumented 'feature', there are no documents about that. Your approach using WM_SETFOCUS only worked because the tree control used (doesn't anymore) label controls to show the tree nodes. That's an internal behavior that was never documented. And now that the tree control draws the nodes directly, your approach doesn't work anymore.
Stefan
Stefan,can you see if my new findings help you get a better insight into the issue?Thanks!
maverick