Jump to content

_GUICtrlTreeView_SetChildren behaves differently in version 3.3.16.1


Recommended Posts

Hi, I just upgraded the newest AutoIt version 3.3.16.1 and my treeviews dont work anymore. I figured out that the function [_GUICtrlTreeView_SetChildren] has been changed and causes my problems. I attached a samplew code showing the differences.

 

#include <GUITreeView.au3>
#include <GUIConstantsEx.au3>

Example()

Func Example()

    GUICreate("_GUICtrlTreeView_SetChildren", 350, 215)
    GUISetState(@SW_SHOW)

    Local Const $iTreeView1 = GUICtrlCreateTreeView(5, 5, 100, 100, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_INFOTIP, $TVS_LINESATROOT, $TVS_SHOWSELALWAYS), -1)
    Local Const $hTreeView1 = GUICtrlGetHandle($iTreeView1)

    Local $hItem = _GUICtrlTreeView_Add($hTreeView1, 0, "x")
    ; Works, plus is shown indicating the node has a child and one can react on the EXPAND-event
    _GUICtrlTreeView_SetChildren_OLD($hTreeView1, $hItem, True)


    Local Const $iTreeView2 = GUICtrlCreateTreeView(110, 5, 100, 100, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_INFOTIP, $TVS_LINESATROOT, $TVS_SHOWSELALWAYS), -1)
    Local Const $hTreeView2 = GUICtrlGetHandle($iTreeView2)

    $hItem = _GUICtrlTreeView_Add($hTreeView2, 0, "y")

    ; --->>> DOES NOT WORK !!! <<<---
    _GUICtrlTreeView_SetChildren_NEW($hTreeView2, $hItem, True)

    ;GUIRegisterMsg($WM_NOTIFY, $_WM_NOTIFY)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

EndFunc

Func _WM_NOTIFY(Const $hWnd, Const $iMsg, Const $wParam, Const $lParam)
    Return $GUI_RUNDEFMSG
EndFunc

; ************************
; *** Autoit Functions ***
; ************************

Func _GUICtrlTreeView_SetChildren_OLD($hWnd, $hItem, $bFlag = True)
    If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    Local $tItem = DllStructCreate($tagTVITEMEX)
    DllStructSetData($tItem, "Mask", BitOR($TVIF_HANDLE, $TVIF_CHILDREN))
    DllStructSetData($tItem, "hItem", $hItem)
    DllStructSetData($tItem, "Children", $bFlag)
    Return __GUICtrlTreeView_SetItem($hWnd, $tItem)
EndFunc   ;==>_GUICtrlTreeView_SetChildren


Func _GUICtrlTreeView_SetChildren_NEW($hWnd, $hItem, $bFlag = True)
    Local $iCount = _GUICtrlTreeView_GetChildCount($hWnd, $hItem)
    If $iCount = -1 And $bFlag Then Return False
    If $iCount And Not $bFlag Then Return False

    If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)

    Local $tItem = $__g_tTVItemEx
    DllStructSetData($tItem, "Mask", BitOR($TVIF_HANDLE, $TVIF_CHILDREN))
    DllStructSetData($tItem, "hItem", $hItem)
    DllStructSetData($tItem, "Children", $bFlag)

    Return __GUICtrlTreeView_SetItem($hWnd, $tItem)
EndFunc   ;==>_GUICtrlTreeView_SetChildren

 

So of course its easy to just copy the old function into my code, but I would be interested if I did something wrong.

 

BR, Robert

Link to post
Share on other sites

It seems that the new version is checking if the item has actual children.  It returns false because in your case, it does not.  Not sure how it should be considered (feature, bug, unnecessary precaution).  I would like also that it should be removed.

Edited by Nine
Link to post
Share on other sites
48 minutes ago, Nine said:

It seems that the new version is checking if the item has actual children.  It returns false because in your case, it does not.  Not sure how it should be considered (feature, bug, unnecessary prevention).  I would like also that it should be removed.

Well, according to the documentation, the flag should set the indicator no matter wether there are children or not (I also think this is the idea behind this function :)) So I would say this is a bug :)

 

BR, Robert

Edited by Bubu
Link to post
Share on other sites
8 hours ago, jpm said:

Thanks,

I fix the pb

but I don't really understand how the setting of having no children can be handled

Cheers

I extended the sample from my first post to show how to handle an event.

 

#include <GUITreeView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $g_hTreeView1 = 0
Global $g_hTreeView2 = 0

Example()

Func Example()

    GUICreate("_GUICtrlTreeView_SetChildren", 350, 215)
    GUISetState(@SW_SHOW)

    Local Const $iTreeView1 = GUICtrlCreateTreeView(5, 5, 100, 100, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_INFOTIP, $TVS_LINESATROOT, $TVS_SHOWSELALWAYS), -1)
    $g_hTreeView1   = GUICtrlGetHandle($iTreeView1)

    Local $hItem = _GUICtrlTreeView_Add($g_hTreeView1, 0, "x")
    ; Works, plus is shown indicating the node has a child and one can react on the EXPAND-event
    _GUICtrlTreeView_SetChildren_OLD($g_hTreeView1, $hItem, True)

    Local Const $iTreeView2 = GUICtrlCreateTreeView(110, 5, 100, 100, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_INFOTIP, $TVS_LINESATROOT, $TVS_SHOWSELALWAYS), -1)
    $g_hTreeView2   = GUICtrlGetHandle($iTreeView2)

    $hItem = _GUICtrlTreeView_Add($g_hTreeView2, 0, "y")

    ; --->>> DOES NOT WORK !!! <<<---
    _GUICtrlTreeView_SetChildren_NEW($g_hTreeView2, $hItem, True)

    GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

EndFunc

Func _WM_NOTIFY(Const $hWnd, Const $iMsg, Const $wParam, Const $lParam)

    ; Contains information about a notification message
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom") ; Window handle to the control sending a message
    Local $iCode = DllStructGetData($tNMHDR, "Code")        ; Identifier of the control sending a message
    Local $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")    ; Notification code

    Local $hItem = 0
    Local $tNMTREEVIEW = 0

    Switch $hWndFrom
        Case $g_hTreeView1
            $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam)
            Switch $iCode
                Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
                    $hItem = DllStructGetData($tNMTREEVIEW, "NewhItem")
                    MsgBox(0, "TreeView 1 (" & $hWndFrom & ")", "Expanding " & _GUICtrlTreeView_GetText($hWndFrom , $hItem) & _
                        @CRLF & "Expanded: " & _GUICtrlTreeView_GetExpanded($hWndFrom , $hItem))
            EndSwitch
        Case $g_hTreeView2
            $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam)
            Switch $iCode
                Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
                    $hItem = DllStructGetData($tNMTREEVIEW, "NewhItem")
                    MsgBox(0, "TreeView 2 (" & $hWndFrom & ")", "Expanding " & _GUICtrlTreeView_GetText($hWndFrom , $hItem) & _
                        @CRLF & "Expanded: " & _GUICtrlTreeView_GetExpanded($hWndFrom , $hItem))

            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG

EndFunc

; ************************
; *** Autoit Functions ***
; ************************

Func _GUICtrlTreeView_SetChildren_OLD($hWnd, $hItem, $bFlag = True)
    If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    Local $tItem = DllStructCreate($tagTVITEMEX)
    DllStructSetData($tItem, "Mask", BitOR($TVIF_HANDLE, $TVIF_CHILDREN))
    DllStructSetData($tItem, "hItem", $hItem)
    DllStructSetData($tItem, "Children", $bFlag)
    Return __GUICtrlTreeView_SetItem($hWnd, $tItem)
EndFunc   ;==>_GUICtrlTreeView_SetChildren


Func _GUICtrlTreeView_SetChildren_NEW($hWnd, $hItem, $bFlag = True)
    Local $iCount = _GUICtrlTreeView_GetChildCount($hWnd, $hItem)
    If $iCount = -1 And $bFlag Then Return False
    If $iCount And Not $bFlag Then Return False

    If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)

    Local $tItem = $__g_tTVItemEx
    DllStructSetData($tItem, "Mask", BitOR($TVIF_HANDLE, $TVIF_CHILDREN))
    DllStructSetData($tItem, "hItem", $hItem)
    DllStructSetData($tItem, "Children", $bFlag)

    Return __GUICtrlTreeView_SetItem($hWnd, $tItem)
EndFunc   ;==>_GUICtrlTreeView_SetChildren

BR, Robert

Link to post
Share on other sites
On 11/3/2022 at 9:56 AM, jpm said:

I fix the pb but I don't really understand how the setting of having no children can be handled

Hi Jean-Paul :)
In the new version, it seems to me that you want to supervise the true/false setting, preventing it to be true ("Item children flag is set") when there are no children , and preventing it to be false ("Item children flag is cleared")  when children are present. But it wasn't like that in the precedent versions and no control was done, so why is this change needed ?

In the following script, when the user forces on purpose the flag to false,  then his TreeView will hide the eventual children, even if they exist, like "child b" in the script, who won't appear when you run the script "as is" (maybe he's an illegitimate child) :D

After changing this setting from "false" to "true" in the script, then "child b" will reappear.

Or maybe you wanted to change this behavior and have more control on it because the function _GUICtrlTreeView_SetChildren() "always" returns True in the old version ?

#include <MsgBoxConstants.au3>
#include <GUITreeView.au3>
#include <GUIConstantsEx.au3>

Example()

Func Example()

    GUICreate("_GUICtrlTreeView_SetChildren", 350, 215)
    GUISetState(@SW_SHOW)

    Local Const $iTreeView = GUICtrlCreateTreeView(5, 5, 100, 100, _
        BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_INFOTIP, $TVS_LINESATROOT, $TVS_SHOWSELALWAYS))
    Local Const $hTreeView = GUICtrlGetHandle($iTreeView)

    Local $hItem0 = _GUICtrlTreeView_Add($hTreeView, 0, "parent a")
    _GUICtrlTreeView_AddChild($hTreeView, $hItem0, "child a")
    _GUICtrlTreeView_SetChildren_NEW($hTreeView, $hItem0, True)

    Local $hItem1 = _GUICtrlTreeView_Add($hTreeView, 0, "parent b")
    _GUICtrlTreeView_AddChild($hTreeView, $hItem1, "child b")
    _GUICtrlTreeView_SetChildren_NEW($hTreeView, $hItem1, False) ; False on purpose

    MsgBox($MB_TOPMOST, "Information", "Parents got children ?" & @crlf & _
        "Parent a : " & _GUICtrlTreeView_GetChildren($hTreeView, $hItem0) & @crlf & _
        "Parent b : " & _GUICtrlTreeView_GetChildren($hTreeView, $hItem1))

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
EndFunc

;=================================================================
; just a reminder of the old original function in AutoIt 3.3.14.5
Func _GUICtrlTreeView_SetChildren_OLD($hWnd, $hItem, $bFlag = True)

    If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    Local $tItem = DllStructCreate($tagTVITEMEX)
    DllStructSetData($tItem, "Mask", BitOR($TVIF_HANDLE, $TVIF_CHILDREN))
    DllStructSetData($tItem, "hItem", $hItem)
    DllStructSetData($tItem, "Children", $bFlag)

    Return __GUICtrlTreeView_SetItem($hWnd, $tItem)
EndFunc   ;==>_GUICtrlTreeView_SetChildren_OLD

;=================================================================
Func _GUICtrlTreeView_SetChildren_NEW($hWnd, $hItem, $bFlag = True)

;~     Local $iCount = _GUICtrlTreeView_GetChildCount($hWnd, $hItem)
;~     If $iCount = -1 And $bFlag Then Return False
;~     If $iCount And Not $bFlag Then Return False

    If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)

    ; next line in code removed by jpm (after version 3.3.14.5) because code will be different
    ; in functions called, if handle OR control id (__GUICtrlTreeView_SetItem => __GUICtrl_SendMsg)
    ; If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    Local $tItem = $__g_tTVItemEx ; comes from Global $__g_tTVItemEx = DllStructCreate($tagTVITEMEX)
    DllStructSetData($tItem, "Mask", BitOR($TVIF_HANDLE, $TVIF_CHILDREN))
    DllStructSetData($tItem, "hItem", $hItem)
    DllStructSetData($tItem, "Children", $bFlag)

    Return __GUICtrlTreeView_SetItem($hWnd, $tItem)
EndFunc   ;==>_GUICtrlTreeView_SetChildren_NEW

 

Link to post
Share on other sites

@jpm I place this answer in a separate post as we'll discuss now about a possible solution to your concern.

imho, to stay compatible with older versions of AutoIt and avoid script breaking, then you can't modify the meaning of the Return value (True or False) of the function _GUICtrlTreeView_SetChildren()

This value (True or False) is returned by the called function __GUICtrlTreeView_SetItem() (both in 3.3.14.5 and 3.3.16.1) having in mind that in 3.3.16.1 __GUICtrlTreeView_SetItem() calls also a new big function __GUICtrl_SendMsg() found in the new file GuiCtrlInternals.au3

So this value never had something to do with the fact that there is a discrepancy between the 3rd param. of _GUICtrlTreeView_SetChildren() and the number of eventual children items.

What you could do is add an @error value (or an @extended value if you prefer) coupled with the return of the function, something like this :

Func _GUICtrlTreeView_SetChildren_NEW($hWnd, $hItem, $bFlag = True)

    Local $iCount = _GUICtrlTreeView_GetChildCount($hWnd, $hItem), $iKeep_error = 0
    If $iCount = -1 And $bFlag Then $iKeep_error = 1
    If $iCount And Not $bFlag Then $iKeep_error = 2

    If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)

    Local $tItem = $__g_tTVItemEx
    DllStructSetData($tItem, "Mask", BitOR($TVIF_HANDLE, $TVIF_CHILDREN))
    DllStructSetData($tItem, "hItem", $hItem)
    DllStructSetData($tItem, "Children", $bFlag)

    Return SetError($iKeep_error, 0, __GUICtrlTreeView_SetItem($hWnd, $tItem))
EndFunc   ;==>_GUICtrlTreeView_SetChildren_NEW

 

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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...