Sign in to follow this  
Followers 0
CMJ

TreeView, ItemParam and SetOnEvent

8 posts in this topic

Hello,

I have only been using Autoit for a few days but I am finding it fairly easy to pick up. I have run into my first snag though and I can't seem to figure this out.

I am having trouble with the GUICtrlSetOnEvent function. Below is a simplified version of the script that is not working. When you run this you will get a tree view with some test items. The problem is that if you click a sub item under #1, 2, 3, 4, 9 nothing happens but under #5, 6, 7, 8, 10 pressing click here will display the ItemParam (which is set to the item parent).

I am sure I am doing several things wrong but can anyone point me in the right directions on why the set event seems to work intermittently?

Thanks,

cj

#include <GUIConstantsEx.au3>
#include <TreeViewConstants.au3>
#include <WindowsConstants.au3>
#Include <GuiTreeView.au3>
#Region ### START Koda GUI section ### Form=

Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode

GUISetOnEvent($GUI_EVENT_CLOSE, 'Close')

$Form1 = GUICreate("Form1", 300, 443, 196, 128)
$TreeView1 = GUICtrlCreateTreeView(0, 0, 297, 441)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Global $i, $n

For $i = 1 To 10

    $Parent = GUICtrlCreateTreeViewItem($i, $TreeView1)


    For $n = 1 To 4

        $Child = GUICtrlCreateTreeViewItem("Click Here", $Parent)
        Local $Test = $i & " " & $n
        _GUICtrlTreeView_SetItemParam($TreeView1, $Child, $i)
        GUICtrlSetOnEvent ( $Child, "TreeView_Selection" )
    Next
Next

Func TreeView_Selection ()
    MsgBox(0,"",_GUICtrlTreeView_GetItemParam($TreeView1))
EndFunc

Func Close ()
    Exit
EndFunc

While 1
Sleep(1000)
WEnd

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

CMJ,

Welcome to the AutoIt forum. :)

If you look at the example for _GUICtrlTreeView_SetItemParam in the Help file you see the following:

; Warning do not use SetItemParam on items created with GUICtrlCreateTreeViewItem

; Param is the controlId for items created with the built-in function

Basically when you use the UDF function you are overwriting the value that AutoIt uses to keep track of the Items it has created. This is why your GUICtrlSetOnEvent fails - AutoIt no longer has the data it requires to track the controls it created. Mixing built-in and UDF functions in this way often ends in tears. :P

Try this version where you do not overwrite the $iParam value set by AutoIt:

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

Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode

$Form1 = GUICreate("Form1", 300, 443, 196, 128)
GUISetOnEvent($GUI_EVENT_CLOSE, 'Close')
$TreeView1 = GUICtrlCreateTreeView(0, 0, 297, 441)
GUISetState(@SW_SHOW)

For $i = 1 To 10

    $Parent = GUICtrlCreateTreeViewItem($i, $TreeView1)
    For $n = 1 To 4
        $Child = GUICtrlCreateTreeViewItem("Click Here", $Parent)
        Local $Test = $i & " " & $n
       ; _GUICtrlTreeView_SetItemParam($TreeView1, $Child, $i)
        GUICtrlSetOnEvent ( $Child, "TreeView_Selection" )
    Next
Next

Func TreeView_Selection ()
    MsgBox(0,"",_GUICtrlTreeView_GetItemParam($TreeView1))
EndFunc

Func Close ()
    Exit
EndFunc

While 1
Sleep(1000)
WEnd

Now you see you get the ControlID returned for all the children.

By the way, I also moved the GUISetOnEvent($GUI_EVENT_CLOSE, 'Close') line, so it had a GUI to refer to! o:)

All clear? Please ask if not. ;)

M23

P.S. You are not the CMJ from R4-TMS by any chance? ;)

Edit: Added welcome.

Edited by Melba23

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

CMJ,

Welcome to the AutoIt forum. ;)

...

All clear? Please ask if not. :)

M23

First, thanks for the quick reply and I will assume that since I do not know what R4-TMS is that it is not me.

But I guess that you have found the flaw in my logic. The problem is that I need to set a unique ID for each treeview item and when I saw the Set Param function I figured it would work. I need to be able to set this id and then recall it when the items is selected. The reason for all this is that I am generating my treeview from data in a sqlite db. This is working fine but the problem is that when the item is selected I would like to query the db using the item's unique id from the table (which is not displayed).

For Example: Let's say that I have a table that has a list of students. I am putting that list of students into my treeview and then when the student is selected I want to display the list of classes that the selected student is taking.

Grade 1

-Smith, Bill

-Jones, Tom

Grade 2

-Perkins, Suzy

-Jenkins, Jim

etc...

I figured that I could store the ControlID of each back in my db but it seems like there should be an easier way to store this id with the control and not display it.

Any thoughts?

Thanks again

cj

Share this post


Link to post
Share on other sites

CMJ,

I would use a cross indexing array within the script like this: ;)

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

#include <Array.au3>

; Create an array for cross indexing ControlIDs and StudentID numbers
Global $aCrossRef[1][2] = [[0]]

Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode

; Here you woudl get the list of grades from your db
$aGrades = IniReadSectionNames("DB.ini")

$Form1 = GUICreate("Form1", 300, 443, 196, 128)
GUISetOnEvent($GUI_EVENT_CLOSE, 'Close')
$TreeView1 = GUICtrlCreateTreeView(0, 0, 297, 441)
GUISetState(@SW_SHOW)

; Then for each grade
For $i = 1 To $aGrades[0]

    ; Create the parent
    $Parent = GUICtrlCreateTreeViewItem($aGrades[$i], $TreeView1)

    ; Now get the students in the class from your db
    $aStudents = IniReadSection("DB.ini", $aGrades[$i])

    ; Resize the cross index array as required
    $iNewSize = UBound($aCrossRef) + $aStudents[0][0]
    ReDim $aCrossRef[$iNewSize][2]

    ; Add the students into the tree
    For $n = 1 To $aStudents[0][0]
        $Child = GUICtrlCreateTreeViewItem($aStudents[$n][1], $Parent)
        GUICtrlSetOnEvent($Child, "TreeView_Selection")
        ; Increase the count for each student
        $aCrossRef[0][0] += 1
        ; And save the ControlID and the Student ID into the cross index array
        $aCrossRef[$aCrossRef[0][0]][0] = $Child
        $aCrossRef[$aCrossRef[0][0]][1] = $aStudents[$n][0]
    Next
Next

Func TreeView_Selection ()
    ; Get the ControlID of the clicked student
    $iCID = _GUICtrlTreeView_GetItemParam($TreeView1)
    ; Search for it in the cross index array
    $iIndex = _ArraySearch($aCrossRef, $iCID)
    ; Display the associated StudentID
    MsgBox(0, "", $aCrossRef[$iIndex][1])
EndFunc

Func Close ()
    Exit
EndFunc

While 1
Sleep(1000)
WEnd

I used this ini file to illustrate the concept:

[Grade 1]
001=Smith, Bill
002=Jones, Tom
[Grade 2]
003=Perkins, Suzy
004=Jenkins, Jim

You will have to modify the script to pull the data from your DB.

I hope that helps. :)

M23

P.S. To explain the R4-TMS reference. While replying to you I was listening to the gripping England-Pakistan Test match (that is cricket if you are not from one of the Test nations) on BBC Radio 4 - the programme is known as Test Match Special and one of the commentators is Chris Martin-Jenkins, more commonly referred to as CMJ. I did not really think that you were one and the same, but it amused me at the time. ;)


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

$iIndex = _ArraySearch($aCrossRef, $iCID)

I hope that helps. ;)

M23

Just to cut in. :)

THANKS M23 that one line of code!

I've been using _GUICtrlTreeView_SetItemParam in one of my programs to save an array position and wondered why OTHER buttons were being pressed when I clicked in the tree. FINALLY found that the Param was the controlID and that is what was doing it.

I missed the

; Warning do not use SetItemParam on items created with GUICtrlCreateTreeViewItem

; Param is the controlId for items created with the built-in function

Comment in the example code. ;)

Anyway my solution was just to add 100 to the arrey position and use that for the SetItemParam. Of course if I ended up with more than 100 controls on the form I was going to be in trouble again.

Your solution is MUCH more elegant and works perfectly!

THANK YOU!

Share this post


Link to post
Share on other sites

storme,

Delighted I could help you out - even if I did not realise it at the time! :)

I learnt about how AutoIt deals with TreeViews internally and the $iParam "problem" from this thread if you are interested. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Just to cut in. ;)

THANKS M23 that one line of code!

I've been using _GUICtrlTreeView_SetItemParam in one of my programs to save an array position and wondered why OTHER buttons were being pressed when I clicked in the tree. FINALLY found that the Param was the controlID and that is what was doing it.

I missed the

Comment in the example code. :)

Anyway my solution was just to add 100 to the arrey position and use that for the SetItemParam. Of course if I ended up with more than 100 controls on the form I was going to be in trouble again.

Your solution is MUCH more elegant and works perfectly!

THANK YOU!

I missed that comment too! Seems like it should be under the remarks section, No?

Thanks for the help M23. I am working on implementing this now.

Share this post


Link to post
Share on other sites

CMJ,

it should be under the remarks section

I have opened ticket #1749 asking for just that. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

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