Sign in to follow this  
Followers 0
benners

Issues with Listview and checkboxes

10 posts in this topic

I know this should be in the GUI section but this forum is a bit more active. After playing around with this code all day I am still unable to get it to function as I want.

The code is stripped from a bigger script but this is the section I am having issues with. The idea is to have a listview with items in. When items are checked, the delete button is enabled. When no items are checked the button is disabled.

The code works when normal selecting speed is applied, however, when you try to break it by using The Flash speed, the counter gets confused as to the amount of items selected and the button is enabled when it shouldn't be. I have tried enabling, disabling the GUI, begin and end update on the listview, adding sleeps, the one thing that has worked best was disabling the listview until the button enabling code has run, this however looks low rent and isn't aesthetically pleasing.

Is there a better was to do the above than the code below?.

#include <Array.au3>
#include <ButtonConstants.au3>
#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $g_id_MultipleSectionsGUI_lv, $g_id_MS_Delete_btn, $g_id_Dummy
Global $g_i_Checked = 0
Global $a_SectionNames[3] = [2, 'Section 1', 'Section 2']
Global Const $g_s_IniFile = ''

GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')

_ShowMultipleSections_GUI($a_SectionNames)

#Region #### Multiple INI Sections GUI ####
Func _ShowMultipleSections_GUI(ByRef $a_SectionNames)
    Local $h_MS_GUI = GUICreate("Multiple Sections", 430, 159, -1, -1)

    $g_id_MultipleSectionsGUI_lv = GUICtrlCreateListView("Choose a Section", 8, 8, 410, 113, BitOR($LVS_REPORT, _
            $LVS_SHOWSELALWAYS), BitOR($WS_EX_CLIENTEDGE, $LVS_EX_GRIDLINES, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT))
    GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 400)
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_LV_ALTERNATE) ; Set backcolour for Multi listview.
    _GUICtrlListView_JustifyColumn(-1, 0, 2) ; center the column text

    $g_id_MS_Delete_btn = GUICtrlCreateButton("Delete", 252, 128, 80, 25, $BS_NOTIFY)
    GUICtrlSetState(-1, $GUI_DISABLE)

    Local $id_MS_Cancel_btn = GUICtrlCreateButton("Cancel", 340, 128, 80, 25, $BS_NOTIFY)
    $g_id_Dummy = GUICtrlCreateDummy()

    _LoadListView($a_SectionNames, $g_id_MultipleSectionsGUI_lv)

    GUISetState(@SW_SHOW, $h_MS_GUI)

    Local $a_GUIMsg, $s_Return = ''

    While 1
        $a_GUIMsg = GUIGetMsg(1)

        Switch $a_GUIMsg[0]
            Case $g_id_MS_Delete_btn
                Local $i_ListView_Count = _GUICtrlListView_GetItemCount($g_id_MultipleSectionsGUI_lv)
                Local $s_SectionName = ''

                For $i = $i_ListView_Count - 1 To 0 Step -1
                    If _GUICtrlListView_GetItemChecked($g_id_MultipleSectionsGUI_lv, $i) Then
                        ; get the selected name
                        $s_SectionName = _GUICtrlListView_GetItemText($g_id_MultipleSectionsGUI_lv, $i)

                        ; remove it from the list view
                        _GUICtrlListView_DeleteItem($g_id_MultipleSectionsGUI_lv, $i)
                    EndIf
                Next

                ; disable the delete button
                GUICtrlSetState($g_id_MS_Delete_btn, $GUI_DISABLE)
            Case $id_MS_Cancel_btn
                ExitLoop
            Case $g_id_Dummy
                $s_Return = _MultipleSectionsLoadSelection($g_id_MultipleSectionsGUI_lv)
                ExitLoop
        EndSwitch

        Sleep(10)
    WEnd

    Return $s_Return
EndFunc   ;==>_ShowMultipleSections_GUI

Func _LoadListView(ByRef $a_ListView, $c_ListView)

    ; loop and load the listview
    For $i = 1 To $a_ListView[0]
        ; Add the current item to the listview.
        GUICtrlCreateListViewItem($a_ListView[$i], $c_ListView)
        ; Alternate the back colour
        GUICtrlSetBkColor(-1, 0xFCF6EA)
    Next
EndFunc   ;==>_LoadListView

Func _MultipleSectionsLoadSelection($c_ListView)
    ; Get the indexes of the selected items.
    Local $CurIndex = _GUICtrlListView_GetSelectedIndices($c_ListView, True)

    ; return the selected section name.
    Return _GUICtrlListView_GetItemText($c_ListView, $CurIndex[1])
EndFunc   ;==>_MultipleSectionsLoadSelection

Func _RunDummy()
    GUICtrlSendToDummy($g_id_Dummy)
EndFunc   ;==>_RunDummy

Func _GetItemChecked($i_State)
    ; get the number of items in the list
    Local $i_Count = _GUICtrlListView_GetItemCount($g_id_MultipleSectionsGUI_lv)

    ; set initial as all unchecked as listview just created
    Local $g_i_Checked = 0

    ; loop through the listview counting checked items, this is for 2nd loop onwards
    For $i = 0 To $i_Count - 1
        If _GUICtrlListView_GetItemChecked($g_id_MultipleSectionsGUI_lv, $i) Then $g_i_Checked += 1
    Next

    ConsoleWrite('after first loop $g_i_Checked =' & $g_i_Checked & @CRLF)

    If $i_State = True Then ; Item is checked
        $g_i_Checked += 1 ; Increase the selected count.
    Else ; Item unchecked.
        If $g_i_Checked > 0 Then $g_i_Checked -= 1 ; Decrease the selected count.
    EndIf

    ConsoleWrite('after check state $g_i_Checked = ' & $g_i_Checked & @CRLF)

;~  Local $i_Recheck = 0

;~  For $i = 0 To $i_Count - 1
;~      If _GUICtrlListView_GetItemChecked($g_id_MultipleSectionsGUI_lv, $i) Then $i_Recheck += 1
;~  Next

;~  If $i_Recheck <> $g_i_Checked Then
;~      ConsoleWrite('$g_i_Checked: ' & $g_i_Checked & ' <> $i_Recheck: ' & $i_Recheck & ' Resetting $g_i_Checked = ' & $i_Recheck & @CRLF)
;~      $g_i_Checked = $i_Recheck
;~  EndIf

;~  ConsoleWrite('After Recheck. $i_Recheck = ' & $i_Recheck & @CRLF)

    If Not $g_i_Checked Then
        GUICtrlSetState($g_id_MS_Delete_btn, $GUI_DISABLE)
    Else
        GUICtrlSetState($g_id_MS_Delete_btn, $GUI_ENABLE)
    EndIf

    ConsoleWrite('Returning. Checked Items = ' & $g_i_Checked & @CRLF)
EndFunc   ;==>_GetItemChecked
#EndRegion #### Multiple INI Sections GUI ####

Func WM_NOTIFY($h_Wnd, $s_Msg, $w_Param, $i_Param)
    Local $t_NMHDR = 0, $id_From = 0, $i_Code = 0

    $t_NMHDR = DllStructCreate($tagNMHDR, $i_Param)
    $id_From = DllStructGetData($t_NMHDR, "IdFrom")
    $i_Code = DllStructGetData($t_NMHDR, "Code")

    Switch $id_From
        ; Multiple section listview.
        Case $g_id_MultipleSectionsGUI_lv

            Switch $i_Code
                Case $NM_CLICK
                    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $i_Param)
                    Local $_iIndex = DllStructGetData($tInfo, "Index")

                    If $_iIndex <> -1 Then
                        Local $i_X = DllStructGetData($tInfo, "X")
                        Local $a_Rect = _GUICtrlListView_GetItemRect($g_id_MultipleSectionsGUI_lv, $_iIndex, 2)
                        If ($i_X < ($a_Rect[0] - 3)) And ($i_X >= 5) Then _GetItemChecked(_GUICtrlListView_GetItemChecked($g_id_MultipleSectionsGUI_lv, $_iIndex) = 0)
                        ConsoleWrite('returned from _GetItemChecked' & @CRLF)
                    EndIf
                Case $NM_DBLCLK ; If double clicked.
                    If _GUICtrlListView_GetSelectedCount($g_id_MultipleSectionsGUI_lv) > 0 Then _RunDummy() ; Load the settings from the selected Office application.
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Share this post


Link to post
Share on other sites



benners,

I have always found that carrying out operations inside the WM_NOTIFY handler can cause the sort of problems you are describing when the handler is fired several times very quickly - the system does not have time to realise the new ListView state before being asked to react to it. I suggest using the handler to set a flag (or fire a dummy control) so that the "check counting" takes place in the idle loop - keeping the code inside the handler to minimum is always a good idea. ;)

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

Thanks Melba

I did as you suggested but was still getting incorrect counters. I manged to fix the problem by altering the switch statement in the WM_Notify.

Switch $i_Code
                Case $NM_CLICK, $NM_DBLCLK
                    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $i_Param)
                    Local $iIndex = DllStructGetData($tInfo, "Index")

                    If $iIndex <> -1 Then
                        Local $iX = DllStructGetData($tInfo, "X")
                        Local $aRect = _GUICtrlListView_GetItemRect($g_id_MultipleSectionsGUI_lv, $iIndex, 2)

                        If ($iX < $aRect[0] - 3) And ($iX >= 5) Then
                            _GetItemChecked(_GUICtrlListView_GetItemChecked($g_id_MultipleSectionsGUI_lv, $iIndex) = 0)
                        ElseIf $i_Code = $NM_DBLCLK Then
                            If _GUICtrlListView_GetSelectedCount($g_id_MultipleSectionsGUI_lv) > 0 Then _RunDummy() ; Load the settings from the selected Office application.
                        EndIf
                    EndIf
            EndSwitch

Share this post


Link to post
Share on other sites

benners,

Glad you got it working. :)

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

#5 ·  Posted (edited)

benners,

You may be over complicating this.  Does this work for you?

#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <array.au3>

#AutoIt3Wrapper_Add_Constants=n

local $gui010 = guicreate('ListView Example',400,400)
local $lv0010 = guictrlcreatelistview('Choose a Section',20,20,360,300, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS))
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_LV_ALTERNATE)
guictrlsetbkcolor(-1,0xBBF6EA)

; recommended way to set extended LV styles to prevent collision with other style values
_GUICtrlListView_SetExtendedListViewStyle ($lv0010,  BitOR($WS_EX_CLIENTEDGE, $LVS_EX_GRIDLINES, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT))

_GUICtrlListView_SetColumnWidth ($lv0010,0,360)

local $btnDEL = guictrlcreatebutton('Delete',20,360,50,20)
guictrlsetstate($btnDEL,$GUI_DISABLE)
local $btnCAN = guictrlcreatebutton('Cancel',100,360,50,20)
local $lv_dummy = guictrlcreatedummy()

_populate_lv()

guisetstate()

GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')

while 1
    switch guigetmsg()
        case $gui_event_close, $btnCAN
            Exit
        case $btnDEL
            guisetstate(@SW_LOCK, $gui010)
            for $1 = _GUICtrlListView_GetItemCount($lv0010) to 0 step -1
                if _GUICtrlListView_GetItemChecked ($lv0010, $1) = true then _GUICtrlListView_DeleteItem($lv0010,$1)
            Next
            guisetstate(@SW_UNLOCK,$gui010)
            guictrlsetstate($btnDEL,$GUI_DISABLE)
        case $lv_dummy
            for $1 = 0 to _GUICtrlListView_GetItemCount($lv0010)
                if _GUICtrlListView_GetItemChecked ($lv0010, $1) = true then
                    guictrlsetstate($btnDEL,$GUI_ENABLE)
                    ExitLoop
                EndIf
            next
    EndSwitch
WEnd

Func WM_NOTIFY($h_Wnd, $s_Msg, $w_Param, $i_Param)

    $t_NMHDR = DllStructCreate($tagNMHDR, $i_Param)

    Switch $t_NMHDR.IdFrom
        Case $lv0010
            Switch $t_NMHDR.Code
                Case $NM_CLICK, $NM_DBLCLK
                    GUICtrlSendToDummy($lv_dummy)
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

func _populate_lv()

    for $1 = 0 to 1000
        GUICtrlCreateListViewItem('Item ' & $1, $lv0010)
        GUICtrlSetBkColor(-1, 0xFCF6EA)
    Next

endfunc

kylomas

edit: comment

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

Thanks Kylomas

I tried the code and pinched a few bits that made my code smaller, mostly the $t_NMHDR parts, saved a few DllStructGetData calls, didn't know you could do that.

The code works fine but I need single and double click detections and functions, single click for listview items selection, (this does nothing), single click to detect checkbox selections (selects item for deletion), and double click (selects the item and runs code after). I Initially had multi select for the list view, then deleted the selectedindices but like boxes better.

The main reason for counting how many boxes are checked is to disable the delete button if none are checked. I could leave the button enabled and show a msgbox to ask for a selection but I think it looks better if it's disabled.

Thanks

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

benners,

Yes, I did nothing for Clicks besides enable/disable the del button.  Was having trouble wading through your code.  One last thing, if you want to detect a checked item without looping through the entire list or maintaining a counter it can be done like this...

#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <array.au3>

#AutoIt3Wrapper_Add_Constants=n

local $gui010 = guicreate('ListView Example',400,400)
local $lv0010 = guictrlcreatelistview('Choose a Section',20,20,360,300, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS))
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_LV_ALTERNATE)
guictrlsetbkcolor(-1,0xBBF6EA)

; recommended way to set extended LV styles to prevent collision with other style values
_GUICtrlListView_SetExtendedListViewStyle ($lv0010,  BitOR($WS_EX_CLIENTEDGE, $LVS_EX_GRIDLINES, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT))

_GUICtrlListView_SetColumnWidth ($lv0010,0,360)

local $btnDEL = guictrlcreatebutton('Delete',20,360,50,20)
guictrlsetstate($btnDEL,$GUI_DISABLE)
local $btnCAN = guictrlcreatebutton('Cancel',100,360,50,20)
local $lv_dummy = guictrlcreatedummy()

_populate_lv()

guisetstate()

GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')

while 1
    switch guigetmsg()
        case $gui_event_close, $btnCAN
            Exit
        case $btnDEL
            guisetstate(@SW_LOCK, $gui010)
            for $1 = _GUICtrlListView_GetItemCount($lv0010) to 0 step -1
                if _GUICtrlListView_GetItemChecked ($lv0010, $1) = true then _GUICtrlListView_DeleteItem($lv0010,$1)
            Next
            guisetstate(@SW_UNLOCK,$gui010)
            guictrlsetstate($btnDEL,$GUI_DISABLE)
        case $lv_dummy
            guictrlsetstate($btnDEL,$GUI_ENABLE)
    EndSwitch
WEnd

Func WM_NOTIFY($h_Wnd, $s_Msg, $w_Param, $i_Param)

    $t_NMHDR = DllStructCreate($tagNMHDR, $i_Param)
    $t_NMLISTVIEW = DllStructCreate($tagNMLISTVIEW, $i_Param)

    Switch $t_NMHDR.IdFrom
        Case $lv0010
            Switch $t_NMHDR.Code
                Case $LVN_ITEMCHANGED
                    if _GUICtrlListView_GetItemChecked ($lv0010, $t_NMLISTVIEW.Item) = true then GUICtrlSendToDummy($lv_dummy)
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

func _populate_lv()

    for $1 = 0 to 1000
        GUICtrlCreateListViewItem('Item ' & $1, $lv0010)
        GUICtrlSetBkColor(-1, 0xFCF6EA)
    Next

endfunc

edit: Extended LV styles should be set using the function due to collision of style value.  Also, activity inside of the notification function should be minimized.  The GUI may become unresponsive and some actions may cause calls to the function to cascade.

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

Kylomas,

I have updated the code with the new tweaks and added more comments detailing what I want to do. I still need the total count of checked items to set the sate of the delete button.

The $LVN_ITEMCHANGED event occurs to often to maintain a reliable counter, I was trying to knock something together maybe using $t_NMLISTVIEW.ActionX to get the X co-ord of the event but kept getting 0, which is my understanding of DllStructCreate calls and returns :

There would still need to be checks for double clicks to fire the associated action. I have #### some of the comments, these are some suggestions that maybe better, some have been tested to work but may not be best practice, I have read Ternary operation has negative views.

Thanks

#include <ButtonConstants.au3>
#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $g_id_MultipleSectionsGUI_lv, $g_id_MS_Delete_btn, $g_id_Dummy
Global $g_i_Checked = 0
Global $a_SectionNames[3] = [2, 'Section 1', 'Section 2']

GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')

; added to check returned string
Local $s_Return = _ShowMultipleSections_GUI($a_SectionNames)
If $s_Return Then MsgBox(64, 'Section', $s_Return)

#Region #### Multiple INI Sections GUI ####
Func _ShowMultipleSections_GUI(ByRef $a_SectionNames)
    Local $h_MS_GUI = GUICreate("Multiple Sections", 430, 159, -1, -1)

    $g_id_MultipleSectionsGUI_lv = GUICtrlCreateListView("Choose a Section", 8, 8, 410, 113, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS))
    _GUICtrlListView_SetExtendedListViewStyle($g_id_MultipleSectionsGUI_lv, BitOR($WS_EX_CLIENTEDGE, $LVS_EX_GRIDLINES, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT))
    GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 400)

    ; Set backcolour for Multi listview.
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_LV_ALTERNATE)

    ; center the column text
    _GUICtrlListView_JustifyColumn(-1, 0, 2)

    $g_id_MS_Delete_btn = GUICtrlCreateButton("Delete", 252, 128, 80, 25, $BS_NOTIFY)
    GUICtrlSetState(-1, $GUI_DISABLE)

    Local $id_MS_Cancel_btn = GUICtrlCreateButton("Cancel", 340, 128, 80, 25, $BS_NOTIFY)
    $g_id_Dummy = GUICtrlCreateDummy()

    ; load the section names into the listview
    _LoadListView($a_SectionNames, $g_id_MultipleSectionsGUI_lv)

    GUISetState(@SW_SHOW, $h_MS_GUI)

    Local $a_GUIMsg, $s_Return = ''

    While 1
        $a_GUIMsg = GUIGetMsg(1)

        Switch $a_GUIMsg[0]
            Case $g_id_MS_Delete_btn
                ; get the number of items in the listview
                Local $i_ListView_Count = _GUICtrlListView_GetItemCount($g_id_MultipleSectionsGUI_lv)
                Local $s_SectionName = ''

                ; loop backwards through the list view
                For $i = $i_ListView_Count - 1 To 0 Step -1
                    If _GUICtrlListView_GetItemChecked($g_id_MultipleSectionsGUI_lv, $i) Then
                        ; get the selected name
                        $s_SectionName = _GUICtrlListView_GetItemText($g_id_MultipleSectionsGUI_lv, $i)

                        ; remove it from the list view
                        _GUICtrlListView_DeleteItem($g_id_MultipleSectionsGUI_lv, $i)
                    EndIf
                Next

                ; disable the delete button
                GUICtrlSetState($g_id_MS_Delete_btn, $GUI_DISABLE)
            Case $id_MS_Cancel_btn
                ExitLoop
            Case $g_id_Dummy
                ; Get the indexes of the selected items.
                Local $a_CurIndex = _GUICtrlListView_GetSelectedIndices($g_id_MultipleSectionsGUI_lv, True)

                ; return the selected section name.
                Return _GUICtrlListView_GetItemText($g_id_MultipleSectionsGUI_lv, $a_CurIndex[1])
        EndSwitch

        Sleep(10)
    WEnd
EndFunc   ;==>_ShowMultipleSections_GUI

Func _LoadListView(ByRef $a_ListView, $c_ListView)
    ; loop and load the listview
    For $i = 1 To $a_ListView[0]
        ; Add the current item to the listview.
        GUICtrlCreateListViewItem($a_ListView[$i], $c_ListView)

        ; Alternate the back colour
        GUICtrlSetBkColor(-1, 0xFCF6EA)
    Next
EndFunc   ;==>_LoadListView

Func _RunDummy()
    GUICtrlSendToDummy($g_id_Dummy)
EndFunc   ;==>_RunDummy

Func _GetItemChecked($i_State)
    ; just for debug notification when running event
    ConsoleWrite('state: ' & $i_State & @CRLF)

    If $i_State Then ; Item is checked
        $g_i_Checked += 1 ; Increase the selected count.
    Else ; Item unchecked.
        $g_i_Checked -= 1 ; Decrease the selected count.
    EndIf

    ; if no items are checked then disable the delete button
    If Not $g_i_Checked Then
        GUICtrlSetState($g_id_MS_Delete_btn, $GUI_DISABLE)
    Else
        GUICtrlSetState($g_id_MS_Delete_btn, $GUI_ENABLE)
    EndIf
EndFunc   ;==>_GetItemChecked
#EndRegion #### Multiple INI Sections GUI ####

Func WM_NOTIFY($h_Wnd, $s_Msg, $w_Param, $i_Param)
    Local $t_NMHDR = DllStructCreate($tagNMHDR, $i_Param)
    Local $t_NMLISTVIEW = DllStructCreate($tagNMLISTVIEW, $i_Param)

;~  Switch $t_NMHDR.IdFrom
;~      Case $g_id_MultipleSectionsGUI_lv
;~          Switch $t_NMHDR.Code
;~              Case $LVN_ITEMCHANGED ; event runs when creating listview, selecting items for counter will be incorrect
;~                  ; #### needs code to find if checkbox actioned, maybe using ActionX ? ####

;~                  ; #### maybe replace if\then with Ternary ####
;~                  _GetItemChecked((_GUICtrlListView_GetItemChecked($g_id_MultipleSectionsGUI_lv, $t_NMLISTVIEW.Item) = True) ? (True) : (False))

;~                  If _GUICtrlListView_GetItemChecked($g_id_MultipleSectionsGUI_lv, $t_NMLISTVIEW.Item) = True Then
;~                      _GetItemChecked(True)
;~                  Else
;~                      _GetItemChecked(False)
;~                  EndIf
;~          EndSwitch
;~  EndSwitch
;~  Local $t_NMHDR = DllStructCreate($tagNMHDR, $i_Param)

    Switch $t_NMHDR.IdFrom
        ; Multiple section listview.
        Case $g_id_MultipleSectionsGUI_lv

            Switch $t_NMHDR.Code
                Case $NM_CLICK, $NM_DBLCLK
                    Local $t_Info = DllStructCreate($tagNMITEMACTIVATE, $i_Param)
                    ; get the index of the listview item that was clicked
                    Local $i_Index = DllStructGetData($t_Info, "Index")

                    ; if it's a viable index
                    If not @error Then
                        Local $iX = DllStructGetData($t_Info, "X")

                        ; get the bounding rectangle for the listview item text (Returns an array)
                        Local $a_Rect = _GUICtrlListView_GetItemRect($g_id_MultipleSectionsGUI_lv, $i_Index, 2)

                        ; just use the top left corner of the rectangle ($a_Rect[0], returns 20)
                        ; check if the clicked area was less than 17 (checkbox width) and more the 5 (random X co-ord)
                        If ($iX < $a_Rect[0] - 3) And ($iX >= 5) Then ; #### could just scrap _GUICtrlListView_GetItemRect and use 17 for ($iX < $a_Rect[0] - 3) part acounting for DPI? ####
                            ; increase check count and determine button state
                            _GetItemChecked(_GUICtrlListView_GetItemChecked($g_id_MultipleSectionsGUI_lv, $i_Index) = 0)
                        ElseIf $t_NMHDR.Code = $NM_DBLCLK Then
                            ; Load the settings from the ini section selected
                            If _GUICtrlListView_GetSelectedCount($g_id_MultipleSectionsGUI_lv) > 0 Then _RunDummy()
                        EndIf
                    EndIf
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

benners,

Yes, apologies for the $LVN_ITEMCHANGED code.  Realized last night that I was going down the wrong path but could'nt get to a PC....

edit:  Looks like the DEL btn portion is working.  When I DBL click I get a msg box and the script ends.  Still in developement?  Also, why do you prefer maintaining a counter of checked items as opposed to spinning throught the items?  I tested with 1000 items and could not detect a slowdown using the spinning method.

kylomas

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

The code is unfinished, It's a re write of an old program I made a while ago called Office Integrator. I like to break things down into small functions so I do smaller test scripts then when the code is working change it into a function.

When the dbl click happens the next part will load values from an INI with the section header that is selected. and actions will be performed on the selected files.

I don't need to keep a count of the # of checked boxes, all I really need is code to check if any are unchecked then I can disable the Delete button, if not, it's enabled. The problem is when the _GetItemChecked is fired and run the checkbox isn't selected, I tried running a loop inside the function but it always returned wrong results. I could get rid of another Global var if I didn't need the $g_i_Checked.

The old function code is below, the counter method always seemed bulletproof.

Func _GetItemChecked($i_State)
    Local $i_ListView_Count = _GUICtrlListView_GetItemCount($g_id_MultipleSectionsGUI_lv)
    Local $i_ListView_Checked = 0

    MsgBox(0,'Before loop','check listview')

    For $i = 0 to $i_ListView_Count - 1
        if _GUICtrlListView_GetItemChecked($g_id_MultipleSectionsGUI_lv, $i) then $i_ListView_Checked +=1
    Next

    MsgBox(0,'After loop','check listview')

;~  If $i_State Then ; Item is checked
;~      $g_i_Checked += 1 ; Increase the selected count.
;~  Else ; Item unchecked.
;~      $g_i_Checked -= 1 ; Decrease the selected count.
;~  EndIf

;~ if not $g_i_Checked then
;~  GUICtrlSetState($id_MS_Delete_btn, $GUI_DISABLE)
;~ Else
;~  GUICtrlSetState($id_MS_Delete_btn, $GUI_ENABLE)
;~ EndIf

EndFunc   ;==>_GetItemChecked
Edited by benners

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