Delphi - Pure TListBox Objects

I want to clear the list by checking it against two other lists.

  • Listbox1 will have a large list of items
  • Listbox2 will have words that I want to remove from listbox1
  • Listbox3 will have required words that must exist for it to stay in listbox1

Below is the code I have for this, it is very slow with large lists.

// not very efficient 
Function checknegative ( instring : String; ListBox : TListBox ) : Boolean;
Var
  i : Integer;
Begin
  For I := listbox.Items.Count - 1 Downto 0 Do
  Begin
    If ExistWordInString ( instring, listbox.Items.Strings [i], 
      [soWholeWord, soDown] ) = True 
    Then
    Begin
      result := True;  //True if in list, False if not.
      break; 
    End
    Else
    Begin
      result := False;
    End;
  End;
  result:=false;
End;

Function ExistWordInString ( aString, aSearchString : String;
  aSearchOptions : TStringSearchOptions ) : Boolean;
Var
  Size : Integer;
Begin
  Size := Length ( aString );
  If SearchBuf ( Pchar ( aString ), Size, 0, 0, aSearchString, aSearchOptions ) <> Nil Then
  Begin
    result := True;
  End
  Else
  Begin
    result := False;
  End;
End;

      

+2


a source to share


2 answers


If you're doing anything that loops with an instance TStrings

in a control, it can be helpful to create a temporary instance TStringList

, assign controls to it, and then use the temporary list.



The reason for this is that the property Items

list, list box or the like is implemented through a proxy class, which does not contain the lines themselves, but which uses Windows messages such as LB_GETCOUNT

and LB_GETTEXT

to retrieve items directly from their own Windows control. If you scan the string list item multiple times, then the overhead of handling duplicate messages will be added.

+4


a source


If it works on a list, it probably takes a long time to redraw everything every time. You can disable this behavior. Surround the outer path with the following:

listbox.Items.BeginUpdate;
try
  //do the loop here
finally
  listbox.Items.EndUpdate;
end;

      

Alternatively, you can assign a boolean value directly to evaluate the boolean expression, which will save some time on your inner loop. So:



Function ExistWordInString ( aString, aSearchString : String; aSearchOptions : TStringSearchOptions ) : Boolean;
Var
  Size : Integer;
Begin
  Size := Length ( aString );
  result := SearchBuf ( Pchar ( aString ), Size, 0, 0, aSearchString, aSearchOptions ) <> Nil;
End;

      

I don’t know what difference it will do. If you do make these changes and are still too slow, try running your program through a profiler like Sampling Profiler to help you figure out the code is wasting most of its time.

+3


a source







All Articles