Sign in to follow this  
Followers 0
Yonekura

TreeView Select Item On Right and Left Click

8 posts in this topic

#1 ·  Posted (edited)

Hello, I pretty sure this is a simple question. I have a treeveiw with a context menu. When I left click to select an item and then right click to pull up my context menu everything works fine. However, when I right click on different item, it appears to be selected, but it is not. If I let off the right click button without choosing on option in my context menu it springs back to the previously selected item. If I choose an option from my context menu it acts as if the previously selected item is currently selected. It's like focusing on the item, but not really selecting the item when I right click.

So how can select the item on a right click instead of just focusing? I am not using and event loop but GUICtrlSetOnEvent to determine when and item clicked or changed.

Or is there a way to disable a focus change on a right click because that would work too.

Edited by yonekura

Share this post


Link to post
Share on other sites



Post your code or a reproducer.


Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Okay here is some code I quickly wrote up that reproduces the problem.

#include <GuiMenu.au3>
#include <GuiTreeView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <TreeViewConstants.au3>

Global $idUI        = GUICreate("Reproducer", 210, 482, -1, -1,  BitOR($WS_CAPTION, $WS_SYSMENU), $WS_EX_COMPOSITED)
Global $TreeStyles  = BitOR($TVS_HASLINES, $TVS_SHOWSELALWAYS, $TVS_HASBUTTONS, $WS_VSCROLL, $WS_HSCROLL, $TVS_DISABLEDRAGDROP, $TVS_LINESATROOT)
Global $idItemTree  = GUICtrlCreateTreeView(5, 5, 200, 472, $TreeStyles, $WS_EX_CLIENTEDGE)
;lets add 6 items 
Global $idBrowsers  = GUICtrlCreateTreeViewItem("Browsers", $idItemTree)
Global $idFirefox   = GUICtrlCreateTreeViewItem("Firefox", $idBrowsers)
Global $idChrome    = GUICtrlCreateTreeViewItem("Chrome", $idBrowsers)

Global $idFruit     = GUICtrlCreateTreeViewItem("Fruit", $idItemTree)
Global $idOranges   = GUICtrlCreateTreeViewItem("Oranges", $idFruit)
Global $idPears     = GUICtrlCreateTreeViewItem("Pears", $idFruit)

GUICtrlSetImage($idBrowsers, "imageres.dll", 5)
GUICtrlSetImage($idFruit, "imageres.dll", 5)

GUICtrlSetImage($idFirefox, "shell32.dll", 278)
GUICtrlSetImage($idChrome, "shell32.dll", 278)
GUICtrlSetImage($idOranges, "shell32.dll", 278)
GUICtrlSetImage($idPears, "shell32.dll", 278)

_GUICtrlTreeView_Expand($idItemTree)
_GUICtrlTreeView_Sort($idItemTree)

;Let create the context menu
Global $idTreeContext   = GUICtrlCreateContextMenu($idItemTree)
Global $idAddMenu   = GUICtrlCreateMenuItem("Add New Item", $idTreeContext)
Global $idDeleteMenu    = GUICtrlCreateMenuItem("Delete Selected", $idTreeContext)

GUISetState(@SW_SHOW, $idUI)

;Lets register events
Opt("GUIOnEventMode", 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "terminate", $idUI)
GUICtrlSetOnEvent($idAddMenu    , "add_item")
GUICtrlSetOnEvent($idDeleteMenu , "delete_item")

Func terminate()
    Exit
EndFunc

Func delete_item()
    Local $idSelItem = _GUICtrlTreeView_GetSelection($idItemTree)
    MsgBox(0,"Selected Item", "The selected item is:"&_GUICtrlTreeView_GetText($idItemTree,  $idSelItem))
    ;delete it just an example don't worry about childern objects
    _GUICtrlTreeView_Delete($idItemTree, $idSelItem)
EndFunc

Func add_item()
    Local $sName = InputBox("New Item", "Enter a name for the new item", "", "", 100, 125)
    If (@error=0) Then
        Local $idNew=GUICtrlCreateTreeViewItem($sName, $idItemTree)
        GUICtrlSetImage($idNew, "shell32.dll", 278)
    EndIf
EndFunc

;do other stuff
while 1
    Sleep(10)
WEnd
Edited by Yonekura
1 person likes this

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Well after reading around I think I found a solution. I did not find any functions that did what wanted at  GuiTreeView Management. So I looked around and ended up Creating an event with GUIRegisterMsg of type $WM_NOTIFY. After finding similar problems and their solution code.  However, it does seem a bit hacky to me though? Any other better solutions?

#include <GuiMenu.au3>
#include <GuiTreeView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <TreeViewConstants.au3>

Global $idUI        = GUICreate("Reproducer", 210, 482, -1, -1,  BitOR($WS_CAPTION, $WS_SYSMENU), $WS_EX_COMPOSITED)
Global $TreeStyles  = BitOR($TVS_HASLINES, $TVS_SHOWSELALWAYS, $TVS_HASBUTTONS, $WS_VSCROLL, $WS_HSCROLL, $TVS_DISABLEDRAGDROP, $TVS_LINESATROOT)
Global $idItemTree  = GUICtrlCreateTreeView(5, 5, 200, 472, $TreeStyles, $WS_EX_CLIENTEDGE)
;lets add 6 items 
Global $idBrowsers= GUICtrlCreateTreeViewItem("Browsers", $idItemTree)
Global $idFirefox   = GUICtrlCreateTreeViewItem("Firefox", $idBrowsers)
Global $idChrome    = GUICtrlCreateTreeViewItem("Chrome", $idBrowsers)

Global $idFruit         = GUICtrlCreateTreeViewItem("Fruit", $idItemTree)
Global $idOranges   = GUICtrlCreateTreeViewItem("Oranges", $idFruit)
Global $idPears = GUICtrlCreateTreeViewItem("Pears", $idFruit)

GUICtrlSetImage($idBrowsers, "imageres.dll", 5)
GUICtrlSetImage($idFruit, "imageres.dll", 5)

GUICtrlSetImage($idFirefox, "shell32.dll", 278)
GUICtrlSetImage($idChrome, "shell32.dll", 278)
GUICtrlSetImage($idOranges, "shell32.dll", 278)
GUICtrlSetImage($idPears, "shell32.dll", 278)

_GUICtrlTreeView_Expand($idItemTree)
_GUICtrlTreeView_Sort($idItemTree)

;Let create the context menu
Global $idTreeContext   = GUICtrlCreateContextMenu($idItemTree)
Global $idAddMenu   = GUICtrlCreateMenuItem("Add New Item", $idTreeContext)
Global $idDeleteMenu    = GUICtrlCreateMenuItem("Delete Selected", $idTreeContext)

GUISetState(@SW_SHOW, $idUI)

;Let register events
Opt("GUIOnEventMode", 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "terminate", $idUI)
GUICtrlSetOnEvent($idAddMenu    , "add_item")
GUICtrlSetOnEvent($idDeleteMenu , "delete_item")
;Register a windows event/msg
GUIRegisterMsg($WM_NOTIFY , "RIGHTSEL_WM_NOTIFY")

Func terminate()
    Exit
EndFunc

Func delete_item()
    Local $idSelItem = _GUICtrlTreeView_GetSelection($idItemTree)
    MsgBox(0,"Selected Item", "The selected item is:"&_GUICtrlTreeView_GetText($idItemTree,  $idSelItem))
    ;delete it just an example don't worry about childern objects
    _GUICtrlTreeView_Delete($idItemTree, $idSelItem)
EndFunc

Func add_item()
    Local $sName = InputBox("New Item", "Enter a name for the new item", "", "", 100, 125)
    If (@error=0) Then
        Local $idNew=GUICtrlCreateTreeViewItem($sName, $idItemTree)
        GUICtrlSetImage($idNew, "shell32.dll", 278)
    EndIf
EndFunc

Func RIGHTSEL_WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    ;Notsure what DLLStructure functions do exactly but I feel it can be 
    ;Performed with bitwise and bit shifting operators
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    IF (($iIDFrom=$idItemTree) AND ($iCode=$NM_RCLICK)) Then
        Local $iMouseX =_WinAPI_GetMousePosX (True, $hWndFrom)
        Local $iMouseY =_WinAPI_GetMousePosY (True, $hWndFrom)
        Local $hItemSel  =_GUICtrlTreeView_HitTestItem($hWndFrom, $iMouseX, $iMouseY)
        Local $iHitStat    =_GUICtrlTreeView_HitTest ($hWndFrom, $iMouseX, $iMouseY)
        ;Only update the selected item if right click is in the objects area
        If (NOT(64 < $iHitStat) AND ($iHitStat > 1)) Then
            If IsPtr($hItemSel)Then
                _GUICtrlTreeView_SelectItem($hWndFrom, $hItemSel)
                _GUICtrlTreeView_SetFocused($hWndFrom, $hItemSel, True)
            EndIf
        EndIf
    EndIF
    Return $GUI_RUNDEFMSG
EndFunc

;do other stuff
while 1
    Sleep(10)
WEnd
Edited by Yonekura

Share this post


Link to post
Share on other sites

I have waited a few days, and I have not heard anything back. Is what I have a fine solution?

Share this post


Link to post
Share on other sites

This is basically the same method (maybe a tiny bit more efficient). Also I find it's easier to read and looks nicer.

#include <GuiMenu.au3>
#include <GuiTreeView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <TreeViewConstants.au3>

Global $idUI        = GUICreate("Reproducer", 210, 482, -1, -1,  BitOR($WS_CAPTION, $WS_SYSMENU), $WS_EX_COMPOSITED)
Global $TreeStyles  = BitOR($TVS_HASLINES, $TVS_SHOWSELALWAYS, $TVS_HASBUTTONS, $WS_VSCROLL, $WS_HSCROLL, $TVS_DISABLEDRAGDROP, $TVS_LINESATROOT)
Global $idItemTree  = GUICtrlCreateTreeView(5, 5, 200, 472, $TreeStyles, $WS_EX_CLIENTEDGE)
;lets add 6 items
Global $idBrowsers= GUICtrlCreateTreeViewItem("Browsers", $idItemTree)
Global $idFirefox   = GUICtrlCreateTreeViewItem("Firefox", $idBrowsers)
Global $idChrome    = GUICtrlCreateTreeViewItem("Chrome", $idBrowsers)

Global $idFruit         = GUICtrlCreateTreeViewItem("Fruit", $idItemTree)
Global $idOranges   = GUICtrlCreateTreeViewItem("Oranges", $idFruit)
Global $idPears = GUICtrlCreateTreeViewItem("Pears", $idFruit)

GUICtrlSetImage($idBrowsers, "imageres.dll", 5)
GUICtrlSetImage($idFruit, "imageres.dll", 5)

GUICtrlSetImage($idFirefox, "shell32.dll", 278)
GUICtrlSetImage($idChrome, "shell32.dll", 278)
GUICtrlSetImage($idOranges, "shell32.dll", 278)
GUICtrlSetImage($idPears, "shell32.dll", 278)

_GUICtrlTreeView_Expand($idItemTree)
_GUICtrlTreeView_Sort($idItemTree)

;Let create the context menu
Global $idTreeContext   = GUICtrlCreateContextMenu($idItemTree)
Global $idAddMenu   = GUICtrlCreateMenuItem("Add New Item", $idTreeContext)
Global $idDeleteMenu    = GUICtrlCreateMenuItem("Delete Selected", $idTreeContext)

GUISetState(@SW_SHOW, $idUI)

;Let register events
Opt("GUIOnEventMode", 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "terminate", $idUI)
GUICtrlSetOnEvent($idAddMenu    , "add_item")
GUICtrlSetOnEvent($idDeleteMenu , "delete_item")
;Register a windows event/msg
GUIRegisterMsg($WM_NOTIFY , "WM_NOTIFY")

Func terminate()
    Exit
EndFunc

Func delete_item()
    Local $idSelItem = _GUICtrlTreeView_GetSelection($idItemTree)
    MsgBox(0,"Selected Item", "The selected item is:"&_GUICtrlTreeView_GetText($idItemTree,  $idSelItem))
    ;delete it just an example don't worry about childern objects
    _GUICtrlTreeView_Delete($idItemTree, $idSelItem)
EndFunc

Func add_item()
    Local $sName = InputBox("New Item", "Enter a name for the new item", "", "", 100, 125)
    If (@error=0) Then
        Local $idNew=GUICtrlCreateTreeViewItem($sName, $idItemTree)
        GUICtrlSetImage($idNew, "shell32.dll", 278)
    EndIf
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 $idItemTree
            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 _GUICtrlTreeView_SelectItem($hWndFrom, DllStructGetData($tHitTest, 'Item'))
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

;do other stuff
while 1
    Sleep(10)
WEnd

Found here:

I couldn't find another solution. It seems there is no simple setting you could change, to add the secondary mousebutton as a valid select trigger.

Share this post


Link to post
Share on other sites

The issue is that the right click is not detected, tried many functions, but they all depend on the LEFT click first to work. :(


Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

 

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Okay well if that case. I guess I will stick with what I have. Unless someone has some major improvements.

Edited by Yonekura

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0