Jump to content

Recommended Posts

Posted (edited)

Awesome.

Can you also make example how to automatically Hide/Show ListView Items with relation to this search string ?

EDIT:
oops i see

 2) Show matching rows only.au3

+5

:)

 

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted

Third example 3) Standard Find text dialog.au3  showing errors:

  Quote

>Running AU3Check (3.3.14.2)  from:C:\Program Files (x86)\AutoIt3  input:C:\Users\user\Downloads\ListviewIncrSearch\3) Standard Find text dialog.au3
"C:\Users\user\Downloads\ListviewIncrSearch\WinAPIDlgEx.au3"(10,43) : warning: $__pFRBuffer: possibly used before declaration.
    $__pFRBuffer = __HeapReAlloc($__pFRBuffer,
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\user\Downloads\ListviewIncrSearch\WinAPIDlgEx.au3"(10,65) : warning: $__iFRBufferSize: possibly used before declaration.
    $__pFRBuffer = __HeapReAlloc($__pFRBuffer, 2 * $__iFRBufferSize)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\user\Downloads\ListviewIncrSearch\WinAPIDlgEx.au3"(10,65) : error: $__iFRBufferSize: undeclared global variable.
    $__pFRBuffer = __HeapReAlloc($__pFRBuffer, 2 * $__iFRBufferSize)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\Users\user\Downloads\ListviewIncrSearch\3) Standard Find text dialog.au3 - 1 error(s), 2 warning(s)

 

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted

Oops, sorry, I'm still on 3.3.10. It must be the cause of the errors. I will take the opportunity to upgrade. And fix the errors. But I do not have time until tomorrow.

Posted

No hurry up.
Thanks for the effort.

mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted

Well written code :)

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

  • 3 weeks later...
  • 1 month later...
Posted

You are welcome.

Thank you for feedback. Always nice.

I would have preferred to implement it in a custom drawn listview. But there was a lot of flicker. I've made a note about that. I'll look into it. And it would have been easier with some kind of UDF. I'm working on that.

  • 3 years later...
Posted

Hello.
Sorry to bring up the old topic.
I liked the example "
2) Show matching rows only.au3 ".
Added in "#include <WinAPI.au3>" for function "_WinAPI_SetWindowsHookEx".
Everything seemed to work, but when I try to write in a search with
something in big letters (where caps look is on ) with unchecked "Use regular expression..." ,

the program crashes with an error.
Can somebody help me?
Thank.

Posted

Replace

If StringInStr( $aItems[$i], $sSearch ) Then ; Normal search

with

If StringInStr( $aItems[$i], $sSearch, $STR_CASESENSE ) Then ; Normal search

It should be done in all three examples.

 

The Hook functions were moved to WinAPISys.au3 last year.

Posted (edited)

Thanks for the answer.
I need to use non-sensitive mode. I added

$STR_NOCASESENSEBASIC


Also I change some array fill letters to upper case.

The script crashes when I type the missing small letter. 😦

Edited by Lion66
edit
Posted (edited)

LarsJ,

I'm not even sure the error occurs in the search or in the marking operation in yellow...

Edited by Lion66
  • 2 months later...
Posted (edited)

Hello all!

First of all thanks LarsJ for awesome examples! It's really cool!

On the russian forum, I found a slightly modified (by Lion66) one of your examples. But, unfortunately, it seems it's a dead topic.
In the modified code several columns were added, but the search still on the first '0' column.
I tried to do a more advanced search with column select to search. In attached zip file you can find the code with and without marking!

Only without marking works 😜

And now my problem:
I tried to do the same with search and marking example code and it does't work. Crashes with an error and I have no idea how to fix it.

Anybody can help me with this? 😕

ListView Incremental Search Modified .zipFetching info...

Edited by RAMzor
Posted

Under what circumstances does the code fail? Windows version, 32/64 bit code, etc. What is the error when the code crashes?

I briefly tested "Search Example 2 - With Column Select And Marking.au3" under Windows 7 both 32 and 64 bit. It works fine with yellow background marking of the search text and without crashing.

Posted (edited)

Here is an example of search in several columns:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#AutoIt3Wrapper_UseX64=y

Opt( "MustDeclareVars", 1 )

#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <Array.au3>
#include "DrawItem.au3"
#include "GuiListViewEx.au3"

Global Const $tagMSG = "hwnd hwnd;uint message;wparam wParam;lparam lParam;dword time;int X;int Y"

Global $hGui, $idListView, $hListView, $fListViewHasFocus = 0, $iItems = 1000, $iCols = 4, $iCol = 0, $aItems[$iItems][$iCols]
Global $idSearch, $hSearch, $idSearchAction, $aSearch[$iItems], $iSearch = 0, $sSearch = ""

Example()


Func Example()
  ; Create GUI
  $hGui = GUICreate( "Show matching rows only - multiple columns", 1060, 330 )

  ; Create search group
  GUICtrlCreateGroup( "Search", 10, 5, 1060-20, 120 )

  ; Create Checkbox
  Local $idRegExp = GUICtrlCreateCheckbox( "Use regular expression as search string", 20, 25, 260, 20 )
  GUICtrlSetState( $idRegExp, $GUI_CHECKED )

  ; Create Edit control
  $idSearch = GUICtrlCreateEdit( "", 20, 55, 200, 20, $GUI_SS_DEFAULT_EDIT-$ES_AUTOVSCROLL-$WS_HSCROLL-$WS_VSCROLL )
  GUICtrlSetData( $idSearch, "Enter search string - possibly as reg. exp." )
  $hSearch = GUICtrlGetHandle( $idSearch )
  $idSearchAction = GUICtrlCreateDummy()

  ; Create read only Edit control for number of matches
  Local $idCount = GUICtrlCreateEdit( "0", 230, 55, 50, 20, $GUI_SS_DEFAULT_EDIT+$ES_READONLY+$ES_RIGHT-$WS_HSCROLL-$WS_VSCROLL )
  GUICtrlSetBkColor( $idCount, 0xFFFFFF )

  ; Create Buttons
  Local $idNext = GUICtrlCreateButton( "Next match",  20, 85, 125, 25 )
  Local $idPrev = GUICtrlCreateButton( "Prev match", 155, 85, 125, 25 )
  GUICtrlSetState( $idNext, $GUI_DISABLE )
  GUICtrlSetState( $idPrev, $GUI_DISABLE )

  ; Search column
  Local $idComboBox = GUICtrlCreateCombo( "Search column 0", 350, 25, 200, 20 )
  GUICtrlSetData( $idComboBox, "Search column 1|Search column 2|Search column 3" )

  ; Close group
  GUICtrlCreateGroup( "", -99, -99, 1, 1 )

  ; Create ListView
  $idListView = GUICtrlCreateListView( "", 10, 140, 1060-20, 180, $GUI_SS_DEFAULT_LISTVIEW+$LVS_OWNERDATA+$LVS_OWNERDRAWFIXED, $WS_EX_CLIENTEDGE+$LVS_EX_DOUBLEBUFFER )
  $hListView = GUICtrlGetHandle( $idListView )                                          ; Virtual        Owner drawn                            Reduces flicker
  _GUICtrlListView_AddColumn( $hListView, "Column 0",  250 )
  _GUICtrlListView_AddColumn( $hListView, "Column 1",  250 )
  _GUICtrlListView_AddColumn( $hListView, "Column 2",  250 )
  _GUICtrlListView_AddColumn( $hListView, "Column 3",  250 )

  ; Fill array
  FillArray( $aItems )
  _ArraySort( $aItems, 0, 0, 0, $iCol ) ; $iCol is the search column

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

  ; Initialize ListView
  GUICtrlSendMsg( $idListView, $LVM_SETITEMCOUNT, $iSearch, 0 )

  ; Adjust height of GUI and ListView to fit 15 rows
  Local $iLvHeight = _GUICtrlListView_GetHeightToFitRows( $hListView, 15 )
  WinMove( $hGui, "", Default, Default, Default, WinGetPos( $hGui )[3] - WinGetClientSize( $hGui )[1] + $iLvHeight + 150 )
  WinMove( $hListView, "", Default, Default, Default, $iLvHeight )

  ; Register WM_ACTIVATE message handler
  ; To check when GUI receives/loses focus
  GUIRegisterMsg( $WM_ACTIVATE, "WM_ACTIVATE" )

  ; Register WM_COMMAND message handler
  ; To read search string from Edit control while it's typed in
  GUIRegisterMsg( $WM_COMMAND, "WM_COMMAND" )

  ; Register WM_DRAWITEM message handler
  ; To display items in an owner drawn ListView
  GUIRegisterMsg( $WM_DRAWITEM, "WM_DRAWITEM" )

  ; Register message handler to test ListView focus
  Local $hMessageHandler = DllCallbackRegister( "MessageHandler", "long", "int;wparam;lparam" )
  Local $hMessageHook = _WinAPI_SetWindowsHookEx( $WH_MSGFILTER, DllCallbackGetPtr( $hMessageHandler ), 0, _WinAPI_GetCurrentThreadId() )

  ; Show GUI
  GUISetState( @SW_SHOW )

  ; Message loop
  While 1
    Switch GUIGetMsg()
      Case $idSearchAction, $idRegExp
        $sSearch = GUICtrlRead( $idSearch )
        If $sSearch = "" Then
          ; Empty search string, display all items
          For $i = 0 To $iItems - 1
            $aSearch[$i] = $i
          Next
          $iSearch = $iItems
          GUICtrlSetData( $idCount, 0 )
        Else
          ; Find rows matching search string
          $iSearch = 0
          If GUICtrlRead( $idRegExp ) = $GUI_CHECKED Then
            For $i = 0 To $iItems - 1
              If StringRegExp( $aItems[$i][$iCol], $sSearch ) Then ; Reg. exp. search
                $aSearch[$iSearch] = $i
                $iSearch += 1
              EndIf
            Next
          Else
            For $i = 0 To $iItems - 1
              If StringInStr( $aItems[$i][$iCol], $sSearch ) Then ; Normal search
                $aSearch[$iSearch] = $i
                $iSearch += 1
              EndIf
            Next
          EndIf
          GUICtrlSetData( $idCount, $iSearch )
        EndIf
        GUICtrlSendMsg( $idListView, $LVM_SETITEMCOUNT, $iSearch, 0 )

      Case $idComboBox
        ; New search column
        $iCol = Int( StringRight( GUICtrlRead( $idComboBox ), 1 ) )
        _ArraySort( $aItems, 0, 0, 0, $iCol )
        GUICtrlSetData( $idSearch, "" )
        GUICtrlSendToDummy( $idSearchAction )

      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  ; Cleanup
  _WinAPI_UnhookWindowsHookEx( $hMessageHook )
  GUIDelete()
EndFunc

; Check when GUI receives/loses focus
Func WM_ACTIVATE( $hWnd, $iMsg, $wParam, $lParam )
  #forceref $iMsg, $lParam
  If $hWnd = $hGui Then _
    $fListViewHasFocus += BitAND( $wParam, 0xFFFF ) ? 1 : -1
  Return $GUI_RUNDEFMSG
EndFunc

; Read search string from Edit control while it's typed in
Func WM_COMMAND( $hWnd, $iMsg, $wParam, $lParam )
  #forceref $hWnd, $iMsg
  Local Static $bEditClear = True
  Local $hWndFrom = $lParam
  Local $iCode = BitShift( $wParam, 16 ) ; High word
  Switch $hWndFrom
    Case $hSearch
      Switch $iCode
        Case $EN_CHANGE
          GUICtrlSendToDummy( $idSearchAction )
        Case $EN_SETFOCUS
          If $bEditClear Then
            GUICtrlSetData( $idSearch, "" )
            $bEditClear = False
          EndIf
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc

; Display items in an owner drawn ListView
Func WM_DRAWITEM( $hWnd, $iMsg, $wParam, $lParam )
  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 Static $hBrushHighLight = _WinAPI_GetSysColorBrush( $COLOR_HIGHLIGHT ), $hBrushButtonFace = _WinAPI_GetSysColorBrush( $COLOR_BTNFACE )

  ; We can optimize code by removing Switch statements because the ListView is the only ownerdrawn control and only $ODA_DRAWENTIRE actions are present

  Local $tDrawItem = DllStructCreate( $tagDRAWITEM, $lParam ), $itemID = DllStructGetData( $tDrawItem, "itemID" ), $iState = DllStructGetData( $tDrawItem, "itemState" ), $hDC = DllStructGetData( $tDrawItem, "hDC" ), $sItemText

  ; Loop through columns
  ; $i is the column index
  For $i = 0 To $iCols - 1
    ; Subitem rectangle
    DllStructSetData( $tRect, 2, $i ) ; Top
    DllStructSetData( $tRect, 1, $LVIR_BOUNDS ) ; Left
    GUICtrlSendMsg( $idListView, $LVM_GETSUBITEMRECT, $itemID, $pRect )
    DllStructSetData( $tRect, 1, DllStructGetData( $tRect, 1 ) + 6 ) ; Left margin
    DllStructSetData( $tRect, 2, DllStructGetData( $tRect, 2 ) + 2 ) ; Top  margin

    ; Subitem background and text color
    If BitAND( $iState, $ODS_SELECTED ) Then _
      DllCall( "user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $tRect, "handle", $fListViewHasFocus = 1 ? $hBrushHighLight : $hBrushButtonFace ) ; _WinAPI_FillRect
    DllCall( "gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int", BitAND( $iState, $ODS_SELECTED ) ? $fListViewHasFocus = 1 ? 0xFFFFFF : 0x000000 : 0x000000 ) ; _WinAPI_SetTextColor

    ; Draw subitem text
    $sItemText = $aItems[$aSearch[$itemID]][$i]
    DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $sItemText, "int", StringLen( $sItemText ), "struct*", $tRect, "uint", 0 ) ; _WinAPI_DrawText

    ; $i is column index
    ; $iCol is the search column
    ; Mark matching substring only if column index = search column
    If $i <> $iCol Then ContinueLoop

    ; Matching substring?
    If $sSearch Then
      Local $sMatch = StringRegExp( $sItemText, $sSearch, 1 ), $extended = @extended, $iLen = StringLen( $sMatch[0] )

      ; Rectangle for matching substring
      DllCall( "gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $sItemText, "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 rectangle with yellow or cyan (selected) background color
      DllCall( "user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $tRect, "handle", BitAND( $iState, $ODS_SELECTED ) ? $hBrushCyan : $hBrushYellow ) ; _WinAPI_FillRect

      ; Draw matching substring in rectangle
      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
    EndIf
  Next

  Return $GUI_RUNDEFMSG
  #forceref $hWnd, $iMsg, $wParam
EndFunc

; Message handler to test ListView focus
Func MessageHandler( $nCode, $wParam, $lParam )
  #forceref $nCode, $wParam
  Local $tMsg = DllStructCreate( $tagMSG, $lParam ), $iMsg = DllStructGetData( $tMsg, "message" )
  If $iMsg = $WM_LBUTTONDOWN Or $iMsg = $WM_RBUTTONDOWN Then $fListViewHasFocus = DllStructGetData( $tMsg, "hwnd" ) = $hListView ? 1 : 0
EndFunc

; Fill array with random strings
Func FillArray( ByRef $aItems )
  Local $aLetters[26] = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', _
                          'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ], $s
  For $i = 0 To $iCols - 1
    For $j = 0 To $iItems - 1
      $s = $aLetters[Random(0,25,1)]
      For $k = 1 To Random(10,30,1)
        $s &= $aLetters[Random(0,25,1)]
      Next
      $aItems[$j][$i] = $s
    Next
  Next
EndFunc

OhNwOh0.png

2.2) Show matching rows only - multiple columns.au3Fetching info...

The include files in the zip in first post are needed.

Edited by LarsJ
Include files
Posted

Wow! 🤪

Thanks a lot! It was very helpful!

I make it case-insensitive by adding "(?i)". I'm not sure  if it best solution but it works

StringRegExp( $aItems[$i][$iCol], "(?i)" & $sSearch )

 

I'm confused and can't understand how to update the ListView after manipulation on data in array $aItems?

For example after add, delete or sorting rows. Only GUICtrlSendToDummy( $idSearchAction ) not make a sense

 

Posted

If you add or delete rows in the array, you must inform the listview of the new number of rows: GUICtrlSendMsg( $idListView, $LVM_SETITEMCOUNT, $iRows, 0 ). This command also redraws all visible listview items.

To redraw all visible listview items: GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iRows - 1 )

To redraw a single listview item: GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, $iRow, $iRow )

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
  • Recently Browsing   0 members

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