La case supprimée réapparaît dans le nœud de l’arborescence lorsque l’utilisateur appuie sur la barre d’espacement

J’ai utilisé la solution acceptée de cette question pour supprimer la case à cocher d’un nœud d’ WM_INITDIALOG dans mon gestionnaire WM_INITDIALOG .

Au chargement, l’ arbre a un aspect correct. Après que j’ai sélectionné le nœud et cliqué sur l’endroit où la case à cocher serait, rien ne se passe (la case à cocher n’apparaît pas) qui est le comportement correct.

Cependant, si je sélectionne le nœud et appuie sur la barre d'espace, la case à cocher est automatiquement ajoutée au nœud.

Voici le gestionnaire WM_INITDIALOG qui illustre le problème:

 case WM_INITDIALOG: { // get treeview handle HWND TreeView = GetDlgItem( hDlg, IDC_TREE1 ); /************ enable checkboxes **************/ DWORD dwStyle = GetWindowLong( TreeView , GWL_STYLE); dwStyle |= TVS_CHECKBOXES; SetWindowLongPtr( TreeView , GWL_STYLE, dwStyle ); /************ add items and subitems **********/ // add root item TVINSERTSTRUCT tvis = {0}; tvis.item.mask = TVIF_TEXT; tvis.item.pszText = L"This is root item"; tvis.hInsertAfter = TVI_LAST; tvis.hParent = TVI_ROOT; HTREEITEM hRootItem = reinterpret_cast( SendMessage( TreeView , TVM_INSERTITEM, 0, reinterpret_cast( &tvis ) ) ); // and here is an example of removing a checkbox TVITEM tvi; tvi.hItem = hRootItem ; tvi.mask = TVIF_STATE; tvi.stateMask = TVIS_STATEIMAGEMASK; tvi.state = 0; TreeView_SetItem( TreeView, &tvi ); // add firts subitem for the hTreeItem memset( &tvis, 0, sizeof(TVINSERTSTRUCT) ); tvis.item.mask = TVIF_TEXT; tvis.item.pszText = L"This is first subitem"; tvis.hInsertAfter = TVI_LAST; tvis.hParent = hRootItem; HTREEITEM hTreeSubItem1 = reinterpret_cast( SendMessage( TreeView , TVM_INSERTITEM, 0, reinterpret_cast( &tvis ) ) ); // now we insert second subitem for hRootItem memset( &tvis, 0, sizeof(TVINSERTSTRUCT) ); tvis.item.mask = TVIF_TEXT | TVIF_STATE; // added extra flag tvis.item.pszText = L"This is second subitem"; tvis.hInsertAfter = TVI_LAST; tvis.hParent = hRootItem; HTREEITEM hTreeSubItem2 = reinterpret_cast( SendMessage( TreeView , TVM_INSERTITEM, 0, reinterpret_cast( &tvis ) ) ); } return (INT_PTR)TRUE; 

Voici une citation intéressante de MSDN:

Version 5.80. Affiche une case à cocher même si aucune image n’est associée à l’élément.

C’est peut-être la cause de mon problème?

J’ai essayé de gérer TVN_KEYDOWN et de définir l’état des éléments ou encore de supprimer la case à cocher, mais sans succès.

EDIT # 2:

J’ai sous-classé l’arbre, comme l’a suggéré le membre Jonathan Potter , et cela a fonctionné:

 LRESULT CALLBACK TreeProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) { switch (message) { case WM_KEYDOWN: { // reject spacebar if tree node doesn't have checkbox if( wParam == VK_SPACE ) { HTREEITEM ht = TreeView_GetSelection( hwnd ); TVITEM tvItem; // Prepare to receive the desired information. tvItem.mask = TVIF_HANDLE | TVIF_STATE; tvItem.hItem = (HTREEITEM)ht; tvItem.stateMask = TVIS_STATEIMAGEMASK; // Request the information. TreeView_GetItem( hwnd, &tvItem ); // reject if it's not checked, or pass default value otherwise switch( tvItem.state >> 12 ) { case 0: MessageBeep(0); return FALSE; break; case 1: case 2: default: return ::DefSubclassProc( hwnd, message, wParam, lParam ); break; } } } break; case WM_NCDESTROY: ::RemoveWindowSubclass( hwnd, TreeProc, 0 ); break; } return ::DefSubclassProc( hwnd, message, wParam, lParam); } 

FIN DE L’EDIT

QUESTION:

Comment puis-je supprimer correctement la case à cocher d’un nœud d’arborescence afin qu’elle n’apparaisse plus jamais ?

Je vous remercie.

Meilleures salutations.

Sous- WM_KEYDOWN le contrôle, interceptez la touche espace via WM_KEYDOWN et ne transmettez pas le message si le focus est sur un élément pour lequel vous ne voulez pas avoir de case à cocher.