Blog. Just Blog

Выпадающий список (Combobox) с динамическим поиском

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Продолжаем усовершенствовать элемент Combobox. Создавать его мы научились, красивыми иконками снабдили, теперь давайте добавим полнотекстовый поиск по списку и фильтрацию. Справедливости ради стоит отметить, что зачаточный вариант поиска в комбобоксе все-таки присутствует. Если ввести какую-нибудь строку, а затем открыть выпадающий список, то курсор будет установлен на первом найденном пункте списка, который начинается с введенной строки. Я же хочу сделать так, чтобы в списке оставались только те пункты, в которых присутствует введенная строка, причем не только в начале, а вообще. Например, если я введу "Jo", то в списке должны остаться как "John Smith", так и "Patrick Joel".

Изменения поля ввода будем отлавливать штатными средствами в обработчике комбобокса. Это должно быть уведомление CBN_EDITUPDATE. После этого сохраняем введенную строку в сухом прохладном месте, очищаем список, а затем заполняем его, но уже только теми пунктами, где присутствует введенная строка.
  1.         cmp     [msg],WM_COMMAND
  2.         je      wmcommand
  3.         ...
  4.         ...
  5. wmcommand:
  6.         cmp     [wparam], CBN_EDITUPDATE shl 16 + ID_LIST
  7.         je      combobox_filter
Тут я использовал обработчик главного окна, но никто не запрещает воспользоваться субклассированием, а то и вовсе нарисовать какой-нибудь универсальный модуль для работы с комбобоксами.

В фильтре все делается так, как написано выше. Если введенная строка меньше двух символов, то список выводится в полном объеме без фильтрации.
  1. combobox_filter:
  2.         ; Добавлять все строки
  3.         mov     ebx,1
  4.         ; Получить длину введенной строки
  5.         invoke  SendMessage,[CtrlID],WM_GETTEXTLENGTH,0,0
  6.         cmp     eax,2
  7.         ; Короткие строки не обрабатываем
  8.         jb      @f
  9.         ; Требуется фильтрация по строкам
  10.         mov     ebx,0
  11. @@:
  12.         ; Сохранить введенный текст и позицию курсора
  13.         invoke  SendMessage,[CtrlID],WM_GETTEXT,100h,buff
  14.         invoke  SendMessage,[CtrlID],CB_GETEDITSEL,posStart,posEnd
  15.  
  16.         ; Очистить список
  17.         invoke  SendMessage,[CtrlID],CB_RESETCONTENT,0,0
  18.  
  19.         ; Указатель на список элементов
  20.         mov     esi,items
  21. filter_list:
  22.         ; Длина строки списка
  23.         invoke  lstrlen,esi
  24.         or      eax,eax
  25.         jz      filter_end
  26.         push    eax
  27.  
  28.         ; Добавляем в любом случае?
  29.         cmp     ebx,1
  30.         je      filter_add
  31.  
  32.         ; Строка включает в себя введенный фрагмент?
  33.         stdcall str_in_text,buff,esi
  34.         or      eax,eax
  35.         jz      @f
  36. filter_add:
  37.         ; Добавить строку в список
  38.         invoke  SendMessage,[CtrlID],CB_ADDSTRING,0,esi
  39. @@:
  40.         pop     eax
  41.         ; Следующий элемент списка
  42.         add     esi,eax
  43.         inc     esi
  44.         jmp     filter_list
  45. filter_end:
  46.         ; Вернуть на место строку
  47.         invoke  SetDlgItemText,[hwnddlg],ID_LIST,buff
  48.         ; Вернуть позицию курсора
  49.         mov     eax,[posEnd]
  50.         shl     eax,16
  51.         add     eax,[posStart]
  52.         invoke  SendMessage,[CtrlID],CB_SETEDITSEL,0,eax
  53.         ; Открыть отфильтрованный список
  54.         invoke  SendMessage,[CtrlID],CB_SHOWDROPDOWN,TRUE,0
Основное колдунство творится в пользовательской функции str_in_text. У меня это простейший регистрозависимый поиск подстроки в ASCIIZ-строке, приводить его тут не будут, посмотрите сами в исходнике. А для своих нужд вы можете наворотить любые проверки какой угодно сложности. Если проверка вернула EAX=0, то пункт в список не добавляется.

В приложении пример программы с исходным текстом, которая создает в диалоговом окне комбобокс с функцией поиска и фильтрации списка по введенной строке.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Combobox.Suggestion.Demo.zip (3,284 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 1264 | Комментариев: 0

Метки: Assembler, окна
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.06 сек. / MySQL: 2 (0.0046 сек.) / Память: 4.5 Mb
Наверх