CMJ Posted March 2, 2011 Share Posted March 2, 2011 Why doesn't right clicking on an item in a tree view set that item as selected. The item appears to be selected but then when you act on the selected item the selection switches to the first item in the treeview. Here is a script that shows what I mean. In this example expand a parent, for example Parent 4, and right click on the child, Child 4-2. You will see the context menu but when you select delete it will delete Parent 1 and all of its children. However if you left click Child 4-1 before you right click on it, the delete function works as expected. Thanks in advance for any help. cj expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiTreeView.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Global $MenuParent, $gui, $contextmenu, $i, $n, $textitem, $Tree, $Child Main() While 1 Sleep(100) WEnd Func Main() $gui = GUICreate("Treeview Demo", 300, 500, -1, -1) $Tree = GUICtrlCreateTreeView(-1, -1, 300, 500) For $n = 1 to 9 $Parent = GUICtrlCreateTreeViewItem("Parent " & $n,$Tree) For $i = 1 to 3 $Child = GUICtrlCreateTreeViewItem("Child " & $n & "-" & $i,$Parent) contextMenu($Child) Next Next GUISetOnEvent($GUI_EVENT_CLOSE, 'Close') GUISetState(@SW_SHOW) EndFunc Func contextMenu($MenuParent) $contextmenu = GUICtrlCreateContextMenu($MenuParent) $textitem = GUICtrlCreateMenuItem("Delete", $contextmenu) GUICtrlSetOnEvent ( $textitem, "Delete" ) EndFunc Func Delete() _GUICtrlTreeView_Delete($Tree, _GUICtrlTreeView_GetSelection ($Tree)) EndFunc Func Close() Exit EndFunc Link to comment Share on other sites More sharing options...
CMJ Posted September 9, 2011 Author Share Posted September 9, 2011 I am going to bump this topic because I keep encountering this "bug". Anyone know if there is a work around? It is definitely only an issue with the treeview. List controls work as expected. If not is there a place that I can officially report this bug so that it can be fixed in the next release. Thanks in advance for any help. cj Link to comment Share on other sites More sharing options...
rover Posted September 10, 2011 Share Posted September 10, 2011 This is the default behaviour of a treeview, no bug Right click notifications from the treeview must be hit tested for the item under the mouse so the item can be selected. expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiTreeView.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Global $MenuParent, $gui, $contextmenu, $i, $n, $textitem, $Tree, $Child Global $Tree, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $fOnItem = False Main() While 1 Sleep(100) WEnd Func Main() $gui = GUICreate("Treeview Demo", 300, 500, -1, -1) $Tree = GUICtrlCreateTreeView(-1, -1, 300, 500) For $n = 1 to 9 $Parent = GUICtrlCreateTreeViewItem("Parent " & $n,$Tree) For $i = 1 to 3 $Child = GUICtrlCreateTreeViewItem("Child " & $n & "-" & $i,$Parent) contextMenu($Child) Next Next GUISetOnEvent($GUI_EVENT_CLOSE, 'Close') GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState(@SW_SHOW) EndFunc Func contextMenu($MenuParent) $contextmenu = GUICtrlCreateContextMenu($MenuParent) $textitem = GUICtrlCreateMenuItem("Delete", $contextmenu) GUICtrlSetOnEvent ( $textitem, "Delete" ) EndFunc Func Delete() ;If $fOnItem Then ;optionally block menu return from right click over non-item area ;$fOnItem = False _GUICtrlTreeView_Delete($Tree, _GUICtrlTreeView_GetSelection ($Tree)) ;EndIf EndFunc Func Close() Exit EndFunc Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom") $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $iIDFrom Case $Tree Switch $iCode Case $NM_RCLICK Local $tPoint = _WinAPI_GetMousePos(True, $hWndFrom), $tHitTest $tHitTest = _GUICtrlTreeView_HitTestEx($hWndFrom, DllStructGetData($tPoint, 1), DllStructGetData($tPoint, 2)) ;If BitAND(DllStructGetData($tHitTest, "Flags"), $TVHT_ONITEM) Then ;optionally block menu return from right click over non-item area ;$fOnItem = True Local $hItem = DllStructGetData($tHitTest, 'Item') If IsPtr($hItem) Then _GUICtrlTreeView_SelectItem($hWndFrom, $hItem) EndIf ;EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Asaman83687 and uncommon 2 I see fascists... Link to comment Share on other sites More sharing options...
CMJ Posted September 16, 2011 Author Share Posted September 16, 2011 (edited) Thanks for the reply Rover. Seems to work perfectly. Though I am not sure I understand hittesting. I guess I have more studying to do. cj Edit: Implemented and working great. Thanks again. As a followup question: Is there ever a time when you would want a right click not to select the item you right click on? Seems as if this could be "built in" to the functionality of the TreeView control. The ListView functions this way so it seem logical that the TreeView would follow suit. No? Edited September 16, 2011 by CMJ Link to comment Share on other sites More sharing options...
rover Posted September 16, 2011 Share Posted September 16, 2011 (edited) Thanks for the reply Rover. Seems to work perfectly. Though I am not sure I understand hittesting. I guess I have more studying to do. cj Edit: Implemented and working great. Thanks again. As a followup question: Is there ever a time when you would want a right click not to select the item you right click on? Seems as if this could be "built in" to the functionality of the TreeView control. The ListView functions this way so it seem logical that the TreeView would follow suit. No? Hit testing determines if there is a treeview/listview item under the mouse, and, if the mouse is over an allowable area of the item. (over checkbox, icon, text, or if over a non item element such as the header or blank areas) Very useful for limiting a contextmenu to treeview/listview items. Read the Wiki for an explanation of message handling with GUIRegisterMsg (NM_RCLICK) http://www.autoitscript.com/wiki/GUIRegisterMsg If you want the default treeview behaviour, this example bounces back to the previously selected/focused item after deleting a right clicked item. I've added _GUICtrlTreeView_SetFocused($Tree, $hItemSel, True) to the code, and it should be added to the other example as well. It seems there is an issue under some circumstances if the right clicked item is not given focus (mentioned on an MSDN forum) though I don't see any problem here. Is there ever a time when you would want a right click not to select the item you right click on? I can only point to Explorer as an example. Selecting a contextmenu action on a drive/folder other than the currently selected drive/folder doesn't change the currently selected drive/folder in the right pane listview. I'll hazard a guess that this is the reason for this treeview design feature. Seems as if this could be "built in" to the functionality of the TreeView control. The ListView functions this way so it seem logical that the TreeView would follow suit. No? This is a user preference change of a Microsoft Common Controls default behaviour. The AutoIt devs will reject a user preference change request for a common controls default behaviour. Requested changes that can be easily implemented by a UDF and are of minimal utility to the broader community of AutoIt users are always rejected. A read of the Closed Requests list in TRAC will give you some idea of what gets rejected. expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiTreeView.au3> #include <WindowsConstants.au3> Opt('MustDeclareVars', 1) Opt("GUIOnEventMode", 1) Global $MenuParent, $Parent, $gui, $contextmenu, $i, $n, $textitem, $Tree, $Child Global $Tree, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $fOnItem = False Global $hItemSel Main() While 1 Sleep(100) WEnd Func Main() $gui = GUICreate("Treeview Demo", 300, 500, -1, -1) $Tree = GUICtrlCreateTreeView(-1, -1, 300, 500) For $n = 1 to 9 $Parent = GUICtrlCreateTreeViewItem("Parent " & $n,$Tree) For $i = 1 to 3 $Child = GUICtrlCreateTreeViewItem("Child " & $n & "-" & $i,$Parent) contextMenu($Child) Next Next GUISetOnEvent($GUI_EVENT_CLOSE, 'Close') GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState(@SW_SHOW) EndFunc Func contextMenu($MenuParent) $contextmenu = GUICtrlCreateContextMenu($MenuParent) $textitem = GUICtrlCreateMenuItem("Delete", $contextmenu) GUICtrlSetOnEvent ( $textitem, "Delete" ) EndFunc Func Delete() ;If $fOnItem Then ;optionally block menu return from right click over non-item area ;$fOnItem = False If IsPtr($hItemSel) Then _GUICtrlTreeView_SetFocused($Tree, $hItemSel, True) _GUICtrlTreeView_Delete($Tree, $hItemSel) $hItemSel = 0 EndIf ;_GUICtrlTreeView_Delete($Tree, _GUICtrlTreeView_GetSelection ($Tree)) ;EndIf EndFunc Func Close() Exit EndFunc Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom") $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $iIDFrom Case $Tree Switch $iCode Case $NM_RCLICK Local $tPoint = _WinAPI_GetMousePos(True, $hWndFrom), $tHitTest $tHitTest = _GUICtrlTreeView_HitTestEx($hWndFrom, DllStructGetData($tPoint, 1), DllStructGetData($tPoint, 2)) ;If BitAND(DllStructGetData($tHitTest, "Flags"), $TVHT_ONITEM) Then ;optionally block menu return from right click over non-item area ;$fOnItem = True $hItemSel = DllStructGetData($tHitTest, 'Item') ;Local $hItem = DllStructGetData($tHitTest, 'Item') ;~ If IsPtr($hItem) Then ;~ _GUICtrlTreeView_SelectItem($hWndFrom, $hItem) ;~ _GUICtrlTreeView_SetFocused($hWndFrom, $hItem, True) ;~ EndIf ;EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Edited September 16, 2011 by rover I see fascists... Link to comment Share on other sites More sharing options...
CMJ Posted September 18, 2011 Author Share Posted September 18, 2011 Thanks for the info. I see your point about the tree view selection. I had not considered the explorer behavior. Seems obvious now. Thanks again. cj Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now