HurleyShanabarger

Filter in listview header

4 posts in this topic

Hello,

I come kind if empty handed/coded.

I am wondering if there is any example/recent UDF/good approach to:

  1. search in a listview in a fast way, deleting everything and reading data from an SQL would be an option
  2. filter in a listview

I have been seeing that it is possible to add filter headers to a listview, but I don't see any natural way to receive the data and apply the filter.

Any feedback/approach is highly appreciated!

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

Global $g_header, $g_iFilterColumn = -1, $g_boEdit = False
_GUI_LV_example()

Func _GUI_LV_example()
    Local $hGUI, $hListView
    $hGUI = GUICreate("Listview test", 400, 330)
    $hListView = _GUICtrlListView_Create($hGUI, "", 2, 30, 394, 268)
    _GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))


    ;Add the filter bar to the header control
    GUISetState(@SW_LOCK, $hGUI)
    _GUICtrlListView_BeginUpdate($hListView)
    $g_header = _GUICtrlListView_GetHeader($hListView)
    $styles = _WinAPI_GetWindowLong($g_header, $GWL_STYLE)
    _WinAPI_SetWindowLong($g_header, $GWL_STYLE, BitOR($styles, $HDS_FILTERBAR))
    _GUICtrlListView_EndUpdate($hListView)
    GUISetState(@SW_UNLOCK, $hGUI)

    ; Add columns
    _GUICtrlListView_InsertColumn($hListView, 0, "Column 1", 100)
    _GUICtrlListView_InsertColumn($hListView, 1, "Column 2", 100)
    _GUICtrlListView_InsertColumn($hListView, 2, "Column 3", 100)

    ; Add items
    _GUICtrlListView_AddItem($hListView, "Row 1: Col 1", 0)
    _GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 2", 1)
    _GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 3", 2)
    _GUICtrlListView_AddItem($hListView, "Row 2: Col 1", 1)
    _GUICtrlListView_AddSubItem($hListView, 1, "Row 2: Col 2", 1)
    _GUICtrlListView_AddItem($hListView, "Row 3: Col 1", 2)

    ; Add button
    GUICtrlCreateButton("Get filter text", 5, 5, 394, 20)
    GUISetState(@SW_SHOW)

    ;Register WM_NOTIFY to handle $HDN_FILTERBTNCLICK messages
    GUIRegisterMsg($WM_NOTIFY, "_GUI_msg_Notify")

    ; Main loop
    While 1
        $iMsg = GUIGetMsg()
        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case Else
                If $g_boEdit = False And $g_iFilterColumn > -1 Then
                    $g_boEdit = True
                    _GUICtrlHeader_EditFilter($g_header, $g_iFilterColumn)
                    $g_sFilterText = ControlGetText($hGUI, "", "Edit1")
                    Send("{Enter}")
                    $g_iFilterColumn = -1
                    $g_boEdit = False
                    ConsoleWrite($g_sFilterText & @CRLF)
                EndIf
        EndSwitch
    WEnd
    GUIDelete()
EndFunc   ;==>_GUI_LV_example

Func _GUI_msg_Notify($hWnd, $iMsg, $iwParam, $ilParam)
    If $g_boEdit Then Return $GUI_RUNDEFMSG
    Local $hWndFrom, $iIDFrom, $iCode
    Local $tNMHDR, $tNMHEADER, $tNMHDFILTERBTNCLICK, $tNMHDDISPINFO
    Local $iHeaderItem, $tItem
    Local $HDFT_ISSTRING = 0x0
    Local $HDFT_ISNUMBER = 0x1

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    If $hWndFrom <> $g_header Then Return $GUI_RUNDEFMSG
    If $iCode <> $HDN_FILTERBTNCLICK Then Return $GUI_RUNDEFMSG

    $tNMHDFILTERBTNCLICK = DllStructCreate($tagNMHDFILTERBTNCLICK, $ilParam)
    $g_iFilterColumn = DllStructGetData($tNMHDFILTERBTNCLICK, "Item")

    Return False
EndFunc   ;==>_GUI_msg_Notify

 

Share this post


Link to post
Share on other sites



HurleyShanabarger,

I would do it like this:

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

#include <Array.au3>

Global $g_header, $g_FilterDummy

_GUI_LV_example()

Func _GUI_LV_example()
    Local $hGUI, $hListView
    $hGUI = GUICreate("Listview test", 400, 330)
    $hListView = _GUICtrlListView_Create($hGUI, "", 2, 30, 394, 268)
    _GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))


    ;Add the filter bar to the header control
    GUISetState(@SW_LOCK, $hGUI)
    _GUICtrlListView_BeginUpdate($hListView)
    $g_header = _GUICtrlListView_GetHeader($hListView)
    $styles = _WinAPI_GetWindowLong($g_header, $GWL_STYLE)
    _WinAPI_SetWindowLong($g_header, $GWL_STYLE, BitOR($styles, $HDS_FILTERBAR))
    _GUICtrlListView_EndUpdate($hListView)
    GUISetState(@SW_UNLOCK, $hGUI)

    ; Add columns
    _GUICtrlListView_InsertColumn($hListView, 0, "Column 1", 100)
    _GUICtrlListView_InsertColumn($hListView, 1, "Column 2", 100)
    _GUICtrlListView_InsertColumn($hListView, 2, "Column 3", 100)

    ; Add items
    _GUICtrlListView_AddItem($hListView, "Row 1: Col 1", 0)
    _GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 2", 1)
    _GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 3", 2)
    _GUICtrlListView_AddItem($hListView, "Row 2: Col 1", 1)
    _GUICtrlListView_AddSubItem($hListView, 1, "Row 2: Col 2", 1)
    _GUICtrlListView_AddItem($hListView, "Row 3: Col 1", 2)

    ; Create dummy to fire when filter button pressed
    $g_FilterDummy = GUICtrlCreateDummy()

    GUISetState(@SW_SHOW)

    ;Register WM_NOTIFY to handle $HDN_FILTERBTNCLICK messages
    GUIRegisterMsg($WM_NOTIFY, "_GUI_msg_Notify")

    ; Main loop
    While 1
        $iMsg = GUIGetMsg()
        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $g_FilterDummy
                ; Get column and filter text sent from handler
                $aSplit = StringSplit(GUICtrlRead($g_FilterDummy), "|")
                If $aSplit[0] = 2 Then
                    ; If no errors
                    $iCol = $aSplit[1]
                    $sFilter = $aSplit[2]

                    ; Read current ListView contents into an array
                    $iColCount = _GUICtrlListView_GetColumnCount($hListView)
                    $iRowCount = _GUICtrlListView_GetItemCount($hListView)
                    Local $aLVContent[$iRowCount][$iColCount]
                    For $i = 0 To $iColCount - 1
                        $aItemContent = _GUICtrlListView_GetItemTextArray($hListView, $i)
                        For $j = 1 To $iColCount
                            $aLVContent[$i][$j - 1] = $aItemContent[$j]
                        Next
                    Next

                    ; Delete current ListView contents
                    _GUICtrlListView_DeleteAllItems($hListView)

                    ; Filter array
                    $sDeleteString = ""
                    For $i = 0 To $iRowCount - 1
                        If Not StringInStr($aLVContent[$i][$iCol], $sFilter) Then
                            $sDeleteString &= $i & ";"
                        EndIf
                    Next

                    _ArrayDelete($aLVContent, StringTrimRight($sDeleteString, 1))

                    ; Rewrite ListView
                    _GUICtrlListView_AddArray($hListView, $aLVContent)

                    ; Clear up
                    $aLVContent = ""

                EndIf

        EndSwitch
    WEnd
    GUIDelete()
EndFunc   ;==>_GUI_LV_example

Func _GUI_msg_Notify($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode
    Local $tNMHDR, $tNMHEADER, $tNMHDFILTERBTNCLICK, $tHDTEXTFILTER, $tNMHDDISPINFO
    Local $iHeaderItem, $tItem
    Local $HDFT_ISSTRING = 0x0
    Local $HDFT_ISNUMBER = 0x1

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $g_header
            Switch $iCode
                Case $HDN_FILTERBTNCLICK

                    $tNMHDFILTERBTNCLICK = DllStructCreate($tagNMHDFILTERBTNCLICK, $ilParam)
                    $column = DllStructGetData($tNMHDFILTERBTNCLICK, "Item")

                    $tText = DllStructCreate("wchar[64]")
                    $pText = DllStructGetPtr($tText)
                    $tHDTEXTFILTER = DllStructCreate($tagHDTEXTFILTER)
                    $pHDTEXTFILTER = DllStructGetPtr($tHDTEXTFILTER)
                    DllStructSetData($tHDTEXTFILTER, "Text", $pText)
                    DllStructSetData($tHDTEXTFILTER, "TextMax", 64)

                    $tHDITEM = DllStructCreate($tagHDITEM)
                    DllStructSetData($tHDITEM, "Mask", $HDI_FILTER)
                    DllStructSetData($tHDITEM, "Type", 0)
                    DllStructSetData($tHDITEM, "pFilter", $pHDTEXTFILTER)
                    $pHDITEM = DllStructGetPtr($tHDITEM)

                    _SendMessage($g_header, $HDM_GETITEMW, $column, $pHDITEM)

                    $sText = DllStructGetData($tText, 1)

                    ; Send column and filter text to dummy
                    GUICtrlSendToDummy($g_FilterDummy, $column & "|" & $sText)

                    Return True
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>_GUI_msg_Notify

Credit to LarsJ for the majority of the handler code.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

That is pretty amazing, I will look into the details later.

Different question - same script. If i perform an SQL query using "_SQLite_GetTable2d" on a table with about 5000 entries it takes about 900ms until I have the data in an array. However I use _SQLite_SQLiteExe and perform the query via cmd, dump the output and read it with _FileReadToArray it takes until 300ms.

Is this kind of normal?

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

HurleyShanabarger,

No idea - I suggest you open a new thread to discuss it.

M23

Edit: And please do ask if after having looked at it in more detail you have any questions on the script I posted.

Edited by Melba23

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

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