Recent

Author Topic: Find partial string in ListBox  (Read 11652 times)

jeff

  • New Member
  • *
  • Posts: 18
Find partial string in ListBox
« on: August 26, 2014, 02:06:56 pm »
Hi,
I want to find a string in a ListBox using
Code: [Select]
var search: array[0..19] of char;
    id: string;
    i: integer;
begin
  id:='example';
  StrPCopy(search, id);
  i:=ListBox1.Perform(LB_FINDSTRING, 0, longint(@search));
end;
This code is working in Delphi, but not in FPC. It compiles, but the listbox1.perform always returns 0.
All Insight and thoughts gratefully accepted.

exdatis

  • Hero Member
  • *****
  • Posts: 668
    • exdatis
Re: Find partial string in ListBox
« Reply #1 on: August 26, 2014, 03:02:36 pm »
You can use function Pos(
  const substr: shortstring;
  const s: shortstring
):SizeInt;
or:
http://lazarus-ccr.sourceforge.net/docs/rtl/sysutils/stringfunctions.html

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Find partial string in ListBox
« Reply #2 on: August 26, 2014, 03:07:17 pm »
Pos will work on an individual string.  If I understand @jeff correctly, he's looking for the (first?) partial match in a series of strings loaded in a ListBox, using the winapi to do the search instead of manually trawling the strings himself.

@jeff  I'll ask the obvious question.  Are you using Windows?  I assume so as you reference Delphi.  Obviously LB_FINDSTRING will be dependent upon the underlying API, so if you're trying this on anything other than Win32/64 widgetset I doubt it'll work.  If you are under Windows, then I don't know I'm afraid.  I'd be writing the manual trawl code myself...

UPDATE:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775187(v=vs.85).aspx
I see the string it finds depends on a few options...

UPDATE 2:
Quote
wParam
The zero-based index of the item before the first item to be searched. When the search reaches the bottom of the list box, it continues searching from the top of the list box back to the item specified by the wParam parameter. If wParam is –1, the entire list box is searched from the beginning.
Bleh, that breaks my head.  Has to be an easier way to say that.
Can you try passing -1 instead of 0 as your second parameter to .Perform?
« Last Edit: August 26, 2014, 03:14:32 pm by Mike.Cornflake »
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

jeff

  • New Member
  • *
  • Posts: 18
Re: Find partial string in ListBox
« Reply #3 on: August 26, 2014, 03:37:44 pm »
Mike, thanks for your response. Yes, I'm using windows, forgot to mention that. Unfortunatelly with the second parameter is -1 still doesn't work, the result is always 0. I'm ran out of ideas, so I replaced the listbox.perform with the manual line by line method, it's slower, but at least it's working.

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Find partial string in ListBox
« Reply #4 on: August 26, 2014, 03:56:04 pm »
Code: [Select]
i := ListBox1.Items.IndexOf(search);

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Find partial string in ListBox
« Reply #5 on: August 26, 2014, 03:56:37 pm »
I know you've moved on, but I kept persisting :-)  After much testing, the following works...  (Had to add Windows to the uses list to get LParam, but as this is OS dependent code, no problems there)

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
Var
  search : String;
  i: Integer;
begin
  search := 'example';
  i:=Windows.SendMessage(ListBox1.Handle, LB_FINDSTRING, -1, LParam(PChar(search)));
end; 

Looks like .Perform behaves differently under Lazarus.  (I tried the LParam(Pchar()) stuff with Perform as well)

While I was searching through source code looking for hints, I came across a whole slew of code like the following, so be aware, the code above may break under future releases...

Code: [Select]
    {$ifdef WindowsUnicodeSupport}
    if UnicodeEnabledOS then
      FLastInsertedIndex := Windows.SendMessageW(FWin32List, FFlagAddString, 0, LPARAM(PWideChar(UTF8ToUTF16(S))))
    else
      FLastInsertedIndex := Windows.SendMessage(FWin32List, FFlagAddString, 0, LPARAM(PChar(Utf8ToAnsi(S))));
    {$else}
    FLastInsertedIndex := Windows.SendMessage(FWin32List, FFlagAddString, 0, LPARAM(PChar(S)));
    {$endif}
« Last Edit: August 26, 2014, 04:00:24 pm by Mike.Cornflake »
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Find partial string in ListBox
« Reply #6 on: August 26, 2014, 03:57:21 pm »
Code: [Select]
i := ListBox1.Items.IndexOf(search);
This finds whole strings only.  LB_FINDSTRING returns partial matches as well.
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Find partial string in ListBox
« Reply #7 on: August 26, 2014, 04:28:26 pm »
This is a Delphi problem, some OS features are not used.

To what extent compatibility needs should force Lazarus to do the same?
« Last Edit: August 26, 2014, 04:30:51 pm by typo »

jeff

  • New Member
  • *
  • Posts: 18
Re: Find partial string in ListBox
« Reply #8 on: August 26, 2014, 04:31:52 pm »
Many thanks  8)
I would never have figured out this on my own.

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Find partial string in ListBox
« Reply #9 on: August 26, 2014, 04:38:05 pm »
This is a Delphi problem, some OS features are not used.

To what extent compatibility needs should force Lazarus to do the same?
Sorry?  Where am I forcing Lazarus to do something?  No rules broken here.  Just because Lazarus can be used for cross-platform development, doesn't mean ALL app's developed with Lazarus have to be cross-platform.   You'll have the Android developers all in a tizz if that was the case :) 

Many thanks  8)
I would never have figured out this on my own.

No probs - I had fun :)
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Find partial string in ListBox
« Reply #10 on: August 26, 2014, 04:49:29 pm »
Sorry, my point is: Lazarus TListBox implementation should have a Find method like this.

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Find partial string in ListBox
« Reply #11 on: August 26, 2014, 09:47:01 pm »
Sorry, my point is: Lazarus TListBox implementation should have a Find method like this.
Good idea. I don't use ListBoxes myself, but can see the advantage of having this in comboboxes (which in win api are really just edits and listboxes)  Would be useful in implementing Autoselect as you type...
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

 

TinyPortal © 2005-2018