Выпадающий список (Combobox) с динамическим поиском
Продолжаем усовершенствовать элемент Combobox. Создавать его мы научились, красивыми иконками снабдили, теперь давайте добавим полнотекстовый поиск по списку и фильтрацию. Справедливости ради стоит отметить, что зачаточный вариант поиска в комбобоксе все-таки присутствует. Если ввести какую-нибудь строку, а затем открыть выпадающий список, то курсор будет установлен на первом найденном пункте списка, который начинается с введенной строки. Я же хочу сделать так, чтобы в списке оставались только те пункты, в которых присутствует введенная строка, причем не только в начале, а вообще. Например, если я введу "Jo", то в списке должны остаться как "John Smith", так и "Patrick Joel".Изменения поля ввода будем отлавливать штатными средствами в обработчике комбобокса. Это должно быть уведомление CBN_EDITUPDATE. После этого сохраняем введенную строку в сухом прохладном месте, очищаем список, а затем заполняем его, но уже только теми пунктами, где присутствует введенная строка.
Code (Assembler) : Убрать нумерацию
- cmp [msg],WM_COMMAND
- je wmcommand
- ...
- ...
- wmcommand:
- cmp [wparam], CBN_EDITUPDATE shl 16 + ID_LIST
- je combobox_filter
В фильтре все делается так, как написано выше. Если введенная строка меньше двух символов, то список выводится в полном объеме без фильтрации.
Code (Assembler) : Убрать нумерацию
- combobox_filter:
- ; Добавлять все строки
- mov ebx,1
- ; Получить длину введенной строки
- invoke SendMessage,[CtrlID],WM_GETTEXTLENGTH,0,0
- cmp eax,2
- ; Короткие строки не обрабатываем
- jb @f
- ; Требуется фильтрация по строкам
- mov ebx,0
- @@:
- ; Сохранить введенный текст и позицию курсора
- invoke SendMessage,[CtrlID],WM_GETTEXT,100h,buff
- invoke SendMessage,[CtrlID],CB_GETEDITSEL,posStart,posEnd
- ; Очистить список
- invoke SendMessage,[CtrlID],CB_RESETCONTENT,0,0
- ; Указатель на список элементов
- mov esi,items
- filter_list:
- ; Длина строки списка
- invoke lstrlen,esi
- or eax,eax
- jz filter_end
- push eax
- ; Добавляем в любом случае?
- cmp ebx,1
- je filter_add
- ; Строка включает в себя введенный фрагмент?
- stdcall str_in_text,buff,esi
- or eax,eax
- jz @f
- filter_add:
- ; Добавить строку в список
- invoke SendMessage,[CtrlID],CB_ADDSTRING,0,esi
- @@:
- pop eax
- ; Следующий элемент списка
- add esi,eax
- inc esi
- jmp filter_list
- filter_end:
- ; Вернуть на место строку
- invoke SetDlgItemText,[hwnddlg],ID_LIST,buff
- ; Вернуть позицию курсора
- mov eax,[posEnd]
- shl eax,16
- add eax,[posStart]
- invoke SendMessage,[CtrlID],CB_SETEDITSEL,0,eax
- ; Открыть отфильтрованный список
- invoke SendMessage,[CtrlID],CB_SHOWDROPDOWN,TRUE,0
В приложении пример программы с исходным текстом, которая создает в диалоговом окне комбобокс с функцией поиска и фильтрации списка по введенной строке.
Просмотров: 1343 | Комментариев: 0
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария