Old 28th January 2013, 11:51   #1
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
Iterate through ComboBox items

would anyone be so kind a provide an example how to iterate through the items of a combobox?

actually a working example using CB_GETITEMDATA for any position in the combobox would be enough, i can wrap a loop around that myself. it's only that i haven't found a clear example and (as always) msdn provides near to zero information, let alone examples.

thanks!
Yathosho is offline   Reply With Quote
Old 28th January 2013, 15:32   #2
demiller9
Senior Member
 
Join Date: Mar 2006
Location: Dallas
Posts: 462
I have an installer with a combobox but I didn't need to use CB_GETITEMDATA. The user's choice is read with ${NSD_GetText} and I set a default selection with ${NSD_CB_SelectString} when building the list or modify it later with
code:
SendMessage $hComboBox ${CB_SETCURSEL} $1 0
When I need to modify the selection the item number is determined by using ${WordFind} on the list of items I put in the combobox list. This works for us because our list is under a dozen items.
demiller9 is offline   Reply With Quote
Old 28th January 2013, 20:10   #3
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,484
GET/SETITEMDATA only stores a pointer sized number (32bit), if you wanted to store an extra string in addition to the displayed text you need to allocate memory/struct with the system plugin and just store the memory address as the item data. (Just storing the item data in a .ini is probably less work)

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 28th January 2013, 22:29   #4
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
Quote:
Originally Posted by demiller9 View Post
I have an installer with a combobox but I didn't need to use CB_GETITEMDATA. The user's choice is read with ${NSD_GetText} and I set a default selection with ${NSD_CB_SelectString} when building the list or modify it later with
code:
SendMessage $hComboBox ${CB_SETCURSEL} $1 0
When I need to modify the selection the item number is determined by using ${WordFind} on the list of items I put in the combobox list. This works for us because our list is under a dozen items.
i'm not looking for the user choice, i'd like to hide all entries in the combobox that don't partially fit what the user entered.

example:
the combobox is populated with all css properties. when the user types "background" into the box i want to hide all items that are not background properties (background-color, background-image etc.)
Yathosho is offline   Reply With Quote
Old 30th January 2013, 10:29   #5
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
ok, i got a bit further. turns out i can use CB_FINDSTRING to iterate through all items in the combobox. what i haven't figured out yet is how i can read a string from its index (i guess this is where CB_GETITEMDATA comes in)

i tried the following without success
code:
SendMessage $ComboBox ${CB_GETITEMDATA} $index $string
Yathosho is offline   Reply With Quote
Old 30th January 2013, 15:43   #6
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,484
Cb_getlbtext

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 30th January 2013, 19:56   #7
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
phew, i'm not getting this to work. as always, i find msdn's documentation more than scarce. here's what i've bee using

code:
${NSD_GetText} $ComboBox $R0
SendMessage $ComboBox ${CB_FINDSTRING} -1 "STR:$R0" $0
SendMessage $ComboBox ${CB_GETLBTEXT} $0 $1



must be the last line and i tried several variants (e.g. providing three arguments after CB_GETLBTEXT) - no success. i don't even understand what a TCHAR is, so i'd really appreciate a working example.
Yathosho is offline   Reply With Quote
Old 30th January 2013, 23:33   #8
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,484
To receive a string you have to use System::Call user32::SendMessage... (See GetText in nsdialogs.nsh)

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 2nd February 2013, 22:08   #9
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
i don't see how this is supposed to help
Yathosho is offline   Reply With Quote
Old 3rd February 2013, 04:34   #10
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,484
To receive the string you need the "t.r1" syntax of the system plugin, the built-in basic sendmessage cannot convert the raw memory buffer back to a nsis variable...

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 4th February 2013, 13:08   #11
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
unfortunately, i don't understand any of that. which is why i kindly asked for an example in the first place.
Yathosho is offline   Reply With Quote
Old 4th February 2013, 13:19   #12
jpderuiter
Major Dude
 
Join Date: Feb 2007
Posts: 672
http://forums.winamp.com/showthread.php?t=314626
jpderuiter is offline   Reply With Quote
Old 5th February 2013, 12:15   #13
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
looking good so far, thanks a lot!
Yathosho is offline   Reply With Quote
Old 19th February 2013, 12:53   #14
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
i've attached a first working version showcasing what i'm trying to accomplish. unfortunately, this is currently a one-way, older combobox items do not get restored. not sure what would be the best practice to do so, should i listen whether the delete key was pressed (and how does that work?) or simply compare whether the input length got shorter compared to a previous input?

edit: to see what this example does, start typing any command from the combobox, e.g. "border"
Attached Files
File Type: nsi _cssfilter.nsi (3.3 KB, 302 views)
Yathosho is offline   Reply With Quote
Old 19th February 2013, 18:50   #15
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
big problem: typing works, but selecting an item with the mouse breaks the whole thing. it seems that when clicking, nsd_gettext will always get the previous item, how could this be?
Yathosho is offline   Reply With Quote
Old 20th February 2013, 05:09   #16
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,484
nsDialogs hooks CBN_EDITUPDATE and CBN_SELCHANGE, that callback might be too soon, use something other than nsd_gettext (CB_*) or try a timer hack...

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 20th February 2013, 07:38   #17
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
Quote:
Originally Posted by Anders View Post
nsDialogs hooks CBN_EDITUPDATE and CBN_SELCHANGE, that callback might be too soon, use something other than nsd_gettext (CB_*) or try a timer hack...
hm, i was taking a look at nsDialogs.nsh hoping to find any of the keywords you delivered. changed quite a lot, i remember tinkering around in that file years ago, but it looks nothing like that anymore. got some further leads?
Yathosho is offline   Reply With Quote
Old 22nd February 2013, 23:02   #18
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
i'm wondering how that can be a desired behaviour, onChange should really listen to both cases, especially since combining onChange and onClick doesn't work as one would expect. if there's need for seperating both (and i can't think of a scenario), it'd probably good to have a third macro. any thoughts on this?
Yathosho is offline   Reply With Quote
Old 3rd March 2013, 06:14   #19
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
You probably want to iterate all of the available options and not all of the items in the combobox when filtering. This way, if someone hits the backspace, you still get all the other options.

To get text from a combobox item, one System::Call is enough. No need to allocate stuff and use the built-in SendMessage.

code:
# new
System::Call "user32::SendMessage(i $ComboBox, i ${CB_GETLBTEXT}, i r9, t.r2)"

# old
#System::Alloc ${NSIS_MAX_STRLEN}
#Pop $1
#SendMessage $ComboBox ${CB_GETLBTEXT} $9 $1
#System::Call "*$1(&t32.r2)"
#System::Free $1



As for the last issue of choosing something with the mouse, I'm not sure why this happens, but Anders is probably right. In any case, you can work around it by calling CB_GETCURSEL first and checking if it returns -1 or not. If it returns a value, the user selected that item. If not, the user typed something.

code:
SendMessage $ComboBox ${CB_GETCURSEL} 0 0 $9
${If} $9 != -1
# user selected something
System::Call "user32::SendMessage(i $ComboBox, i ${CB_GETLBTEXT}, i r9, t .R0)"
${Else}
${NSD_GetText} $ComboBox $R0
${EndIf}



Attached is my almost working version. I'm sure you can take it from here.
Attached Files
File Type: nsi _cssfilter.nsi (3.6 KB, 317 views)

NSIS FAQ | NSIS Home Page | Donate $
"I hear and I forget. I see and I remember. I do and I understand." -- Confucius
kichik is offline   Reply With Quote
Old 5th March 2013, 21:40   #20
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
thanks for the help, love how this works. can this be blocked for certain keystrokes (e.g. cursor keys)?
Yathosho is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Tags
cb_getitemdata, combobox, iterate, nsdialogs

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump