Jump to content

Weired behavior on _GUICtrlListView_AddItem


Recommended Posts

I have starange behavior with my script. Hope someone can help on this matter. I spent 5 days to figure out what's wrong...

I found were the problem exists but I do not know how to correct it.

The intended functionality of this script is:

1. Updating XML file when checking the ListView's check boxes

2. On changing the combobox's drop down list box, the ListView items should be updated with objects from the XML file but keeps the checked status of the items of the ListView control as was set previously in the xml file.

I observed that when changing the combobox dropdown listbox item, the XML file is updated with data (which this functionality is not expected to be).

The WM_COMMAND and the WM_NOTIFY functions are called on the code line:

"_GUICtrlListView_AddItem ($hListView, StringFormat($NodeRoot[$y], $y),-1)"

The $LVN_ITEMCHANGED and the $CBN_SELCHANGE are used on "_GUICtrlListView_AddItem , hence the problem.

Here is a steps to reproduce the problem:

You will need the include file "_XMLDomWrapper.au3" file.

1) Create xml file and name it AllTests.xml. (Add the xml code bellow to the AllTests.xml)

2) Create the au3 file with the code bellow.

3) Run the script.

4) Check all check boxes of the list box items.

5) Select from the combo box a different item (NOTE: There is only one item defined but it is enough to reproduce the problem)

6) Open the AllTests.xml file with text editor.

The Problem: The <Run>0</Run> node is updated with zero. although it was set to 1 on step number 4 above.

The AllTest.xml file:

<?xml version="1.0"?>
<Tests>
    <Header>
        <Run>0</Run>
        <Path>C:\AutoMDP\Suites\Default\cases\Header\Header_Auto.au3</Path>
    </Header>
    <A>
        <Run>0</Run>
        <Path>C:\AutoMDP\Suites\Default\cases\A\A_Auto.au3</Path>
    </A>
    <B>
        <Run>0</Run>
        <Path>C:\AutoMDP\Suites\Default\cases\B\B_Auto.au3</Path>
    </B>
    <C>
        <Run>0</Run>
        <Path>C:\AutoMDP\Suites\Default\cases\C\C_Auto.au3</Path>
    </C>
</Tests>

The code:

#include-once
#include <GUIConstants.au3>
#include <GuiListView.au3>
#include "_XMLDomWrapper.au3"
#Include <GuiComboBox.au3>
Global $sXMLFile = @ScriptDir & "\" & "AllTests.xml"
Global $XMLRoot="Tests"
Global $Suite = "AAA"
Dim $NodeRoot

$GUI = GUICreate("", 633, 447, 193, 115)
$hListView = _GUICtrlListView_Create ($GUI, "", 56, 144, 466, 246, -1, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
_GUICtrlListView_SetExtendedListViewStyle ($hListView, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES, $LVS_EX_REGIONAL, $LVS_EX_GRIDLINES, $LVS_EX_REGIONAL, $LVS_EX_DOUBLEBUFFER))
GUICtrlSetResizing(-1, $GUI_DOCKWIDTH)
$ComboSuiteName = GUICtrlCreateCombo($Suite, 80, 40, 145, 25)
GUISetState(@SW_SHOW)

_Tree()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _Tree()
    Local $IsRun
    $oXML = _XMLFileOpen ($sXMLFile)
    If $oXML = 0 Then
        MsgBox(0, "", "Error opening " & $sXMLFile)
        Exit
    EndIf
    $NodeRoot = _XMLGetChildNodes ($XMLRoot)
    _GUICtrlListView_BeginUpdate ($hListView)
    _GUICtrlListView_DeleteAllItems ($hListView)
    _GUICtrlListView_DeleteColumn ($hListView, 0)
    _GUICtrlListView_AddColumn ($hListView, "Suite Name: " & "Test Bugs", 170)
    For $y = 1 To UBound($NodeRoot) - 1
        
; Problem START here: The code line bellow update the xml file
        _GUICtrlListView_AddItem ($hListView, StringFormat($NodeRoot[$y], $y),-1)
; Problem END here:
        
        $IsRun =_XMLGetValue("//" & $XMLRoot & "/" & $NodeRoot[$y] & "/" & "Run")
        Select
            Case $IsRun[1] = 1
                _GUICtrlListView_SetItemChecked($hListView, $y -1, True)
            Case $IsRun[1] = 0
                _GUICtrlListView_SetItemChecked($hListView, $y -1, False)
            Case Else
        EndSelect
    Next
    _GUICtrlListView_EndUpdate ($hListView)
EndFunc

Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Local $tagNMHDR, $event
    $tagNMHDR = DllStructCreate("int;int;int;int;int;int;int;ptr;int;int;int;int;int;int;int;int;int;int;int", $lParam)
    If @error Then Return
    $hWndFrom = DllStructGetData($tagNMHDR, 1)
    $idFrom = DllStructGetData($tagNMHDR, 2)
    $event = DllStructGetData($tagNMHDR, 3)
    $position = DllStructGetData($tagNMHDR, 4)
    $ch = DllStructGetData($tagNMHDR, 5)
    $modifiers = DllStructGetData($tagNMHDR, 6)
    $modificationType = DllStructGetData($tagNMHDR, 7)
    $char = DllStructGetData($tagNMHDR, 8)
    $length = DllStructGetData($tagNMHDR, 9)
    $linesAdded = DllStructGetData($tagNMHDR, 10)
    $message = DllStructGetData($tagNMHDR, 11)
    $uptr_t = DllStructGetData($tagNMHDR, 12)
    $sptr_t = DllStructGetData($tagNMHDR, 13)
    $Line = DllStructGetData($tagNMHDR, 14)
    $foldLevelNow = DllStructGetData($tagNMHDR, 15)
    $foldLevelPrev = DllStructGetData($tagNMHDR, 16)
    $margin = DllStructGetData($tagNMHDR, 17)
    $listType = DllStructGetData($tagNMHDR, 18)
    $x = DllStructGetData($tagNMHDR, 19)
    $y = DllStructGetData($tagNMHDR, 20)
    
    Select
        Case $hWndFrom = $hWndListView
            Switch $iCode
                Case $LVN_ITEMCHANGED
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)
                    $oXML = _XMLFileOpen ($sXMLFile)
                    If $oXML = 0 Then
                        MsgBox(0, "", "Error opening " & $sXMLFile)
                        Exit
                    EndIf
            
                    Select
                        Case DllStructGetData($tInfo, "NewState") = "8192"
                            _XMLUpdateField($XMLRoot & "/" & _GUICtrlListView_GetItemText($hWndListView,DllStructGetData($tInfo, "Item")) & "/Run", 1)
                        Case DllStructGetData($tInfo, "NewState") = "4096"
                            _XMLUpdateField($XMLRoot & "/" & _GUICtrlListView_GetItemText($hWndListView,DllStructGetData($tInfo, "Item")) & "/Run", 0)
                    EndSelect
            EndSwitch
    EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
    Return $GUI_RUNDEFMSG
EndFunc

Func WM_COMMAND($hwnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo
    If Not IsHWnd($ComboSuiteName) Then $ComboSuiteName = GUICtrlGetHandle($ComboSuiteName)
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF)
    $iCode = BitShift($iwParam, 16)
    Switch $hWndFrom
        Case $ComboSuiteName, $hWndCombo
            Switch $iCode

                Case $CBN_SELCHANGE 
                    
                    _GUICtrlComboBox_GetLBText ($ComboSuiteName, _GUICtrlComboBox_GetCurSel ($Suite), $Suite)
                    _Tree()
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc
Edited by lsakizada

Be Green Now or Never (BGNN)!

Link to comment
Share on other sites

I don't understand what the StringFormat() is supposed to be doing for you. Are you expecting that to produce new values? Try it with this to see the values being used:

Func _Tree()
    Local $IsRun
    $oXML = _XMLFileOpen($sXMLFile)
    If $oXML = 0 Then
        MsgBox(0, "", "Error opening " & $sXMLFile)
        Exit
    EndIf
    $NodeRoot = _XMLGetChildNodes($XMLRoot)
    _GUICtrlListView_BeginUpdate($hListView)
    _GUICtrlListView_DeleteAllItems($hListView)
    _GUICtrlListView_DeleteColumn($hListView, 0)
    _GUICtrlListView_AddColumn($hListView, "Suite Name: " & "Test Bugs", 170)
    For $y = 1 To UBound($NodeRoot) - 1

        ; Problem START here: The code line bellow update the xml file
        ConsoleWrite("Debug: _Tree(), $NodeRoot[" & $y & "] = " & $NodeRoot[$y] & @LF)
        $sFormatted = StringFormat($NodeRoot[$y], $y)
        ConsoleWrite("Debug: _Tree(), $sFormatted = " & $sFormatted & @LF)
        $iNewIndex = _GUICtrlListView_AddItem($hListView, $sFormatted, -1)
        ConsoleWrite("Debug: _Tree(), $iNewIndex = " & $iNewIndex & @LF)
        ; Problem END here:

        $IsRun = _XMLGetValue("//" & $XMLRoot & "/" & $NodeRoot[$y] & "/" & "Run")
        Select
            Case $IsRun[1] = 1
                _GUICtrlListView_SetItemChecked($hListView, $y - 1, True)
            Case $IsRun[1] = 0
                _GUICtrlListView_SetItemChecked($hListView, $y - 1, False)
            Case Else
        EndSelect
    Next
    _GUICtrlListView_EndUpdate($hListView)
EndFunc   ;==>_Tree

Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Local $tagNMHDR, $event
    $tagNMHDR = DllStructCreate("int;int;int;int;int;int;int;ptr;int;int;int;int;int;int;int;int;int;int;int", $lParam)
    If @error Then Return
    $hWndFrom = DllStructGetData($tagNMHDR, 1)
    $idFrom = DllStructGetData($tagNMHDR, 2)
    $event = DllStructGetData($tagNMHDR, 3)
    $position = DllStructGetData($tagNMHDR, 4)
    $ch = DllStructGetData($tagNMHDR, 5)
    $modifiers = DllStructGetData($tagNMHDR, 6)
    $modificationType = DllStructGetData($tagNMHDR, 7)
    $char = DllStructGetData($tagNMHDR, 8)
    $length = DllStructGetData($tagNMHDR, 9)
    $linesAdded = DllStructGetData($tagNMHDR, 10)
    $message = DllStructGetData($tagNMHDR, 11)
    $uptr_t = DllStructGetData($tagNMHDR, 12)
    $sptr_t = DllStructGetData($tagNMHDR, 13)
    $Line = DllStructGetData($tagNMHDR, 14)
    $foldLevelNow = DllStructGetData($tagNMHDR, 15)
    $foldLevelPrev = DllStructGetData($tagNMHDR, 16)
    $margin = DllStructGetData($tagNMHDR, 17)
    $listType = DllStructGetData($tagNMHDR, 18)
    $x = DllStructGetData($tagNMHDR, 19)
    $y = DllStructGetData($tagNMHDR, 20)

    Select
        Case $hWndFrom = $hWndListView
            Switch $iCode
                Case $LVN_ITEMCHANGED
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)
                    $oXML = _XMLFileOpen($sXMLFile)
                    If $oXML = 0 Then
                        MsgBox(0, "", "Error opening " & $sXMLFile)
                        Exit
                    EndIf

                    Select
                        Case DllStructGetData($tInfo, "NewState") = "8192"
                            ConsoleWrite("Debug: WM_NOTIFY(), NewState = 8192, " & @LF)
                            _XMLUpdateField($XMLRoot & "/" & _GUICtrlListView_GetItemText($hWndListView, DllStructGetData($tInfo, "Item")) & "/Run", 1)
                        Case DllStructGetData($tInfo, "NewState") = "4096"
                            ConsoleWrite("Debug: WM_NOTIFY(), NewState = 4096" & @LF)
                            _XMLUpdateField($XMLRoot & "/" & _GUICtrlListView_GetItemText($hWndListView, DllStructGetData($tInfo, "Item")) & "/Run", 0)
                    EndSelect
            EndSwitch
    EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Please pay attentions to the cases in the WM_* functions that I mentioned (The WM_COMMAND and the WM_NOTIFY)

The $LVN_ITEMCHANGED and the $CBN_SELCHANGE. They are both used when the _GUICtrlListView_AddItem evaluated.

I think it is a bug but I can not nail it.

In order to see the problem you must run the script with the steps to reproduce that i wrote in my first post.

maybe Gary Frost should read this post? I do not know how to notify him about this issue. he might have interest to look at it.

My post is a snap of larger code but it reproduce the issue if running the steps.

Be Green Now or Never (BGNN)!

Link to comment
Share on other sites

Well, lets see....

You write checkbox states to XML flags during $LVN_ITEMCHANGED.

When you create a new item with _GUICtrlListView_AddItem in Tree() function, this triggers $LVN_ITEMCHANGED, and as at this point checkbox is cleared (as the reader from XML in Tree() hasn't yet been executed), it writes 0 to XML.

Then the reader from XML reads 0.

One way to solve it would be create a global flag and modify it in Tree() function - set it on/off at the start/end of creating item. Then depending on that flag skip XML writing in LVN_ITEMCHANGED.

"be smart, drink your wine"

Link to comment
Share on other sites

Well, lets see....

You write checkbox states to XML flags during $LVN_ITEMCHANGED.

When you create a new item with _GUICtrlListView_AddItem in Tree() function, this triggers $LVN_ITEMCHANGED, and as at this point checkbox is cleared (as the reader from XML in Tree() hasn't yet been executed), it writes 0 to XML.

Then the reader from XML reads 0.

One way to solve it would be create a global flag and modify it in Tree() function - set it on/off at the start/end of creating item. Then depending on that flag skip XML writing in LVN_ITEMCHANGED.

Didnt' even bother getting into it as far as Siao, once you have that much mixed into the heap of things that can go wrong it takes too long to sort it all out.

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Well, lets see....

You write checkbox states to XML flags during $LVN_ITEMCHANGED.

When you create a new item with _GUICtrlListView_AddItem in Tree() function, this triggers $LVN_ITEMCHANGED, and as at this point checkbox is cleared (as the reader from XML in Tree() hasn't yet been executed), it writes 0 to XML.

Then the reader from XML reads 0.

One way to solve it would be create a global flag and modify it in Tree() function - set it on/off at the start/end of creating item. Then depending on that flag skip XML writing in LVN_ITEMCHANGED.

Yep, you understood the problem clearly. Your solution is correct I guess and thanks for you as well.

I will make the script as small as I could for review by the masters if they will asked for.

Be Green Now or Never (BGNN)!

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...