goss34

Search In ListView (Redraw with matching string)

11 posts in this topic

Hi Guys,

I am writing an app that involves a list view with for example 100 rows. I have added an input box and search button to search the list view for whatever was in the input box.

I found this function on the forum:

Button2()

Func Button2()
    ;MsgBox(0, "Button2", GUICtrlRead($Input))
    $value = GUICtrlRead($Input)
    ; Search for target item
    $iI = _GUICtrlListView_FindInText($ListView1, $value, -1)
    _GUICtrlListView_EnsureVisible($ListView1, $iI)
EndFunc

This works to a degree but only jumps to a matching string and not in every case even though the string is definitely in the list view.

What i want to do is redraw the listview with any results matching or part matching the string in the input box. 

Im sure someone will of already done this if so could i see the code as i do not know where to begin.

Thanks,

Dan

 

Share this post


Link to post
Share on other sites



Here is an example for filtering a LlistView

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

Example()

Func Example()
    Local $idListview, $idListview1, $aArr, $iNoCols = 10, $iNoItems = 100, $iDataLimit_0To = 5, $sFind, $aArrData[$iNoItems][$iNoCols]
    Local $sCols = "col0"
    GUICreate("ListView Original", 500, 350, 0, 0, $WS_SIZEBOX)
    GUICtrlCreateLabel("Filter", 4, 302)
    Local $idInput = GUICtrlCreateInput("2", 40, 302, 355, 25)
    Local $FilterBut = GUICtrlCreateButton("Go", 400, 302, 30, 25)
    For $m = 1 To $iNoCols - 1
        $sCols &= "|col" & $m
    Next
    $idListview = GUICtrlCreateListView($sCols, 0, 0, 500, 300)

    ; ------- Create data in array for ListView ------------------
    For $j = 0 To $iNoItems - 1
        $sData = "index " & $j
        $aArrData[$j][0] = $sData
        For $k = 1 To $iNoCols - 1
            $aArrData[$j][$k] = Random(0, $iDataLimit_0To, 1) & Random(0, $iDataLimit_0To, 1) & _
                    Random(0, $iDataLimit_0To, 1) & Random(0, $iDataLimit_0To, 1) & Random(0, $iDataLimit_0To, 1)
        Next
    Next
    _GUICtrlListView_AddArray($idListview, $aArrData)
    _GUICtrlListView_SetColumnWidth($idListview, 0, 55)
    GUISetState(@SW_SHOW)

    ; ------- Create 2nd GUI and ListView and fill with same data. ---------------
    GUICreate("ListView Filtered", 500, 330, @DesktopWidth / 2, 0, $WS_SIZEBOX)
    $idListview1 = GUICtrlCreateListView($sCols, 0, 0, 500, 300)
    _GUICtrlListView_AddArray($idListview1, $aArrData)
    _GUICtrlListView_SetColumnWidth($idListview1, 0, 55)
    GUISetState(@SW_SHOW)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exitloop
            Case $FilterBut
                $sFind = GUICtrlRead($idInput)
                If $sFind <> "" Then
                    _GUICtrlListView_DeleteAllItems($idListview1)
                    For $i = 0 To _GUICtrlListView_GetItemCount($idListview) - 1
                        $aArr = _GUICtrlListView_GetItemTextArray($idListview, $i)
                        $sData1 = ""
                        For $n = 1 To UBound($aArr) - 1
                            If StringInStr($aArr[$n], $sFind) = 0 Then $aArr[$n] = "---" ; <<<< Apply filter
                            $sData1 &= $aArr[$n] & "|"
                        Next
                        GUICtrlCreateListViewItem($sData1, $idListview1)
                    Next
                Else ; When no filter present.
                    _GUICtrlListView_DeleteAllItems($idListview1)
                    _GUICtrlListView_AddArray($idListview1, $aArrData)
                EndIf
        EndSwitch
    WEnd
    GUIDelete()
EndFunc   ;==>Example

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

goss34, You can find an example with a search field and a virtual listview here. Initially the listview is filled out with 1000 rows of random strings with a length between 10 and 30 characters.

When you type in a search string in the search field (edit control), the listview is updated with the rows, that matches the search string. The listview is updated dynamically while the search string is typed in. The search string can be a regular expression.

 

 

Edited by LarsJ

Share this post


Link to post
Share on other sites

Woah, thanks for the replies guys, i have just picked up the examples and trying to figure out what i need to amend my list view.

Be back once i have had time to work through them.

Thanks

Dan

Share this post


Link to post
Share on other sites

Hi Guys,

I am trying to follow LarsJ example but its going way over my skill level at the moment. 

Any chance someone could slim it down or comment it so i can try to understand what is actually going on.

I just made this reproducer quickly (haha not as quick as you might think) but its doing the same as i am doing in my script at the moment although the search works better with the simple strings it currently has! Maybe you could merge the 2 so i can grasp whats going on in the big example? (I do struggle to understand whats happening when arrays are involved).

#include <GUIConstants.au3>
#include <GuiListView.au3>
#include <Array.au3>
#include <File.au3>
#include <ButtonConstants.au3>


Global $Fill = @ScriptDir & "\sample.ini"

IniWriteSection(@ScriptDir & "\sample.ini", "ITEM1", "1=2")
IniWriteSection(@ScriptDir & "\sample.ini", "ITEM2", "1=3")
IniWriteSection(@ScriptDir & "\sample.ini", "ITEM3", "1=4")
IniWriteSection(@ScriptDir & "\sample.ini", "ITEM4", "1=5")
IniWriteSection(@ScriptDir & "\sample.ini", "ITEM5", "1=6")
IniWriteSection(@ScriptDir & "\sample.ini", "ITEM6", "1=7")
IniWriteSection(@ScriptDir & "\sample.ini", "ITEM7", "1=8")
IniWriteSection(@ScriptDir & "\sample.ini", "ITEM8", "1=9")
IniWriteSection(@ScriptDir & "\sample.ini", "ITEM9", "1=10")
IniWriteSection(@ScriptDir & "\sample.ini", "ITEM10", "1=11")
IniWriteSection(@ScriptDir & "\sample.ini", "ITEM11", "1=12")

$Gui = GUICreate("Gui", 300, 250)
$LV = GUICtrlCreateListView("Item|Value", 18, 40, 260, 200)
_GUICtrlListView_SetExtendedListViewStyle($LV, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))
GUICtrlSendMsg(-1, 0x101E, 0, 130)
GUICtrlSendMsg(-1, 0x101E, 1, 125)
;GUICtrlCreateTabItem("") ; This ends the tab item creation
$Button2 = GUICtrlCreateButton("Search", 180, 10, 100, 22, 0)
$Input = GUICtrlCreateInput("Enter Search Term...", 20, 10, 150, 22)

Populate()
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            FileDelete($Fill)
            Exit
        Case $Button2
            Search()
    EndSwitch
WEnd


Func Populate()
    Local $aArray = IniReadSectionNames($Fill)
    If Not @error Then
        ; Enumerate through the array displaying the section names.
        For $i = 1 To $aArray[0]
        $Value = IniRead($Fill, $aArray[$i], "1", "")
        GUICtrlCreateListViewItem($aArray[$i] & "|" & $Value, $LV)
        ;_GUICtrlListView_SimpleSort($ListView1, $Sort, 0, False) ;<<<<<<<<<<<<<< Works but slows down load time.
        Next
    EndIf
EndFunc


Func Search()
    $value = GUICtrlRead($Input)
    $iI = _GUICtrlListView_FindInText($LV, $value, -1)
    _GUICtrlListView_EnsureVisible($LV, $iI)
EndFunc

Thanks for your help so far.

Dan

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Try this. The search is in the Item field. Press 1 to get all items with "1" in the item field.

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

Opt( "MustDeclareVars", 1 )

Global $hGui, $hEdit, $idEditSearch, $hLV, $iItems = 1000, $aItems[$iItems][2], $aSearch[$iItems], $iSearch = 0, $Fill

Example()


Func Example()
  $Fill = @ScriptDir & "\sample.ini"
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM1", "1=2")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM2", "1=3")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM3", "1=4")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM4", "1=5")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM5", "1=6")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM6", "1=7")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM7", "1=8")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM8", "1=9")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM9", "1=10")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM10", "1=11")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM11", "1=12")

  ; Create GUI
  $hGui = GUICreate( "Gui", 300, 230 )

  ; Create Edit control
  Local $idEdit = GUICtrlCreateEdit( "", 10, 10, 300-20, 20, BitXOR( $GUI_SS_DEFAULT_EDIT, $WS_HSCROLL, $WS_VSCROLL ) )
  $hEdit = GUICtrlGetHandle( $idEdit )
  $idEditSearch = GUICtrlCreateDummy()

  ; Handle $WM_COMMAND messages from Edit control
  ; To be able to read the search string dynamically while it's typed in
  GUIRegisterMsg( $WM_COMMAND, "WM_COMMAND" )

  ; Create ListView                                                Virtual listview
  Local $idLV = GUICtrlCreateListView( "", 10, 40, 300-20, 200-20, $LVS_OWNERDATA )
  $hLV = GUICtrlGetHandle( $idLV )
  _GUICtrlListView_SetExtendedListViewStyle( $hLV, BitOR( $LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES ) )
  _GUICtrlListView_AddColumn( $hLV, "Item",  130 )
  _GUICtrlListView_AddColumn( $hLV, "Value", 125 )

  ; Handle $WM_NOTIFY messages from ListView
  ; Necessary to display the rows in a virtual ListView
  GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )

  ; Show GUI
  GUISetState( @SW_SHOW )

  ; Fill array
  Local $aArray = IniReadSectionNames($Fill), $Value
  If Not @error Then
    ; Enumerate through the array displaying the section names.
    For $i = 1 To $aArray[0]
      $Value = IniRead($Fill, $aArray[$i], "1", "")
      $aItems[$i-1][0] = $aArray[$i]
      $aItems[$i-1][1] = $Value
    Next
    $iItems = $aArray[0]
  EndIf

  ; Set search array to include all items
  For $i = 0 To $iItems - 1
    $aSearch[$i] = $i
  Next
  $iSearch = $iItems

  ; Display items
  GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iSearch, 0 )

  ; Message loop
  While 1
    Switch GUIGetMsg()
      Case $idEditSearch
        Local $sSearch = GUICtrlRead( $idEdit )
        If $sSearch = "" Then
          ; Empty search string, display all rows
          For $i = 0 To $iItems - 1
            $aSearch[$i] = $i
          Next
          $iSearch = $iItems
        Else
          ; Find rows matching the search string
          $iSearch = 0
          For $i = 0 To $iItems - 1
            If StringInStr( $aItems[$i][0], $sSearch ) Then ; Normal search
            ;If StringRegExp( $aItems[$i][0], $sSearch ) Then ; Reg. exp. search
              $aSearch[$iSearch] = $i
              $iSearch += 1
            EndIf
          Next
        EndIf
        ; Display items
        GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iSearch, 0 )
        ConsoleWrite( StringFormat( "%4d", $iSearch ) & " rows matching """ & $sSearch & """" & @CRLF )

      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  GUIDelete()
EndFunc

Func WM_COMMAND( $hWnd, $iMsg, $wParam, $lParam )
  Local $hWndFrom = $lParam
  Local $iCode = BitShift( $wParam, 16 ) ; High word
  Switch $hWndFrom
    Case $hEdit
      Switch $iCode
        Case $EN_CHANGE
          GUICtrlSendToDummy( $idEditSearch )
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc

Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local Static $tText = DllStructCreate( "wchar[50]" )
  Local Static $pText = DllStructGetPtr( $tText )

  Local $tNMHDR, $hWndFrom, $iCode
  $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
  $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
  $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hLV
      Switch $iCode
        Case $LVN_GETDISPINFOW
          Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )
          If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
            Local $sItem = $aItems[$aSearch[DllStructGetData($tNMLVDISPINFO,"Item")]][DllStructGetData($tNMLVDISPINFO,"SubItem")]
            DllStructSetData( $tText, 1, $sItem )
            DllStructSetData( $tNMLVDISPINFO, "Text", $pText )
            DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )
          EndIf
      EndSwitch
  EndSwitch

  Return $GUI_RUNDEFMSG
EndFunc

 

Edited by LarsJ

Share this post


Link to post
Share on other sites

That works great Lars, I am working on implementing that into my code now. I have to say its some clever stuff! It seems this particular function is a lot harder to achieve that i first thought it would be. 

I started with 3 lines of code and almost had it doing what i wanted and now i have 144 lines :lmao:

Got to admit i still do not understand it but I am going to give it a shot!

Cheers

Dan

Share this post


Link to post
Share on other sites

Here is another example of filtering a LlistView.

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

Global $idListview, $iNoCols = 2, $iNoItems = 1000, $aArrData[$iNoItems][$iNoCols], $idInput

Example()

Func Example()
    Local $sCols = "col0"
    GUICreate("ListView Original", 500, 350, -1, -1, $WS_SIZEBOX)
    GUICtrlCreateLabel("Filter", 4, 302)
    GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT + $GUI_DOCKLEFT + $GUI_DOCKWIDTH)
    $idInput = GUICtrlCreateInput("", 40, 302, 355, 25)
    GUICtrlSetResizing($idInput, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT + $GUI_DOCKLEFT)

    For $m = 1 To $iNoCols - 1
        $sCols &= "|col" & $m
    Next
    $idListview = GUICtrlCreateListView($sCols, 0, 0, 500, 300)
    GUICtrlSetResizing($idListview, $GUI_DOCKBOTTOM + $GUI_DOCKTOP)

    ; ------- Create data in array for ListView ------------------
    $Fill = @ScriptDir & "\sample.ini"
    For $i = 1 To $iNoItems
        IniWrite(@ScriptDir & "\sample.ini", "ITEM", "ITEM " & $i, $i + 1)
    Next
    $aArrData = IniReadSection(@ScriptDir & "\sample.ini", "ITEM")
    _ArrayDelete($aArrData, 0) ; Remove number of elements from array

    _GUICtrlListView_AddArray($idListview, $aArrData)
    _GUICtrlListView_SetColumnWidth($idListview, 0, 80)

    GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")
    GUISetState(@SW_SHOW)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
    GUIDelete()
EndFunc   ;==>Example

Func MY_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $iIDFrom = BitAND($wParam, 0xFFFF);LoWord
    Local $iCode = BitShift($wParam, 16) ;HiWord
    If $iIDFrom = $idInput And $iCode = $EN_CHANGE Then
        _GUICtrlListView_DeleteAllItems($idListview)
        _GUICtrlListView_AddArray($idListview, $aArrData)
        $sFind = GUICtrlRead($idInput)
        If $sFind <> "" Then
            For $i = _GUICtrlListView_GetItemCount($idListview) To 0 Step -1
                $sText = _GUICtrlListView_GetItemText($idListview, $i)
                If StringInStr($sText, $sFind) = 0 Then _GUICtrlListView_DeleteItem($idListview, $i); <<<< Apply filter
            Next
        EndIf
    EndIf
EndFunc   ;==>MY_WM_COMMAND

 

Share this post


Link to post
Share on other sites

goss34, Yesterday you reported a problem about extracting data from a virtual listview on double click. It seems as if your thread got lost because of the failed upgrade of the forum software and the subsequent restore of the backup from friday morning.

In your thread from yesterday you were referring to an old case. I have found the old case and added the answer here.

You were using this code in the WM_NOTIFY function to extract data on double click:

Local $sSelected = _GUICtrlListView_GetItemTextString( $hLV, -1 )
ConsoleWrite( "Double Click" & @CR & $sSelected & @CR )

_GUICtrlListView_GetItemTextString does not work for a virtual listview. Instead, you need to extract data directly from the array that feeds your listview:

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

Opt( "MustDeclareVars", 1 )

Global $hGui, $hEdit, $idEditSearch, $hLV, $iItems = 1000, $aItems[$iItems][2], $aSearch[$iItems], $iSearch = 0, $Fill

Example()


Func Example()
  $Fill = @ScriptDir & "\sample.ini"
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM1", "1=2")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM2", "1=3")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM3", "1=4")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM4", "1=5")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM5", "1=6")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM6", "1=7")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM7", "1=8")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM8", "1=9")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM9", "1=10")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM10", "1=11")
  IniWriteSection(@ScriptDir & "\sample.ini", "ITEM11", "1=12")

  ; Create GUI
  $hGui = GUICreate( "Gui", 300, 230 )

  ; Create Edit control
  Local $idEdit = GUICtrlCreateEdit( "", 10, 10, 300-20, 20, BitXOR( $GUI_SS_DEFAULT_EDIT, $WS_HSCROLL, $WS_VSCROLL ) )
  $hEdit = GUICtrlGetHandle( $idEdit )
  $idEditSearch = GUICtrlCreateDummy()

  ; Handle $WM_COMMAND messages from Edit control
  ; To be able to read the search string dynamically while it's typed in
  GUIRegisterMsg( $WM_COMMAND, "WM_COMMAND" )

  ; Create ListView                                                Virtual listview
  Local $idLV = GUICtrlCreateListView( "", 10, 40, 300-20, 200-20, $LVS_OWNERDATA )
  $hLV = GUICtrlGetHandle( $idLV )
  _GUICtrlListView_SetExtendedListViewStyle( $hLV, BitOR( $LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES ) )
  _GUICtrlListView_AddColumn( $hLV, "Item",  130 )
  _GUICtrlListView_AddColumn( $hLV, "Value", 125 )

  ; Handle $WM_NOTIFY messages from ListView
  ; Necessary to display the rows in a virtual ListView
  GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )

  ; Show GUI
  GUISetState( @SW_SHOW )

  ; Fill array
  Local $aArray = IniReadSectionNames($Fill), $Value
  If Not @error Then
    ; Enumerate through the array displaying the section names.
    For $i = 1 To $aArray[0]
      $Value = IniRead($Fill, $aArray[$i], "1", "")
      $aItems[$i-1][0] = $aArray[$i]
      $aItems[$i-1][1] = $Value
    Next
    $iItems = $aArray[0]
  EndIf

  ; Set search array to include all items
  For $i = 0 To $iItems - 1
    $aSearch[$i] = $i
  Next
  $iSearch = $iItems

  ; Display items
  GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iSearch, 0 )

  ; Message loop
  While 1
    Switch GUIGetMsg()
      Case $idEditSearch
        Local $sSearch = GUICtrlRead( $idEdit )
        If $sSearch = "" Then
          ; Empty search string, display all rows
          For $i = 0 To $iItems - 1
            $aSearch[$i] = $i
          Next
          $iSearch = $iItems
        Else
          ; Find rows matching the search string
          $iSearch = 0
          For $i = 0 To $iItems - 1
            If StringInStr( $aItems[$i][0], $sSearch ) Then ; Normal search
            ;If StringRegExp( $aItems[$i][0], $sSearch ) Then ; Reg. exp. search
              $aSearch[$iSearch] = $i
              $iSearch += 1
            EndIf
          Next
        EndIf
        ; Display items
        GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iSearch, 0 )
        ConsoleWrite( StringFormat( "%4d", $iSearch ) & " rows matching """ & $sSearch & """" & @CRLF )

      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  GUIDelete()
EndFunc

Func WM_COMMAND( $hWnd, $iMsg, $wParam, $lParam )
  Local $hWndFrom = $lParam
  Local $iCode = BitShift( $wParam, 16 ) ; High word
  Switch $hWndFrom
    Case $hEdit
      Switch $iCode
        Case $EN_CHANGE
          GUICtrlSendToDummy( $idEditSearch )
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc

Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local Static $tText = DllStructCreate( "wchar[50]" )
  Local Static $pText = DllStructGetPtr( $tText )

  Local $tNMHDR, $hWndFrom, $iCode
  $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
  $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
  $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hLV
      Switch $iCode
        Case $LVN_GETDISPINFOW
          Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )
          If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
            Local $sItem = $aItems[$aSearch[DllStructGetData($tNMLVDISPINFO,"Item")]][DllStructGetData($tNMLVDISPINFO,"SubItem")]
            DllStructSetData( $tText, 1, $sItem )
            DllStructSetData( $tNMLVDISPINFO, "Text", $pText )
            DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )
          EndIf
        Case $NM_DBLCLK
          ;Local $sSelected = _GUICtrlListView_GetItemTextString( $hLV, -1 )
          Local $tNMITEMACTIVATE = DllStructCreate( $tagNMITEMACTIVATE, $lParam )
          Local $iIndex = DllStructGetData( $tNMITEMACTIVATE, "Index" )
          Local $sSelected = $aItems[$aSearch[$iIndex]][0] & "|" & _ ; Column 0
                             $aItems[$aSearch[$iIndex]][1]           ; Column 1
          ConsoleWrite( "Double Click" & @CR & $sSelected & @CR )
      EndSwitch
  EndSwitch

  Return $GUI_RUNDEFMSG
EndFunc

 

Share this post


Link to post
Share on other sites

Hi Lars,

Thank you so much for replying even though the new thread disappeared, much appreciated.

I have managed to implement the double click using the example above but i am struggling to come up with a way to launch a function after the doubleclick without hanging the listview, it still produces the blanked out row.

I have worked around it so it does what i want but it does hang the listview and i need to scroll after the function finishes in order to get it to redraw the entries. I am pretty sure i am missing something simple but could use a pointer :'(

Cheers

Dan

Share this post


Link to post
Share on other sites

Nevermind Lars,

Got there in the end, i knew why it was hanging but didnt know how to get what i wanted to action.

Re-read the tutorial - https://www.autoitscript.com/wiki/Tutorial_GUIRegisterMsg and a post of Melbas and sorted the code accordingly so i now set a value to true after the double click and process an action under the while so it no longer hangs the GUI.

Thanks for all your help as usual.

Dan

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

  • Similar Content

    • AndyS19
      By AndyS19
      I have a listview with 3 columns and I want to set the 3rd column's color based on the item's 'Param' value, but even though I set up for the 3rd column, the entire row always gets the color.
      My test code is below, but here is the pertinent code:
      Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam, $ilParam Local $hWndFrom, $iCode, $tNMHDR $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW Local $iDrawStage, $tCustDraw $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $ilParam) $iDrawStage = DllStructGetData($tCustDraw, 'dwDrawStage') Switch $iDrawStage Case BitOR(0, $CDDS_ITEMPREPAINT) ;, $CDDS_SUBITEM) setItemColor($tCustDraw, $hWndFrom) Return $CDRF_NOTIFYSUBITEMDRAW EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func setItemColor($tCustDraw, $hWnd) Local $iIndex, $color, $iSubitem $iIndex = DllStructGetData($tCustDraw, 'dwItemSpec') ; item number $color = _GUICtrlListView_GetItemParam($hWnd, $iIndex) $iSubitem = DllStructGetData($tCustDraw, 'iSubItem') ; Here, I want to only change the color of the 3rd col, and not the 1st and 2nd cols DllStructSetData($tCustDraw, 'iSubItem', 2) ; always use the 3rd column (the 'sample' col) logmsg("+++: setItemColor($tCustDraw, 0x" & Hex($hWnd) & ") entered ... " _ & ", $iIndex = " & $iIndex & ", $iSubItem = " & $iSubitem & ", $color = " & Hex($color)) DllStructSetData($tCustDraw, 'clrText', $color) ; set the Text color DllStructSetData($tCustDraw, 'clrTextBk', bitnot($color)) ; set the background color EndFunc ;==>setItemColor Func logmsg($msg, $lnum = @ScriptLineNumber) ConsoleWrite("+++:" & $lnum & ": " & $msg & @CRLF) EndFunc ;==>logmsg
      Here is the full test code:
      #include-once ;#cs #NoTrayIcon #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #AutoIt3Wrapper_UseX64=N Opt("GUICloseOnESC", 1) ; ESC closes GUI? (0 = no, 1 = yes) Opt("GUIOnEventMode", 1) ; Change to OnEvent mode Opt('MustDeclareVars', 1) OnAutoItExitRegister("_test_exit") Opt("GUIEventOptions", 1) ;0=default, 1=just notification, 2=GuiCtrlRead tab index Opt("WinTitleMatchMode", -2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase #include <GuiListBox.au3> #include <ListViewConstants.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <ColorConstants.au3> Global $__MCP_obj, $__MCP_GUI_hWnd, $idListView, $hListView Global $hMainWin test() Exit Func test() $hMainWin = GUICreate("Test window", 120, 100, @DesktopWidth / 2, -1) GUICtrlCreateButton("Hwnd", 10, 10, 40, 20) GUICtrlSetOnEvent(-1, "handle_1stTEST_btn") GUICtrlCreateButton("ID", 50, 10, 40, 20) GUICtrlSetOnEvent(-1, "handle_2ndTEST_btn") GUISetOnEvent($GUI_EVENT_CLOSE, "_test_exit") GUISetState(@SW_SHOW) While (1) Sleep(17) WEnd EndFunc ;==>test Func _myColorPicker($obj) logmsg("+++: $obj = 0x" & Hex($obj) & @CRLF) Local $flags = 0 Local $ww, $wh, $x, $y, $w, $h $__MCP_obj = $obj $ww = 350 $wh = 500 $x = 200 $y = 150 $__MCP_GUI_hWnd = GUICreate("myColorPicker", $ww, $wh, $x, $y, $flags) $x = 10 $y = 10 $w = 150 $h = 20 GUICtrlCreateButton("Set caller's color", $x, $y, $w, $h) GUICtrlSetOnEvent(-1, "__MCP_handle_SetColor_btn") $y += $h + 5 $w = $ww - 25 $h = $wh - 100 $idListView = GUICtrlCreateListView("", $x, $y, $w, $h, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) $hListView = GUICtrlGetHandle($idListView) $x = $ww / 2 - 50 $y = $wh - 60 $w = 100 $h = 25 GUICtrlCreateButton("Quit Popup", $x, $y, $w, $h) GUICtrlSetOnEvent(-1, "__MCP_handle_QUIT_btn") GUICtrlSetFont($idListView, 8.5, -1, -1, "courier new") _GUICtrlListView_AddColumn($idListView, "Name", 100) _GUICtrlListView_AddColumn($idListView, "Value", 100) _GUICtrlListView_AddColumn($idListView, "Sample", 100) _GUICtrlListView_SetColumnWidth($idListView, 0, 100) _GUICtrlListView_SetColumnWidth($idListView, 1, 80) logmsg("+++: $idListView = " & $idListView) logmsg("+++: $hListView = 0x" & Hex($hListView)) __MCP_populateListView($hListView) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState(@SW_SHOW, $__MCP_GUI_hWnd) EndFunc ;==>_myColorPicker Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam, $ilParam Local $hWndFrom, $iCode, $tNMHDR $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW Local $iDrawStage, $tCustDraw $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $ilParam) $iDrawStage = DllStructGetData($tCustDraw, 'dwDrawStage') Switch $iDrawStage Case BitOR(0, $CDDS_ITEMPREPAINT) ;, $CDDS_SUBITEM) setItemColor($tCustDraw, $hWndFrom) Return $CDRF_NOTIFYSUBITEMDRAW EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func setItemColor($tCustDraw, $hWnd) Local $iIndex, $color, $iSubitem $iIndex = DllStructGetData($tCustDraw, 'dwItemSpec') ; item number $color = _GUICtrlListView_GetItemParam($hWnd, $iIndex) $iSubitem = DllStructGetData($tCustDraw, 'iSubItem') ; Here, I want to only change the color of the 3rd col, and not the 1st and 2nd cols DllStructSetData($tCustDraw, 'iSubItem', 2) ; always use the 3rd column (the 'sample' col) logmsg("+++: setItemColor($tCustDraw, 0x" & Hex($hWnd) & ") entered ... " _ & ", $iIndex = " & $iIndex & ", $iSubItem = " & $iSubitem & ", $color = " & Hex($color)) DllStructSetData($tCustDraw, 'clrText', $color) ; set the Text color DllStructSetData($tCustDraw, 'clrTextBk', bitnot($color)) ; set the background color EndFunc ;==>setItemColor Func logmsg($msg, $lnum = @ScriptLineNumber) ConsoleWrite("+++:" & $lnum & ": " & $msg & @CRLF) EndFunc ;==>logmsg Func __MCP_exit() GUIDelete($__MCP_GUI_hWnd) EndFunc ;==>__MCP_exit Func __MCP_handle_SetColor_btn() If (IsHWnd($__MCP_obj)) Then GUISetBkColor($COLOR_BLUE, $__MCP_obj) Else GUICtrlSetBkColor($__MCP_obj, $COLOR_BLUE) EndIf EndFunc ;==>__MCP_handle_SetColor_btn Func __MCP_populateListView($hWnd) Local $text, $parts, $iIndex Local Static $aItems[] = [ _ "BLACK | " & $CLR_BLACK & "|" & "", _ "BLUE | " & $CLR_BLUE & "|" & "", _ "RED | " & $CLR_RED & "|" & "", _ "WHITE | " & $CLR_WHITE & "|" & "", _ "YELLOW | " & $CLR_YELLOW & "|" & "" _ ] _GUICtrlListView_BeginUpdate($hWnd) _GUICtrlListView_DeleteAllItems($hWnd) For $ndx = 0 To UBound($aItems) - 1 $text = $aItems[$ndx] $parts = StringSplit($text, "|", 2) $parts[0] = StringStripWS($parts[0], 3) $parts[2] = StringStripWS($parts[2], 3) $iIndex = _GUICtrlListView_AddItem($hWnd, $parts[0], -1, $parts[1]) _GUICtrlListView_AddSubItem($hWnd, $iIndex, Hex($parts[1]), 1) _GUICtrlListView_AddSubItem($hWnd, $iIndex, $parts[0], 2) Next _GUICtrlListView_EndUpdate($hWnd) EndFunc ;==>__MCP_populateListView Func __MCP_handle_QUIT_btn() GUIDelete($__MCP_GUI_hWnd) EndFunc ;==>__MCP_handle_QUIT_btn Func handle_1stTEST_btn() _myColorPicker($hMainWin) EndFunc ;==>handle_1stTEST_btn Func handle_2ndTEST_btn() _myColorPicker(@GUI_CtrlId) EndFunc ;==>handle_2ndTEST_btn Func _test_exit() Exit EndFunc ;==>_test_exit  
    • wakillon
      By wakillon
      Mp3SearchEngine v2.0.0.6

      May be some of you know Songr .
      This script do the same job, it can find more mp3 files but is not as fast as Songr.
       
       



      Sites used are music search engine Websites designed for LEGAL entertainment purposes only.
      Thanks to Brett Francis, Prog@ndy and Eukalyptus for >Bass Udf, trancex for >WinHttp Udf and the AutoIt Community for his help.

       
      Changes of v1.0.8.5
       
      Three websites replaced cause they are dead or use now js.
      All search engines updated ( not without difficulties for audiodump)
      I use RAGrid.dll for the first listview (more fast and stable, but with some inconvenients to manage the no-edit of cells)
      Input queries are saved ( the twenty latest)
      I use now an mp3 pre-Load management before playing and a double progressbar for visualize pre-load and play, where you can click for directly go play in the loaded part.
      Most includes needed are embedded and all external files are embedded in script with >BinaryToAu3Kompressor .
      Multi downloads available with embedded downloader.exe
       
      Changes of v1.0.8.8
      Search on audiodump and myfreemp3 fixed.
      New buttons.
      Added Gui Menu.
      Titles are no more editable.
      New "About" with >TaskDialog (Thanks Prog@andy)
      Query button permit now to check / uncheck all checkboxes
      And some few fixes and cleaning.
      Really more stable now.
      Changes of v1.0.9.2
      Dilandau is replaced by mp3chief and mp3ili by mp3clan 
      Search on mp3juices, baseofmp3 and soundcloud fixed.
      Soso now provide m4a (aac) instead of mp3 ( m4a can be played by MSE)
      Added possibility to encode automaticaly to mp3, aac or ogg ( at the end of download) using bassenc.dll and command line tools : lame, faac and oggenc.
       
      Changes of v1.0.9.3   mp3skull fixed mp3chief fixed myfreemp3 fixed mp3clan changed to tusmp3  mp3juices changed to emp3world baseofmp3 changed to imp3 and some minor improvements.  
      Version 2.0.0.6
      Most previous websites used are dead or have changed the way to get links, 
      so instead of try to repair the previous version, i have created a complete new version.
      The main tendency is the simplification :
      Only one website : audiodump (Up to 500 results by request)
      Script use now the little pearl created by Ward : curl.au3
      It permit to create tasks (get source and get multi mp3) in asynchronous mode.
      So now, no need to use several executables and no more gui who do not respond in case of connection problems. 
      Script use Bass.dll X86 loaded in memory for play songs.
      Result is light and fast, but don't abuse of audiodump servers who are not beasts of race.
      Warning : For avoid errors with curl.au3, you'll need to comment the line 63 : ;~ #Include <BinaryCall.au3>
      @AutoItX64 not supported and only tested on Win7X64 and Win8.1X64.
      As your browser, use Ctrl+w for remove the current Tab.(if there is no search or download running from it)
      And also Ctrl+q for set/remove Gridlines.
      Events are displayed to the bottom of the Gui.
       
      Version 2.0.1.1
      Added a Paste Button.
      Querry list is now correctly saved.
      Querry Combo is now sorted in alphabetical order
      After a 'No match', the next search will use the previous empty listview.
      Bug when removing tabs is corrected.
      Added string correction for the request that, in the previous version, was not always able to return a correct result.
       
      A big thanks to Ward for his great UDF, and Nina my favorite tester, (who between us is also my third daughter), for his precious advices .
      previous downloads : 1703
       
      As there is no more script downloads count, source and executable are available in the downloads section

      Enjoy ! 
      July 2017 Project Discontinued due to website changes
    • JustinZandee
      By JustinZandee
      I need a random string generator which creates 15 letters/numbers.
      How can I make that?
    • anthonyjr2
      By anthonyjr2
      Hi guys,
      I am pretty bad with regex, and am having some trouble trying to come up with an expression for a certain type of string. Basically I want to be able to tell if a string is of the format:
      AA#####A
      Where the A's are any letter from A-Z and the #'s are any digit from 0-9.
      I've been playing around with a regex tester online for a while but I can't really seem to grasp the concept very well. Could anyone give me any tips?
      This isn't exactly an AutoIt specific question which is why I didn't post it in General Help & Support.
    • LoneWolf_2106
      By LoneWolf_2106
      Hi everybody,
      i have a question related to strings items in an Array and sorting. Maybe someone can advice me how to solve the issue.
      I have an Array of strings, every item of the Array is as following:
      INFO [13.06.2017 11:48:01] [Thread-13] [ConGenImpUsb -> waitForConnection]  INFO [07.06.2017 08:55:44] [main] MDU5 - Ver 5.1x I want to sort the item in the array by date and time, is there any function which allows me to sort by date/time?
      Thanks in advance