benners Posted January 11, 2015 Posted January 11, 2015 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?. expandcollapse popup#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
Moderators Melba23 Posted January 12, 2015 Moderators Posted January 12, 2015 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 Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Â
Solution benners Posted January 12, 2015 Author Solution Posted January 12, 2015 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
Moderators Melba23 Posted January 12, 2015 Moderators Posted January 12, 2015 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 Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Â
kylomas Posted January 12, 2015 Posted January 12, 2015 (edited) benners, You may be over complicating this. Does this work for you? expandcollapse popup#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 January 12, 2015 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
benners Posted January 12, 2015 Author Posted January 12, 2015 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
kylomas Posted January 12, 2015 Posted January 12, 2015 (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... expandcollapse popup#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 January 12, 2015 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
benners Posted January 12, 2015 Author Posted January 12, 2015 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 expandcollapse popup#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
kylomas Posted January 13, 2015 Posted January 13, 2015 (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 January 13, 2015 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
benners Posted January 13, 2015 Author Posted January 13, 2015 (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 January 13, 2015 by benners
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now