Jump to content

Filter in listview header


Recommended Posts

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

 

Link to comment
Share on other sites

  • Moderators

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

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 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

 

Link to comment
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?

Link to comment
Share on other sites

  • Moderators

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

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 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

 

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...