Jump to content
Sign in to follow this  
this-is-me

Prevent keyboard navigation events from firing treeviewitem event

Recommended Posts

My intention is to allow a treeviewitem event to be fired when the user single-clicks on the item, but not when the user uses the keyboard to navigate the treeview. The only time I need the keyboard to fire the event is when the user hits enter. Here is an example script:

#include <GUIConstants.au3>
#include <GuiTreeView.au3>
Opt("GuiOnEventMode", 1)

GUICreate("Treeview Test", 200, 200)
GUISetOnEvent($GUI_EVENT_CLOSE, "bye")

$treeview = GUICtrlCreateTreeView(0, 0, 200, 200)
$general = GUICtrlCreateTreeViewitem("General", $treeview)
GUICtrlSetOnEvent(-1, "togglefolder")
GUICtrlCreateTreeViewitem("Setting 1", $general)
GUICtrlSetOnEvent(-1, "msg")
GUICtrlCreateTreeViewitem("Setting 2", $general)
GUICtrlSetOnEvent(-1, "msg")
GUICtrlCreateTreeViewitem("Setting 3", $general)
GUICtrlSetOnEvent(-1, "msg")
GUICtrlCreateTreeViewitem("Setting 4", $general)
GUICtrlSetOnEvent(-1, "msg")
GUISetState()

While 1
    Sleep(1000)
WEnd

Func bye()
    Exit
EndFunc

Func msg()
    MsgBox(0,"",@GUI_CtrlId)
EndFunc

Func togglefolder()
    If _GUICtrlTreeView_GetChildren($treeview, @GUI_CtrlId) Then
        If _GUICtrlTreeView_GetExpanded($treeview, @GUI_CtrlId) Then
            _GUICtrlTreeView_Expand($treeview, @GUI_CtrlId, 0)
        Else
            _GUICtrlTreeView_Expand($treeview, @GUI_CtrlId, 1)
        EndIf
    EndIf
EndFunc

In this case, using the keyboard up/down arrows will fire the event as well.

Share this post


Link to post
Share on other sites

I realise this isn't a pretty way to do it, but it works

#include <GUIConstants.au3>
#include <GuiTreeView.au3>
#include <Misc.au3>

Opt("GuiOnEventMode", 1)

GUICreate("Treeview Test", 200, 200)
GUISetOnEvent($GUI_EVENT_CLOSE, "bye")

$treeview = GUICtrlCreateTreeView(0, 0, 200, 200)
$general = GUICtrlCreateTreeViewitem("General", $treeview)
GUICtrlSetOnEvent(-1, "togglefolder")
GUICtrlCreateTreeViewitem("Setting 1", $general)
GUICtrlSetOnEvent(-1, "msg")
GUICtrlCreateTreeViewitem("Setting 2", $general)
GUICtrlSetOnEvent(-1, "msg")
GUICtrlCreateTreeViewitem("Setting 3", $general)
GUICtrlSetOnEvent(-1, "msg")
GUICtrlCreateTreeViewitem("Setting 4", $general)
GUICtrlSetOnEvent(-1, "msg")
GUISetState()

While 1
    Sleep(100)
WEnd

Func bye()
    Exit
EndFunc

Func msg()
    For $i = 25 To 28
        If _IsPressed($i) Then Return
    Next    
    MsgBox(0,"",@GUI_CtrlId)
EndFunc

Func togglefolder()
    If _GUICtrlTreeView_GetChildren($treeview, @GUI_CtrlId) Then
        If _GUICtrlTreeView_GetExpanded($treeview, @GUI_CtrlId) Then
            _GUICtrlTreeView_Expand($treeview, @GUI_CtrlId, 0)
        Else
            _GUICtrlTreeView_Expand($treeview, @GUI_CtrlId, 1)
        EndIf
    EndIf
EndFunc

Cheers

Share this post


Link to post
Share on other sites

I am sorry, but this is not reliable when there are a lot of treeview items and moving with the keyboard quickly. I have attached an example script and a small video showing when the error occurs. It only seems to happen when moving rapidly with the keyboard keys and then stopping to either change direction or go slower.

menu.zip

Can anyone recommend a better alternative?

Share this post


Link to post
Share on other sites

Yes

#include <GUIConstants.au3>
#include <GuiTreeView.au3>
Opt("GuiOnEventMode", 1)

$bKeypress = False

GUICreate("Treeview Test", 200, 200)
GUISetOnEvent($GUI_EVENT_CLOSE, "bye")

$treeview = GUICtrlCreateTreeView(0, 0, 200, 200)
$general = GUICtrlCreateTreeViewitem("General", $treeview)
GUICtrlSetOnEvent(-1, "togglefolder")
For $i = 1 to 100
    GUICtrlCreateTreeViewitem("Setting " & $i, $general)
    GUICtrlSetOnEvent(-1, "msg")
Next

GUISetState()

GUIRegisterMsg($WM_NOTIFY, "On_WM_NOTIFY")
While 1
    Sleep(100)
WEnd

Func bye()
    Exit
EndFunc

Func On_WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    If $wParam <> $treeview Then Return $GUI_RUNDEFMSG
    Local $tNMHDR, $tNMTVKEYDOWN
    $tNMHDR = DllStructCreate("hwnd hwndFrom;uint idFrom;int code", $lParam)
    Switch DllStructGetData($tNMHDR, "code")
        Case $TVN_KEYDOWN
            $tNMTVKEYDOWN = DllStructCreate("hwnd;uint;int;short wVKey;uint flags", $lParam)
            ConsoleWrite("Treeview keypress: " & DllStructGetData($tNMTVKEYDOWN, "wVKey") & @CRLF)
            $bKeypress = True
    EndSwitch
    Return $GUI_RUNDEFMSG   
EndFunc

Func msg()
    If $bKeypress Then
        $bKeypress = False
        Return
    EndIf
    MsgBox(0,"",@GUI_CtrlId)
EndFunc

Func togglefolder()
    If _GUICtrlTreeView_GetChildren($treeview, @GUI_CtrlId) Then
        If _GUICtrlTreeView_GetExpanded($treeview, @GUI_CtrlId) Then
            _GUICtrlTreeView_Expand($treeview, @GUI_CtrlId, 0)
        Else
            _GUICtrlTreeView_Expand($treeview, @GUI_CtrlId, 1)
        EndIf
    EndIf
EndFunc

Might need some added compares of keycodes to make it more reliable and bug free. For example, left and right arrows do not trigger controlevent when there is no selection change, so no need to set $bKeypress in such case.

Other than that, subclass the treeview to catch and reject unnecessary keydown messages probably would be the most reliable method.

Edited by Siao

"be smart, drink your wine"

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  

×
×
  • Create New...