#AutoIt3Wrapper_AU3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 Opt("MustDeclareVars", 1) #include #include #include #include #include #include #include #include "RandomArray.au3" Global $g_iRows = 1000, $g_iCols = 6, $g_iLeftLV = 10, $g_iTopLV = 40, $g_aArray, $g_aSubArray, $g_tIndex = DllStructCreate("uint arr[" & $g_iRows & "]"), $g_tDefaultIndex, $g_aIndex[$g_iCols], $g_aIndexTemp[$g_iCols], $g_iSortDir Global $g_aColNames[$g_iCols] = ["Strings", "Integers", "Floats", "Dates", "Times", "R/C"], $g_aColWidths[$g_iCols] = [230, 61, 124, 70, 60, 60], $g_aColAligns[$g_iCols] = [$HDF_RIGHT, $HDF_RIGHT, $HDF_RIGHT, $HDF_RIGHT, $HDF_RIGHT, $HDF_RIGHT] ; $HDF_LEFT, $HDF_RIGHT, $HDF_CENTER Global $g_hGui, $g_idListView, $g_hListView, $g_hHeader, $g_idMarker, $g_hEdit, $g_idEditDummy, $g_idComboCol, $g_idComboColDummy Global $g_sSearch, $g_iSearchCol, $g_iSearch = $g_iRows Global $g_idContextDummy, $g_hContextmenu, $g_iItem = -1, $g_iSubItem = -1, $g_iMenu_Choice ; for context menu Example() Func Example() ; Generate array & one index Generate_All($g_aArray) $g_aSubArray = $g_aArray $g_tDefaultIndex = $g_tIndex ; Create GUI $g_hGui = GUICreate("Virtual and Custom Drawn List View With Sorting and Incremental Search", 630 + 20, 788 + 30 + 20) Local $Left = GUICtrlCreateButton("Left", 120, 10, 40, 20) Local $Right = GUICtrlCreateButton("Right", 170, 10, 40, 20) ; Create Edit control ( search ) + dummy control Local $idEdit = GUICtrlCreateEdit("", 300, 10, 100, 20, BitXOR($GUI_SS_DEFAULT_EDIT, $WS_HSCROLL, $WS_VSCROLL)) $g_hEdit = GUICtrlGetHandle($idEdit) $g_idEditDummy = GUICtrlCreateDummy() ; Create ComboBox control ( how to search : RegEx or Normal ? ) Local $idSearchHow = GUICtrlCreateCombo("RegEx search", 11, 9, 100, 20, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_DROPDOWNLIST)) Local $sSearchHow = "RegEx search", $sSearchHowPrev = $sSearchHow ; Default way of searching ( changeable ) GUICtrlSetData($idSearchHow, "Normal search", $sSearchHow) ; Create ComboBox control ( column where to search ) + dummy control GUICtrlCreateLabel("Col", 429, 10, 20, 20, BitOR($SS_CENTERIMAGE, $SS_CENTER)) $g_idComboCol = GUICtrlCreateCombo("0", 452, 9, 41, 20, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_DROPDOWNLIST)) $g_iSearchCol = 0 ; Default column where to search ( changeable ) Local $iSearchColPrev = $g_iSearchCol For $i = 1 To $g_iCols - 1 GUICtrlSetData($g_idComboCol, $i & "|", $g_iSearchCol) Next $g_idComboColDummy = GUICtrlCreateDummy() ; Create Label control ( number of matching results ) Local $idResult = GUICtrlCreateLabel(" " & $g_iRows & " rows ( no pattern )", 501, 10, 135, 20, BitOR($SS_CENTERIMAGE, $SS_SUNKEN)) ; Create ListView $g_idListView = GUICtrlCreateListView("", $g_iLeftLV, $g_iTopLV, 630, 788, BitOR($GUI_SS_DEFAULT_LISTVIEW, $LVS_OWNERDATA), $WS_EX_CLIENTEDGE) _GUICtrlListView_SetExtendedListViewStyle($g_idListView, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT)) $g_hListView = GUICtrlGetHandle($g_idListView) $g_hHeader = _GUICtrlListView_GetHeader($g_idListView) For $i = 0 To $g_iCols - 1 _GUICtrlListView_AddColumn($g_idListView, $g_aColNames[$i], $g_aColWidths[$i]) _GUICtrlHeader_SetItemFormat($g_hHeader, $i, $HDF_STRING + $g_aColAligns[$i]) Next ; Create Context menu $g_idContextDummy = GUICtrlCreateDummy() Local $idContextMenu = GUICtrlCreateContextMenu($g_idContextDummy) Local $idContext1 = GUICtrlCreateMenuItem("Option 1", $idContextMenu) Local $idContext2 = GUICtrlCreateMenuItem("Option 2", $idContextMenu) Local $idContext3 = GUICtrlCreateMenuItem("Option 3", $idContextMenu) $g_hContextmenu = GUICtrlGetHandle($idContextMenu) ; No ListView column resizing by dragging header dividers ;_WinAPI_SetWindowLong( $hHeader, $GWL_STYLE, _WinAPI_GetWindowLong( $hHeader, $GWL_STYLE ) + $HDS_NOSIZING ) ; AutoIt 3.3.14.5 issue DllCall("user32.dll", "long_ptr", @AutoItX64 ? "SetWindowLongPtrW" : "SetWindowLongW", "hwnd", $g_hHeader, "int", $GWL_STYLE, "long_ptr", _ DllCall("user32.dll", "long_ptr", @AutoItX64 ? "GetWindowLongPtrW" : "GetWindowLongW", "hwnd", $g_hHeader, "int", $GWL_STYLE)[0] + $HDS_NOSIZING) ; Create Marker ( an orange line placed above the header of the column being searched ) $g_idMarker = GUICtrlCreateLabel("", 0, 0) GUICtrlSetBkColor(-1, 0xFFA060) ; Orange _MoveMarker($g_iSearchCol) GUICtrlSendMsg($g_idListView, $LVM_SETSELECTEDCOLUMN, $g_iSearchCol, 0) ; Sorting information $g_iSortDir = $HDF_SORTUP Local $iSortCol = 0, $iSortColPrev = 0 ; Register message handlers GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") ; Allocate memory for ListView rows GUICtrlSendMsg($g_idListView, $LVM_SETITEMCOUNT, $g_iRows, 0) ; Show GUI GUISetState(@SW_SHOW) ; Main loop While 1 Switch GUIGetMsg() Case $g_idContextDummy _GUICtrlListView_SetSelectedColumn($g_hListView, $g_iSubItem) $g_iMenu_Choice = _TrackPopupMenu($g_hContextmenu, $g_hGui, MouseGetPos(0), MouseGetPos(1)) If $g_iMenu_Choice Then Switch $g_iMenu_Choice Case $idContext1 _CM_test1() Case $idContext2 _CM_test2() Case $idContext3 _CM_test3() EndSwitch EndIf Case $Left $g_aColAligns[0] = $HDF_LEFT ; column 0 set align For $i = 0 To $g_iCols - 1 _GUICtrlHeader_SetItemFormat($g_hHeader, $i, $HDF_STRING + $g_aColAligns[$i]) Next GUICtrlSendMsg($g_idListView, $LVM_SETITEMCOUNT, $g_iSearch, 0) Case $Right $g_aColAligns[0] = $HDF_RIGHT ; column 0 set align For $i = 0 To $g_iCols - 1 _GUICtrlHeader_SetItemFormat($g_hHeader, $i, $HDF_STRING + $g_aColAligns[$i]) Next GUICtrlSendMsg($g_idListView, $LVM_SETITEMCOUNT, $g_iSearch, 0) Case $g_idComboCol, $g_idComboColDummy, $idSearchHow $g_iSearchCol = GUICtrlRead($g_idComboCol) + 0 ; Return int $sSearchHow = GUICtrlRead($idSearchHow) Select Case $g_iSearchCol <> $iSearchColPrev _MoveMarker($g_iSearchCol) ; Search column will be selected below, after ContinueCase $iSearchColPrev = $g_iSearchCol Case $sSearchHow <> $sSearchHowPrev $sSearchHowPrev = $sSearchHow Case Else ; No change in both Combo controls ( same search column, same search way ) ContinueLoop EndSelect ContinueCase Case $g_idEditDummy _GUICtrlHeader_SetItemFormat($g_hHeader, $iSortCol, $HDF_STRING + $g_aColAligns[$iSortCol]) $g_sSearch = GUICtrlRead($idEdit) $g_tIndex = $g_tDefaultIndex If $g_sSearch = "" Then ; Empty search string, display all rows $g_aSubArray = $g_aArray $g_iSearch = $g_iRows Else ; Find rows matching the search string $g_iSearch = 0 If $sSearchHow = "RegEx search" Then For $i = 0 To $g_iRows - 1 ; Duplicated For... Next for speed If StringRegExp($g_aArray[$i][$g_iSearchCol], "(?i)" & $g_sSearch) Then For $j = 0 To $g_iCols - 1 $g_aSubArray[$g_iSearch][$j] = $g_aArray[$i][$j] Next $g_iSearch += 1 EndIf Next Else ; "Normal search" For $i = 0 To $g_iRows - 1 ; Duplicated For... Next for speed If StringInStr($g_aArray[$i][$g_iSearchCol], $g_sSearch) Then For $j = 0 To $g_iCols - 1 $g_aSubArray[$g_iSearch][$j] = $g_aArray[$i][$j] Next $g_iSearch += 1 EndIf Next EndIf ; Delete eventual temporary subindexes For $i = 0 To $g_iCols - 1 If VarGetType($g_aIndexTemp[$i]) = "DLLStruct" Then $g_aIndexTemp[$i] = "" Next EndIf GUICtrlSendMsg($g_idListView, $LVM_SETITEMCOUNT, $g_iSearch, 0) GUICtrlSendMsg($g_idListView, $LVM_SETSELECTEDCOLUMN, $g_iSearchCol, 0) GUICtrlSetData($idResult, " " & $g_iSearch & ($g_sSearch = "" ? " rows ( no pattern )" : " matching rows")) Case $g_idListView ; Sort $iSortCol = GUICtrlGetState($g_idListView) + 0 If $iSortCol <> $iSortColPrev Then _GUICtrlHeader_SetItemFormat($g_hHeader, $iSortColPrev, $HDF_STRING + $g_aColAligns[$iSortColPrev]) ; Set $g_tIndex + eventual update of $g_aIndexTemp[$iSortCol] OR $g_aIndex[$iSortCol] $i = GUICtrlRead($idEdit) ? UpdateIndex($g_aIndexTemp, $iSortCol) : UpdateIndex($g_aIndex, $iSortCol) $g_iSortDir = (($iSortCol = $iSortColPrev) ? ($g_iSortDir = $HDF_SORTUP ? $HDF_SORTDOWN : $HDF_SORTUP) : ($HDF_SORTUP)) _GUICtrlHeader_SetItemFormat($g_hHeader, $iSortCol, $HDF_STRING + $g_aColAligns[$iSortCol] + $g_iSortDir) GUICtrlSendMsg($g_idListView, $LVM_SETSELECTEDCOLUMN, $iSortCol, 0) GUICtrlSendMsg($g_idListView, $LVM_SETITEMCOUNT, $g_iSearch, 0) $iSortColPrev = $iSortCol Case $GUI_EVENT_RESTORE ; Needed, or Marker goes back in 0, 0 after Restore ( why ? ) _MoveMarker($g_iSearchCol) Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup GUIDelete($g_hGui) EndFunc ;==>Example ;======================================================================== Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Switch HWnd(DllStructGetData($tNMHDR, "hWndFrom")) Case $g_hListView Switch DllStructGetData($tNMHDR, "Code") Case $NM_RCLICK Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam) $g_iItem = DllStructGetData($tInfo, "Index") If $g_iItem > -1 Then $g_iSubItem = DllStructGetData($tInfo, "SubItem") GUICtrlSendToDummy($g_idContextDummy) EndIf Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Switch DllStructGetData($tCustDraw, "dwDrawStage") ; Holds a value that specifies the drawing stage Case $CDDS_PREPAINT ; Before the paint cycle begins Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window of any item-related drawing operations Case $CDDS_ITEMPREPAINT ; Before painting an item Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window of any subitem-related drawing operations Case $CDDS_ITEMPREPAINT + $CDDS_SUBITEM ; Before painting a subitem If (DllStructGetData($tCustDraw, "iSubItem") = $g_iSearchCol) And $g_sSearch Then Return $CDRF_NOTIFYPOSTPAINT ; If $g_sSearch then paint $g_iSearchCol in postpaint stage Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors ; Paint all other columns in prepaint stage with default code Case $CDDS_ITEMPOSTPAINT + $CDDS_SUBITEM ; After painting a subitem ; Paints $g_iSearchCol ( $g_iSearchCol only ) if $g_sSearch Local Static $tRect = DllStructCreate($tagRECT), $pRect = DllStructGetPtr($tRect), $tSize = DllStructCreate($tagSIZE) Local Static $hBrushYellow = _WinAPI_CreateSolidBrush(0x00FFFF), $hBrushCyan = _WinAPI_CreateSolidBrush(0xFFFF00) ; Yellow and cyan, BGR Local $iItem = DllStructGetData($tCustDraw, "dwItemSpec"), $hDC = DllStructGetData($tCustDraw, "hDC") ; Subitem text and matching text Local $sSubItemText = $g_iSortDir = $HDF_SORTUP ? $g_aSubArray[$g_tIndex.arr($iItem + 1)][$g_iSearchCol] _ : $g_aSubArray[$g_tIndex.arr($g_iSearch - $iItem)][$g_iSearchCol] Local $sMatch = StringRegExp($sSubItemText, "(?i)" & $g_sSearch, 1), $extended = @extended, $iLen = StringLen($sMatch[0]) ; Entire subitem rectangle DllStructSetData($tRect, 2, $g_iSearchCol) ; Top DllStructSetData($tRect, 1, $LVIR_BOUNDS) ; Left GUICtrlSendMsg($g_idListView, $LVM_GETSUBITEMRECT, $iItem, $pRect) DllStructSetData($tRect, 1, DllStructGetData($tRect, 1) + 6) ; Left margin If Not $g_iSearchCol Then DllStructSetData($tRect, 3, DllStructGetData($tRect, 1) + GUICtrlSendMsg($g_idListView, $LVM_GETCOLUMNWIDTH, 0, 0)) ; If $g_iSearchCol = 0 (first column), the rectangle is calculated for the entire listview item. ; Compensate for this by setting the width of the rectangle to the width of the first column. ; Subitem rectangle for right and center aligned columns If $g_aColAligns[$g_iSearchCol] = $HDF_RIGHT Or $g_aColAligns[$g_iSearchCol] = $HDF_CENTER Then DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $sSubItemText, "int", StringLen($sSubItemText), "struct*", $tSize) ; _WinAPI_GetTextExtentPoint32 Switch $g_aColAligns[$g_iSearchCol] Case $HDF_RIGHT DllStructSetData($tRect, "Left", DllStructGetData($tRect, "Right") - DllStructGetData($tSize, "X") - 6) Case $HDF_CENTER DllStructSetData($tRect, "Left", DllStructGetData($tRect, "Left") + (DllStructGetData($tRect, "Right") - DllStructGetData($tRect, "Left") - DllStructGetData($tSize, "X")) / 2 - 3) EndSwitch EndIf ; Set transparent background for the subitem DllCall("gdi32.dll", "int", "SetBkMode", "handle", $hDC, "int", $TRANSPARENT) ; _WinAPI_SetBkMode ; Draw entire subitem text DllStructSetData($tRect, 2, DllStructGetData($tRect, 2) + 2) ; Top margin DllCall("user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $sSubItemText, "int", StringLen($sSubItemText), "struct*", $tRect, "uint", 0) ; _WinAPI_DrawText DllStructSetData($tRect, 2, DllStructGetData($tRect, 2) - 2) ; Top margin ; Rectangle for matching substring DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $sSubItemText, "int", $extended - $iLen - 1, "struct*", $tSize) ; _WinAPI_GetTextExtentPoint32 DllStructSetData($tRect, "Left", DllStructGetData($tRect, "Left") + DllStructGetData($tSize, "X")) DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $sMatch[0], "int", $iLen, "struct*", $tSize) ; _WinAPI_GetTextExtentPoint32 DllStructSetData($tRect, "Right", DllStructGetData($tRect, "Left") + DllStructGetData($tSize, "X")) ; Fill matching rectangle with yellow or cyan background color DllCall("user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $tRect, "handle", GUICtrlSendMsg($g_idListView, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED) ? $hBrushYellow : $hBrushCyan) ; _WinAPI_FillRect ; Redraw matching text on the yellow or cyan background DllStructSetData($tRect, 2, DllStructGetData($tRect, 2) + 2) ; Top margin DllCall("gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int", 0x000000) ; _WinAPI_SetTextColor DllCall("user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $sMatch[0], "int", $iLen, "struct*", $tRect, "uint", 0) ; _WinAPI_DrawText Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch Case $LVN_GETDISPINFOW Local $tNMLVDISPINFO = DllStructCreate($tagNMLVDISPINFO, $lParam) If ($tNMLVDISPINFO.SubItem = $g_iSearchCol) And $g_sSearch Then Return ; Don't paint $g_iSearchCol if $g_sSearch Local Static $tText = DllStructCreate("wchar[50]"), $pText = DllStructGetPtr($tText) Local $s = $g_iSortDir = 0x0400 ? DllStructSetData($tText, 1, $g_aSubArray[$g_tIndex.arr($tNMLVDISPINFO.Item + 1)][$tNMLVDISPINFO.SubItem]) _ ; 0x0400 = $HDF_SORTUP : DllStructSetData($tText, 1, $g_aSubArray[$g_tIndex.arr($g_iSearch - $tNMLVDISPINFO.Item)][$tNMLVDISPINFO.SubItem]) DllStructSetData($tNMLVDISPINFO, "Text", $pText) EndSwitch Case $g_hHeader Switch DllStructGetData($tNMHDR, "Code") Case $HDN_ENDTRACKW, $HDN_DIVIDERDBLCLICKW ; let's forget $HDN_TRACKW... _MoveMarker(GUICtrlRead($g_idComboCol)) Case $NM_RCLICK Local $aHit = _GUICtrlListView_SubItemHitTest($g_hListView) ; $aHit[1] : 0-based index of the LV subitem... i.e. the column in our case (may be -1 if right click on empty part of header) If $aHit[1] > -1 Then ; valid column GUICtrlSetData($g_idComboCol, $aHit[1]) GUICtrlSendToDummy($g_idComboColDummy) EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG #forceref $hWnd, $iMsg, $wParam, $s EndFunc ;==>WM_NOTIFY Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Switch $lParam ; $hWndFrom Case $g_hEdit Switch BitShift($wParam, 16) ; $iCode = High word Case $EN_CHANGE GUICtrlSendToDummy($g_idEditDummy) EndSwitch EndSwitch Return $GUI_RUNDEFMSG #forceref $hWnd, $iMsg EndFunc ;==>WM_COMMAND Func Generate_All(ByRef $g_aArray) $g_aArray = FAS_Random2DArrayAu3($g_iRows, "sifdtr", "abcdefghijklmnopqrstuvwxyz") For $i = 0 To $g_iRows - 1 $g_tIndex.arr($i + 1) = $i Next EndFunc ;==>Generate_All Func SortArrayStruct($aArray, $iCol, $iRows) Local Static $hDll = DllOpen("kernel32.dll"), $hDllComp = DllOpen("shlwapi.dll") Local $tIndex = DllStructCreate("uint arr[" & $iRows & "]"), $pIndex = DllStructGetPtr($tIndex) ; Sorting by one column Local $lo, $hi, $mi For $i = 1 To $iRows - 1 $lo = 0 $hi = $i - 1 Do $mi = Int(($lo + $hi) / 2) Switch DllCall($hDllComp, 'int', 'StrCmpLogicalW', 'wstr', $aArray[$i][$iCol], 'wstr', $aArray[DllStructGetData($tIndex, 1, $mi + 1)][$iCol])[0] Case -1 $hi = $mi - 1 Case 1 $lo = $mi + 1 Case 0 ExitLoop EndSwitch Until $lo > $hi DllCall($hDll, "none", "RtlMoveMemory", "struct*", $pIndex + ($mi + 1) * 4, "struct*", $pIndex + $mi * 4, "ulong_ptr", ($i - $mi) * 4) DllStructSetData($tIndex, 1, $i, $mi + 1 + ($lo = $mi + 1)) Next Return $tIndex EndFunc ;==>SortArrayStruct Func UpdateIndex(ByRef $aIndex, $iCol) If VarGetType($aIndex[$iCol]) = "DLLStruct" Then $g_tIndex = $aIndex[$iCol] Else $g_tIndex = SortArrayStruct($g_aSubArray, $iCol, $g_iSearch) $aIndex[$iCol] = $g_tIndex EndIf EndFunc ;==>UpdateIndex Func _MoveMarker($iCol) Local $aRect = _GUICtrlHeader_GetItemRect($g_hHeader, $iCol) ;ControlMove($g_hGui, "", $g_idMarker, 10 + $aRect[0], 40 - 3, $aRect[2] - $aRect[0] + 1, 3) ControlMove($g_hGui, "", $g_idMarker, $g_iLeftLV + $aRect[0], $g_iTopLV - 3, $aRect[2] - $aRect[0] + 1, 3) EndFunc ;==>_MoveMarker Func _TrackPopupMenu($hMenu, $hWnd, $iX, $iY) ; $TPM_RETURNCMD returns the menu item identifier of the user's selection in the return value. Return DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", $TPM_RETURNCMD, "int", $iX, "int", $iY, "hwnd", $hWnd, "ptr", 0)[0] EndFunc ;==>_TrackPopupMenu Func _CM_test1() Local $sTextMenu = _GUICtrlMenu_GetItemText($g_hContextmenu, $g_iMenu_Choice, False) Local $sTextLV = _GUICtrlListView_GetItemText($g_hListView, $g_iItem, $g_iSubItem) MsgBox($MB_TOPMOST, $sTextMenu, "Func1:" & @CRLF & "Row = " & $g_iItem & " Column = " & $g_iSubItem & " Text = " & $sTextLV & @LF) EndFunc ;==>_CM-test1 Func _CM_test2() Local $sTextMenu = _GUICtrlMenu_GetItemText($g_hContextmenu, $g_iMenu_Choice, False) Local $sTextLV = _GUICtrlListView_GetItemText($g_hListView, $g_iItem, $g_iSubItem) MsgBox($MB_TOPMOST, $sTextMenu, "Func2:" & @CRLF & "Row = " & $g_iItem & " Column = " & $g_iSubItem & " Text = " & $sTextLV & @LF) EndFunc Func _CM_test3() Local $sTextMenu = _GUICtrlMenu_GetItemText($g_hContextmenu, $g_iMenu_Choice, False) Local $sTextLV = _GUICtrlListView_GetItemText($g_hListView, $g_iItem, $g_iSubItem) MsgBox($MB_TOPMOST, $sTextMenu, "Func3:" & @CRLF & "Row = " & $g_iItem & " Column = " & $g_iSubItem & " Text = " & $sTextLV & @LF) EndFunc