Kira16651 Posted May 29, 2015 Posted May 29, 2015 Hello,I'm wanted to click on a List Item and get its Index (Row). In the example for _GuiCtrlListView_Create this works beautifully.When I do the same thing in my code I always get an Index of -1. I found out in the documentation of $tagNMITEMACTIVATE that this is the case if the index is not used for the notification.I have no idea what that means. Any idea how I could search for that or how I can set it to be used for notifications?I put only the relevant parts of my code here:expandcollapse popup#Region ### START Koda GUI section ### Form=q:\programme\autoit\gui_main.kxf $hGuiWindow = GUICreate("Aktuelle Projekte", 616, 408, 592, 469) $hGuiListview = _GUICtrlListView_Create($hGuiWindow, "Projektnummer|Kunde|Maschinentyp|Kommentar|Gewichtung|everything", 8, 40, 601, 357) $hGuiInput = GUICtrlCreateEdit("", 8, 8, 601, 21) GUISetState(@SW_SHOW) _WinAPI_SetFocus(ControlGetHandle($hGuiWindow, "", $hGuiInput)) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch $sGuiInput = GUICtrlRead($hGuiInput) ; read what the search string is If StringRight($sGuiInput, 2) = @CRLF Then ; if return has been pressed in the search field ... GUIDelete($hGuiWindow) Send($sProjectNumber) Exit ElseIf $sGuiInput <> $sGuiInputPrev Then ; if the input in the search field has changed ... _GUICtrlListView_DeleteAllItems($hGuiListview) ; ... delete everything that was in the list box Local $aGuiInput = StringSplit($sGuiInput, " ", 2) ; split the search string into multiple at the space Local $aResults = _LiveSearchResults2D($aProjects, _ArrayToString($aGuiInput, " "), 5, 4) ; put the words into a string and search and add weight $sProjectNumber = $aResults[0][0] ; put the top most article number into the global variable ; $aResults = _2DArray_To_1D_Array_With_Strings($aResults, "|") ; todo: completely remove this _DisplayResultsAdvanced($hGuiListview, $aResults) _GUICtrlListView_SetColumnWidth($hGuiListview, 0, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($hGuiListview, 1, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($hGuiListview, 2, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($hGuiListview, 3, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($hGuiListview, 4, $LVSCW_AUTOSIZE) EndIf $sGuiInputPrev = $sGuiInput ; set the variable for the previous input for the next cycle Sleep(10) ; sleep a bit so that the proccess is not consuming 100% of the cpu WEnd Func _DisplayResultsAdvanced($hListView, $aArray, $sString = "test") ; displays the array in the list view For $Row = 0 To UBound($aArray) - 1 ; creates the list view items _GUICtrlListView_AddItem($hListView, $aArray[$Row][0], $Row) For $Col = 1 To UBound($aArray, 2) - 1 ; only first four columns are important here _GUICtrlListView_AddSubItem($hListView, $Row, $aArray[$Row][$Col], $Col) Next Next EndFunc ;==>_DisplayResultsAdvanced Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo ; Local $tBuffer $hWndListView = $hGuiListview If Not IsHWnd($hGuiListview) Then $hWndListView = GUICtrlGetHandle($hGuiListview) $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndListView Switch $iCode Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam) Local $iIndex = DllStructGetData($tInfo, "Index") ConsoleWrite($iIndex & @CRLF) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY
Moderators Melba23 Posted May 29, 2015 Moderators Posted May 29, 2015 Kira16651,It really helps if you post runnable code - the _LiveSearchResults2D function is missing.Substituting a dummy array shows that you do get the correct answer if you click on the first item of each line, but not if you click on the subitems. If you set the whole line to be selected using: _GUICtrlListView_SetExtendedListViewStyle($hGuiListview, $LVS_EX_FULLROWSELECT) then you also get the correct answer even when clicking the subitems.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
Kira16651 Posted May 29, 2015 Author Posted May 29, 2015 (edited) Thanks! That is exactly what I was looking for.Sorry about the code, thought it would be too much of a mess if I posted everything.For completeness sake here the complete code and an example csv file which is also used.Keep in mind I just got this working for the first time so it's probably still buggy. It's still a work in progress.expandcollapse popup; ------- Version History ---------------------------- ; Author | Date | Version | New features in this Version ; Tobias Beitz | 2015-05-29 | 0.01 | Created the file. ; ; ------- Script Description ------------------------- ; ; opens a window where the user can type things in a search bar and search for projects ; the results are weighted with the best result at the top ; pressing return will insert the project number ; pressing esc will close the window ; users can also just click the project to insert the project number ; ; ---------------------------------------------------- ;######## todo ####### ; - display all the projects even if nothing was typed yet ; - if nothing is in the input, display all the projects again unsorted ; - if you press tab you switch to all projects ever instead of just current projects ;##### stuff we need for this script #include <File.au3> #include <Array.au3> #include <MsgBoxConstants.au3> #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <Misc.au3> ;##### stuff needed for the gui #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIListBox.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <GuiImageList.au3> #Region ### START Koda GUI section ### Form=q:\programme\autoit\gui_main.kxf $hGuiWindow = GUICreate("Aktuelle Projekte", 700, 500) $hGuiInput = GUICtrlCreateEdit("", 8, 8, 700 - 16 - 150, 21, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_WANTRETURN)) $hGuiListview = _GUICtrlListView_Create($hGuiWindow, "Projektnummer|Kunde|Maschinentyp|Maschinennummer|Kommentar|Gewichtung|everything", 8, 37, 700 - 16, 500 - 45) _GUICtrlListView_SetExtendedListViewStyle($hGuiListview, $LVS_EX_FULLROWSELECT) $hGuiButtonSwitchMode = GUICtrlCreateButton("zeig alle Projekte", 700 - 8 - 150, 8, 150, 21) GUISetState(@SW_SHOW) _WinAPI_SetFocus(ControlGetHandle($hGuiWindow, "", $hGuiInput)) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") #EndRegion ### END Koda GUI section ### ;####### global variables Global $aProjects _ReadFileToArray("./aktuelle_projekte_liste.csv") Global $sGuiInput = "" ; read input Global $sGuiInputPrev = "" ; save previous input Global $sProjectNumber = "" ; the project number we want to know/insert Global $sMachineNumber = "" ; the machine number we want to know/insert Global $sMode = "current" ; the mode we are in. "current" = only show current projects. "all" = show all projects Global $iClickedIndex = -1 ; if -1 then nothing happens, if >= 0 then insert project number from the indexed row Global $aResults ; results array of the live search _FilterAndDisplayArrayInListView($hGuiListview, "", $aProjects) ; show an initial unfiltered and unsorted list While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $hGuiButtonSwitchMode If $sMode = "current" Then $sMode = "all" GUICtrlSetData($hGuiButtonSwitchMode, "zeig aktuelle Projekte") WinSetTitle($hGuiWindow, "", "Alle Projekte") _ReadFileToArray("./alle_projekte_liste.csv") ElseIf $sMode = "all" Then $sMode = "current" GUICtrlSetData($hGuiButtonSwitchMode, "zeig alle Projekte") WinSetTitle($hGuiWindow, "", "Aktuelle Projekte") _ReadFileToArray("./aktuelle_projekte_liste.csv") EndIf ; repopulate the list view and filter it and sort it and stuff Local $aGuiInput = StringSplit($sGuiInput, " ", 2) ; split the search string into multiple at the space _FilterAndDisplayArrayInListView($hGuiListview, $aGuiInput, $aProjects) EndSwitch $sGuiInput = GUICtrlRead($hGuiInput) ; read what the search string is if $iClickedIndex >= 0 Then ; if we clicked on a list item $sProjectNumber = $aResults[$iClickedIndex][0] ; put the top most project number into the global variable $sMachineNumber = $aResults[$iClickedIndex][3] ; put the top most machine number into the global variable EndIf If StringRight($sGuiInput, 2) = @CRLF or $iClickedIndex >= 0 Then ; if return has been pressed in the search field or we clicked a list item ... If _IsPressed(10) Then ; if shift is pressed ... GUIDelete($hGuiWindow) Send($sMachineNumber) ; ... send machine number ... Exit Else GUIDelete($hGuiWindow) Send($sProjectNumber) ; ... otherwise send project number Exit EndIf ElseIf $sGuiInput <> $sGuiInputPrev Then ; if the input in the search field has changed ... Local $aGuiInput = StringSplit($sGuiInput, " ", 2) ; split the search string into multiple at the space _FilterAndDisplayArrayInListView($hGuiListview, $aGuiInput, $aProjects) EndIf $sGuiInputPrev = $sGuiInput ; set the variable for the previous input for the next cycle Sleep(10) ; sleep a bit so that the proccess is not consuming 100% of the cpu WEnd ;######### functions Func _ReadFileToArray($sFilePath) Global $aProjects = _CSV_2_2DArray($sFilePath) ; Inhalt der csv datei einlesen und im array speichern ReDim $aProjects[UBound($aProjects)][7] For $Row = 0 To UBound($aProjects) - 1 ; for each row ... Local $sEverything = "" ; todo: add comments For $Col = 0 To 5 $sEverything = $sEverything & " " & $aProjects[$Row][$Col] Next $aProjects[$Row][6] = $sEverything Next EndFunc Func _FilterAndDisplayArrayInListView($hGuiListview, $aGuiInput, $aArray) _GUICtrlListView_DeleteAllItems($hGuiListview) ; ... delete everything that was in the list box $aResults = _LiveSearchResults2D($aArray, _ArrayToString($aGuiInput, " "), 6, 5) ; put the words into a string and search and add weight $sProjectNumber = $aResults[0][0] ; put the top most project number into the global variable $sMachineNumber = $aResults[0][3] ; put the top most machine number into the global variable _DisplayResultsAdvanced($hGuiListview, $aResults) _GUICtrlListView_SetColumnWidth($hGuiListview, 0, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($hGuiListview, 1, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($hGuiListview, 2, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($hGuiListview, 3, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($hGuiListview, 4, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($hGuiListview, 5, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($hGuiListview, 6, $LVSCW_AUTOSIZE) EndFunc ;==>_FilterAndDisplayArrayInListView Func _2DArray_To_1D_Array_With_Strings($aArray, $sDelimiter) ; takes 2d $aArray and converts each element into a string with the given $sDelimiter Local $sSubString ; each row will be seperately saved in this string Local $aReturnArray[UBound($aArray)] ; the array that will be returned Local $Rows = UBound($aArray) - 1 Local $Columns = UBound($aArray, 2) - 1 If $Rows < 2 Then Return "ERROR in 2d array to 1d array ... function" EndIf For $Row = 0 To $Rows $sSubString = $aArray[$Row][0] ; put first element in substring For $Col = 1 To $Columns $sSubString = $sSubString & $sDelimiter & $aArray[$Row][$Col] ; add the next thing to the substring Next $aReturnArray[$Row] = $sSubString ; put the substring into the row Next Return $aReturnArray EndFunc ;==>_2DArray_To_1D_Array_With_Strings Func _CSV_2_2DArray($file, $delim = ";") ; loads csv, returns 2d array Local $aLines Local $hFile = _FileReadToArray($file, $aLines, 0) Local $a2DArray[UBound($aLines)][UBound(StringSplit($aLines[0], $delim)) - 1] Local $aSubstring For $line = 0 To UBound($aLines) - 1 $aSubstring = StringSplit($aLines[$line], $delim) For $Col = 1 To $aSubstring[0] $a2DArray[$line][$Col - 1] = $aSubstring[$Col] Next Next Return $a2DArray EndFunc ;==>_CSV_2_2DArray Func _LiveSearchResults2D($aArray, $sString, $iColumn = 0, $iAddToWeight = -1) ; searches for string in array in column. returns array matches with first column with the weight of the match ; $aArray: the 2d array that is being searched through ; $sString: the search string ; $iColumn: the column that is being searched through ; $iAddToWeight: if -1 a new first column will be added with the weight. if bigger the column with that number will be used as the weight Local $iWeight ; the weight Local $sWord ; the word, that is being checked, not the search string If $iAddToWeight = -1 Then ; add extra column for the weight Local $aReturnArray[UBound($aArray)][UBound($aArray, 2) + 1]; the array that is going to be returned Else ; no extra column since the first one will be interpreted as the weight Local $aReturnArray[UBound($aArray)][UBound($aArray, 2)]; the array that is going to be returned EndIf For $i = 0 To UBound($aArray) - 1 ; compare each element in the array with the search string $sWord = $aArray[$i][$iColumn] ; put the search word into the variable If $iAddToWeight = -1 Then $aReturnArray[$i][$iColumn + 1] = $sWord ; put the article number into the temp array. we work only with that since we don't need the rest Else $aReturnArray[$i][$iColumn] = $sWord ; put the article number into the temp array. we work only with that since we don't need the rest EndIf If $iAddToWeight = -1 Then $iWeight = 0 ; set the initial weight to 0 Else $iWeight = $aArray[$i][$iAddToWeight] ; set the initial weight to whatever is in the first column EndIf If $sWord = $sString Then ; if string is an exact match $iWeight += 1000 Else ; if the string is not an exact match Local $aSplitString = StringSplit($sString, " ", 2) ; split the search string into multiple words, if there are any For $s = 0 To UBound($aSplitString) - 1 ; search and add weight for each word typed in Local $sSubString = $aSplitString[$s] ; save the substring in this variable If StringInStr($sWord, $sSubString, 2) Then ; if the string is a substring (case doesn't matter), it will be evaluated further $iWeight += 100 ; if the substring has been found, add weight ; add: 77 string has same left word boundry If StringRegExp($sWord, "(?i)(^|#| )" & $sSubString) = 1 Then $iWeight += 77 EndIf ; add: 54 string has same right word boundry If StringRegExp($sWord, "(?i)" & $sSubString & "($|#| )") = 1 Then $iWeight += 54 EndIf Else $iWeight -= 50 ; if nothing was found, decrease the weight by 100. this is needed when multiple words have been typed. one adds lots of weight, the other reduces it. so only relevant strings remain on top. EndIf Next EndIf If $iAddToWeight = -1 Then ; add things 1 column to the right, since we add the weight in the first column $aReturnArray[$i][0] = $iWeight - StringLen($sWord); add the weight to the array in column 0 For $tempCol = 1 To UBound($aReturnArray, 2) - 1 ; fill the array with the things in the other array $aReturnArray[$i][$tempCol] = $aArray[$i][$tempCol - 1] Next Else ; add things in the same column For $tempCol = 0 To UBound($aReturnArray, 2) - 1 ; fill the array with the things in the other array $aReturnArray[$i][$tempCol] = $aArray[$i][$tempCol] $aReturnArray[$i][$iAddToWeight] = $iWeight - StringLen($sWord); add the weight to the array Next EndIf Next If $iAddToWeight = -1 Then _ArraySort($aReturnArray, 1, 0, 0, 0) ; sort the first column, decending (sorts by weight) Else _ArraySort($aReturnArray, 1, 0, 0, $iAddToWeight) ; sort the first column, decending (sorts by weight) EndIf Return $aReturnArray EndFunc ;==>_LiveSearchResults2D Func _DisplayResultsAdvanced($hListView, $aArray, $sString = "test") ; displays the array in the list view For $Row = 0 To UBound($aArray) - 1 ; creates the list view items _GUICtrlListView_AddItem($hListView, $aArray[$Row][0], $Row) For $Col = 1 To UBound($aArray, 2) - 1 ; only first four columns are important here _GUICtrlListView_AddSubItem($hListView, $Row, $aArray[$Row][$Col], $Col) Next Next EndFunc ;==>_DisplayResultsAdvanced Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #horseref $hWnd, $iMsg, $iwParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo ; Local $tBuffer $hWndListView = $hGuiListview If Not IsHWnd($hGuiListview) Then $hWndListView = GUICtrlGetHandle($hGuiListview) $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndListView Switch $iCode Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam) $iClickedIndex = DllStructGetData($tInfo, "Index") EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY aktuelle_projekte_liste.csvalle_projekte_liste.csv Edited May 29, 2015 by Kira16651
Moderators Melba23 Posted May 29, 2015 Moderators Posted May 29, 2015 Kira16651,Glad I could help - and welcome to the AutoIt forums, by the way.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
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