Jump to content

Treeview with checkboxes OnEvent behaviour


Recommended Posts

Well, I do have a couple issues related to a treeview.

First: An OnEvent function cannot be assigned to a tree item created using _GUICtrlTreeView_Add

#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)
Opt("GUIOnEventMode", 1)
$Debug_TV = False; Check ClassName being passed to functions, set to True and use a handle to another control to see it work

Global $Item1, $Item2
Global $hTreeView
Global $iStyle = BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
    
GUICreate("TreeView", 400, 300)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Close")
$hTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
$Item1 = GUICtrlCreateTreeViewItem("New Item 1", $hTreeView)
GUICtrlSetOnEvent($Item1, "Parent1Event")
$Item2 = _GUICtrlTreeView_Add($hTreeView, $Item1, "New Item 2")
GUICtrlSetOnEvent($Item2, "Parent2Event")
GUISetState()

While 1
    Sleep(100)
WEnd    

Func Parent1Event()
    MsgBox(0, "", "parent1")
EndFunc
Func Parent2Event()
    MsgBox(0, "", "parent2")
EndFunc
Func _Close()
    Exit
EndFunc

You can see that the function Parent1Event is triggered normally while Parent2Event is never called.

Since both GUICtrlCreateTreeViewItem and _GUICtrlTreeView_Add return the control handle I wonder why the latter doesn't work?

Second: Given a treeveiew with checkboxes, the event is triggered when:

- the checkbox is checked/unchecked

- the text label is clicked

- the node is expanding/collapsing

Q: can the event be triggered only by checking/unchecking the checkbox and not by other 2?

Any help is highly appreciated.

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

Since both GUICtrlCreateTreeViewItem and _GUICtrlTreeView_Add return the control handle I wonder why the latter doesn't work?

The problem is that _GUICtrlTreeView_Add returns a handle and GUICtrlSetOnEvent expects a controlid. Authenticity has a solution in this thread.
Link to comment
Share on other sites

@pickaxe

Thanks for your help. The link is very useful; I can see why it escaped to my search (I've searched for treeview +checkbox in the title).

Now this being clarified ... let's wait for a solution for my second issue :)

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

Q: can the event be triggered only by checking/unchecking the checkbox and not by other 2?

That seems like a useful feature. After playing with some help file and forum snippets. I ended up with this, which appears to do what you want.
#include <GUITreeView.au3>
#include <WindowsConstants.au3>
#include <GuiConstants.au3>

Opt("GUIOnEventMode", 1)

Global $hGUI = GUICreate('TreeView', 250, 300)
Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
Global $idTreeView = GUICtrlCreateTreeView(0, 0, 250, 300, $iStyle, $WS_EX_CLIENTEDGE)
Global $hTreeView = GUICtrlGetHandle($idTreeView)

_GUICtrlTreeView_BeginUpdate($hTreeView)
Global $idParent1 = GUICtrlCreateTreeViewItem('Parent1', $idTreeView)
Global $hParent1 = GUICtrlGetHandle($idParent1)
For $i = 1 To 5
    GUICtrlCreateTreeViewItem('Parent1 Child' & $i, $idParent1)
Next
For $i = 0 To 2
    _GUICtrlTreeView_SetCheckedByIndex($hTreeView, $hParent1, $i)
Next
Global $hParent2 = _GUICtrlTreeView_Add($hTreeView, 0, 'Parent2')
For $i = 1 To 5
    _GUICtrlTreeView_AddChild($hTreeView, $hParent2, 'Parent2 Child' & $i)
Next
_GUICtrlTreeView_SetState($hTreeView, $hParent1, $TVIS_EXPANDED)
_GUICtrlTreeView_SetState($hTreeView, $hParent2, $TVIS_EXPANDED)
_GUICtrlTreeView_EndUpdate($hTreeView)

GUISetOnEvent($GUI_EVENT_CLOSE, "TreeEvents")
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "TreeEvents")
;~ GUIRegisterMsg($WM_NOTIFY, 'OnNotify')
GUISetState()

While 1
    Sleep(20)
WEnd

;~ Func OnNotify($hwnd, $iMsg, $iwParam, $ilParam)
;~     Local $tNMTV = DllStructCreate($tagNMTREEVIEW, $ilParam)
;~     Local $hwndFrom = DllStructGetData($tNMTV, 'hWndFrom')
;~     Local $iCode = DllStructGetData($tNMTV, 'Code')
;~     If $hwndFrom = $hTreeView And $iCode = $TVN_SELCHANGED Then
;~         ConsoleWrite(_GUICtrlTreeView_GetText($hTreeView, DllStructGetData($tNMTV, 'NewhItem')) & @LF)
;~     EndIf
;~ EndFunc

Func TreeEvents()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE
            _GUICtrlTreeView_Destroy($hTreeView)
            GUIDelete()
            Exit
        Case $GUI_EVENT_PRIMARYDOWN
            Local $tMPos = _WinAPI_GetMousePos(True, $hTreeView) 
            Local $tHitTest = _GUICtrlTreeView_HitTestEx($hTreeView, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
            Local $iFlags = DllStructGetData($tHitTest, "Flags")
            If BitAND($iFlags, $TVHT_ONITEMSTATEICON) <> 0 Then
                Local $iItem = _GUICtrlTreeView_HitTestItem($hTreeView, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
                ConsoleWrite(_GUICtrlTreeView_GetText($hTreeView, $iItem) & " is checked = " & _GUICtrlTreeView_GetChecked($hTreeView, $iItem) & @LF)
            EndIf
    EndSwitch
EndFunc
Link to comment
Share on other sites

@picaxe

Thanks alot for your help, it works marvellous. I have to test it with a tree with images to see it it does the same.

I needed this feature on treeview because I needed to implement a "smart" checking-unchecking of parents/children.

I'm thinking an example would be welcome but I don't want to "steal" your idea so I would like to ask you if you would like do that check/uncheck example.

Something like: if a parent is checked/unchecked then it will check/uncheck the children, if a child is checked/unchecked then it will check/uncheck its parent and its own children ...

I really apreciate your help, and now I can continue working on that script :)

EDIT: tested with images and it works very well :party:

Edited by enaiman

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

Something like: if a parent is checked/unchecked then it will check/uncheck the children, if a child is checked/unchecked then it will check/uncheck its parent and its own children ...

You're welcome, try this
#include <GUITreeView.au3>
#include <WindowsConstants.au3>
#include <GuiConstants.au3>

Opt("GUIOnEventMode", 1)
Local $hGUI = GUICreate('TreeView', 300, 400)
Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
Local $idTreeView = GUICtrlCreateTreeView(0, 0, 300, 400, $iStyle, $WS_EX_CLIENTEDGE)
Global $hTreeView = GUICtrlGetHandle($idTreeView)
_GUICtrlTreeView_BeginUpdate($hTreeView)
Local $idParent1 = GUICtrlCreateTreeViewItem('Parent1', $idTreeView)
Local $hParent1 = GUICtrlGetHandle($idParent1)
$idLevel2 = GUICtrlCreateTreeViewItem('1-1', $idParent1)
For $i = 2 To 5
    GUICtrlCreateTreeViewItem('1-' & $i, $idParent1)
Next
$idLevel3 = GUICtrlCreateTreeViewItem('2-1', $idLevel2)
For $i = 2 To 5
    GUICtrlCreateTreeViewItem('2-' & $i, $idLevel2)
Next
$idLevel4 = GUICtrlCreateTreeViewItem('3-1', $idLevel3)
For $i = 2 To 5
    GUICtrlCreateTreeViewItem('3-' & $i, $idLevel3)
Next
For $i = 1 To 5
    GUICtrlCreateTreeViewItem('4-' & $i, $idLevel4)
Next

Local $idParent2 = GUICtrlCreateTreeViewItem('Parent2', $idTreeView)
Local $hParent2 = GUICtrlGetHandle($idParent2)
For $i = 1 To 5
    GUICtrlCreateTreeViewItem('2-' & $i, $idParent2)
Next
Local $idParent3 = GUICtrlCreateTreeViewItem('Parent3', $idTreeView)
Local $hParent3 = GUICtrlGetHandle($idParent3)
For $i = 1 To 5
    GUICtrlCreateTreeViewItem('3-' & $i, $idParent3)
Next
Local $idParent4 = GUICtrlCreateTreeViewItem('Parent4', $idTreeView)
Local $hParent4 = GUICtrlGetHandle($idParent4)

_GUICtrlTreeView_SetState($hTreeView, $hParent1, $TVIS_EXPANDED)
_GUICtrlTreeView_SetState($hTreeView, $hParent2, $TVIS_EXPANDED)
_GUICtrlTreeView_SetState($hTreeView, GUICtrlGetHandle($idLevel2), $TVIS_EXPANDED)
_GUICtrlTreeView_SetState($hTreeView, GUICtrlGetHandle($idLevel3), $TVIS_EXPANDED)
_GUICtrlTreeView_SetState($hTreeView, GUICtrlGetHandle($idLevel4), $TVIS_EXPANDED)
_GUICtrlTreeView_EndUpdate($hTreeView)

GUISetOnEvent($GUI_EVENT_CLOSE, "TreeEvents")
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "TreeEvents")
GUISetState()

While 1
    Sleep(20)
WEnd

Func TreeEvents()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE
            _GUICtrlTreeView_Destroy($hTreeView)
            GUIDelete()
            Exit
        Case $GUI_EVENT_PRIMARYDOWN
            Local $tMPos = _WinAPI_GetMousePos(True, $hTreeView)
            Local $tHitTest = _GUICtrlTreeView_HitTestEx($hTreeView, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
            Local $iFlags = DllStructGetData($tHitTest, "Flags")
            Select
                Case BitAND($iFlags, $TVHT_ONITEMSTATEICON)
                    Local $hItem = _GUICtrlTreeView_HitTestItem($hTreeView, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
                    Local $fChecked = False
                    If _GUICtrlTreeView_GetChecked($hTreeView, $hItem) Then $fChecked = True
                    _TvCheckbox($hItem, $fChecked)
            EndSelect
    EndSwitch
EndFunc   ;==>TreeEvents

Func _TvCheckbox($hTvItem, $fTvCheck)
    Local $hFirst, $hNext
    $hTvParent = _GUICtrlTreeView_GetParentHandle($hTreeView, $hTvItem)
    If $hTvParent = 0 Then $hTvParent = $hTvItem
    If $hTvParent Then _GUICtrlTreeView_SetChecked($hTreeView, $hTvParent, $fTvCheck)
    $hFirst = _GUICtrlTreeView_GetFirstChild($hTreeView, $hTvParent)
    If $hFirst Then
        $hNext = $hFirst
        While $hNext
            _GUICtrlTreeView_SetChecked($hTreeView, $hNext, $fTvCheck)
            If _GUICtrlTreeView_GetChildren($hTreeView, $hNext) Then _
                    _TvCheckbox(_GUICtrlTreeView_GetFirstChild($hTreeView, $hNext), $fTvCheck)
            $hNext = _GUICtrlTreeView_GetNextSibling($hTreeView, $hNext)
        WEnd
    EndIf
EndFunc   ;==>_TvCheckbox
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...