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;
a source to share
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.
a source to share
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.
a source to share