2010-07-26 17 views
0

Mon application a un arbre de type CTreeCtrl. L'un des nœuds de l'arbre est le contrôle CComboBox créé en tant qu'enfant de cette structure arborescente.Windows 7 ne se déclenche pas WM_SETFOCUS lors de la commutation de nœuds dans un contrôle d'arborescence

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

Essentiellement, le ComboBox est créé lorsque l'on clique sur le nœud de l'arbre et nous le détruisons dans la méthode :: OnComboKillFocus() (qui gère essentiellement le message ON_CBN_KILLFOCUS).

Windows ne déclenche pas le message WM_SETFOCUS lors de la navigation d'un nœud de l'arborescence à l'autre SAUF si l'un des nœuds est un contrôle comme dans notre cas, nous avons la liste déroulante. Ainsi, lorsque je sélectionne une option dans la liste déroulante ComboBox et que je clique ensuite sur un nœud différent de l'arborescence, un WM_SETFOCUS est déclenché. C'est le comportement dans Windows XP.

Cependant, apparemment dans Windows 7, après avoir sélectionné une option dans la liste déroulante ComboBox, sigle en cliquant sur un autre nœud ne déclenche pas un message WM_SETFOCUS. Donc, l'accent reste avec la ComboBox si le nouveau nœud est mis en évidence! Et en faisant défiler la molette de la souris ou en utilisant les touches fléchées, les options de la ComboBox seraient encore modifiées.

Est-ce un problème connu ou un comportement attendu de Windows 7 (différent de Windows Xp)?

Existe-t-il un moyen de faire en sorte que Windows 7 déclenche le message WM_SETFOCUS lorsque je passe d'un noeud (comme une zone de liste déroulante) à un autre noeud?

Pour ajouter plus de détails -

Nous traitons un message TVN_SELCHANGED pour le contrôle des arbres et gérer le message ON_CBN_KILLFOCUS pour le contrôle de zone de liste déroulante afin que nous puissions faire une certaine logique dans :: méthode OnComboKillFocus() puis détruire le Combo boîte et rétablir le nœud à un élément d'arborescence simple. Le :: OnSelChanged() est touché mais pas le :: OnComboKillfocus()

Essentiellement, Win 7 notifie un changement de sélection du nœud mais ne notifie pas un changement de focus (d'un nœud de zone de liste déroulante à un autre nœud de l'arbre). J'ai également utilisé Spy ++ et confirmé que Win 7 ne déclenche pas le WM_SETFOCUS lors de la sélection (simple clic) d'un nœud d'arbre différent avec le focus initial sur une zone de liste déroulante (qui est un autre nœud du même arbre). Win XP déclenche le message.

En outre, les contournements de travail suivants aident Win 7 pour déclencher le WM_SETFOCUS

  1. Faire un SetFocus() sur l'arbre (CTreeCtrl) contrôle dans le :: OnSelChanged()

  2. Manipulation de la ON_CBN_CLOSEUP message de la zone de liste déroulante

  3. Ou la manipulation du message ON_CBN_SELENDOK de la zone de liste déroulante

Nouvelles découvertes -

Mon application est construite avec la directive 'Activer les styles visuels'. Apparemment, le ComCtl32.dll de style XP ne provoque pas ce problème, mais le ComCtl32.dll sur Windows Vista et Windows 7 provoque le problème ci-dessus.

Ne pas activer les styles visuels et exécuter l'application sur un Windows 7 ne provoque pas le problème ci-dessus.

Répondre

1

Ceci est un comportement attendu. Ou mieux: vous utilisez un comportement non documenté. WM_SETFOCUS est envoyé si contrôle obtient/perd le focus. Le contrôle d'arbre est un contrôle unique - il peut être construit en utilisant d'autres contrôles, mais ce n'est pas fixe - et comme vous pouvez le voir dans Win7 cela a changé: le contrôle d'arbre est maintenant un seul contrôle et les éléments de l'arbre sont dessinés directement. construit à partir d'autres contrôles différents. Utilisez la notification TVN_BEGINLABELEDIT à la place.

Ou si vous voulez quelque chose de similaire à WM_SETFOCUS, utilisez la notification TVN_ITEMCHANGED et vérifiez s'il y a un changement dans l'état de la sélection.

+0

J'apprécie votre contribution. Merci beaucoup. Dans le but de documenter notre changement de logiciel (pour changer la façon dont nous utilisons actuellement le contrôle d'arborescence), pouvez-vous me diriger vers une documentation qui traite de quelque chose dans ce sens? – maverick

+0

Puisque vous dépendez d'une 'fonctionnalité' non documentée, il n'y a aucun document à ce sujet. Votre approche utilisant WM_SETFOCUS n'a fonctionné que parce que le contrôle de l'arbre utilisait (ne plus) les contrôles d'étiquette pour montrer les nœuds de l'arbre. C'est un comportement interne qui n'a jamais été documenté. Et maintenant que le contrôle des arbres dessine les nœuds directement, votre approche ne fonctionne plus. – Stefan

+0

Stefan, pouvez-vous voir si mes nouvelles découvertes vous aident à mieux comprendre le problème? Merci! – maverick