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!
Iterate through ComboBox items
20 posts
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
SendMessage $hComboBox ${CB_SETCURSEL} $1 0When 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.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)
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.Originally Posted by demiller9 View PostI 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 withWhen 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.SendMessage $hComboBox ${CB_SETCURSEL} $1 0
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.)
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
i tried the following without success
SendMessage $ComboBox ${CB_GETITEMDATA} $index $stringCb_getlbtext
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
${NSD_GetText} $ComboBox $R0
SendMessage $ComboBox ${CB_FINDSTRING} -1 "STR:$R0" $0
SendMessage $ComboBox ${CB_GETLBTEXT} $0 $1must 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.To receive a string you have to use System::Call user32::SendMessage... (See GetText in nsdialogs.nsh)
i don't see how this is supposed to help
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...
unfortunately, i don't understand any of that. which is why i kindly asked for an example in the first place.
looking good so far, thanks a lot!
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"
edit: to see what this example does, start typing any command from the combobox, e.g. "border"
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?
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?Originally Posted by Anders View PostnsDialogs hooks CBN_EDITUPDATE and CBN_SELCHANGE, that callback might be too soon, use something other than nsd_gettext (CB_*) or try a timer hack...
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?
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.
To get text from a combobox item, one System::Call is enough. No need to allocate stuff and use the built-in SendMessage.
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.# 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
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.thanks for the help, love how this works. can this be blocked for certain keystrokes (e.g. cursor keys)?