Что нового

[Элементы GUI] Поиск в ListBox при наборе текста не с начала строки

$k!NNeR

Новичок
Сообщения
5
Репутация
0
Версия AutoIt: 3.3.8.1

Описание: Создаю GUI с ListBox'ом. Данные в ListBox заносятся из файла. Нужна функция поиска в ListBox'е при наборе текста.
Примечания: Есть функция _GUICtrlListView_GetISearchString (построчный поиск), но в ней поиск именно с начала строки.
 
Автор
$

$k!NNeR

Новичок
Сообщения
5
Репутация
0
InnI
Спасибо за ответ. Остался вопрос каким образом можно добавить функционал поиска при наборе. Разбирая функцию _GUICtrlListView_GetISearchString не совсем понимаю как оно работает. Там ведь даже цикла нет.
 

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
$k!NNeR [?]
не совсем понимаю как оно работает
Функция "общается" с элементом через сообщения. Но это элемент класса SysListView32, и к Listbox отношения не имеет.

добавить функционал поиска при наборе
Вы хотите набирать прямо в Listbox или, например, в Input ?
 

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
$k!NNeR [?]
Ниасилил :( Но могу предложить фильтрацию
Код:
GUICreate("Listbox")
$nInput = GUICtrlCreateInput("", 10, 10)
$nList = GUICtrlCreateList("", 10, 30)
$aList = StringSplit("Остался вопрос каким образом можно добавить функционал поиска при наборе", " ")
FillList()
GUISetState()

GUIRegisterMsg(0x0111, '_WM_COMMAND')

Do
Until GUIGetMsg() = -3

Func FillList()
  For $i = 1 To $aList[0]
    GUICtrlSetData($nList, $aList[$i])
  Next
EndFunc

Func Filter($Text)
  GUICtrlSetData($nList, "")
  If Not $Text Then
    FillList()
  Else
    For $i = 1 To $aList[0]
      If StringInStr($aList[$i], $Text) Then GUICtrlSetData($nList, $aList[$i])
    Next
  EndIf
EndFunc

Func _WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
  Local $iIDFrom = BitAND($iwParam, 0xFFFF)
  Local $iCode = BitShift($iwParam, 16)
  Switch $iIDFrom
    Case $nInput
      Switch $iCode
        Case 0x300 ; $EN_CHANGE
          Filter(GUICtrlRead($nInput))
      EndSwitch
  EndSwitch
  Return "GUI_RUNDEFMSG"
EndFunc
 

AZJIO

Меценат
Меценат
Сообщения
2,892
Репутация
1,196
$k!NNeR
Вводи число, будет поиск его в списке.
Код:
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiListBox.au3>

Local $hGui, $iListBox, $hListBox, $iInput

; Создаёт GUI
$hGui = GUICreate('Поиск строки в ListBox', 400, 330)
$iInput = GUICtrlCreateInput('', 10, 330 - 30, 240, 22, -1, $WS_EX_STATICEDGE)
$iListBox = GUICtrlCreateList("", 0, 0, 396, 296)
$hListBox = GUICtrlGetHandle(-1)

; Добавляет строки
_GUICtrlListBox_BeginUpdate($hListBox)
For $i = 1 To 999
	_GUICtrlListBox_AddString($hListBox, StringFormat("%03d", $i))
Next
_GUICtrlListBox_EndUpdate($hListBox)

GUISetState()
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd

Func WM_COMMAND($hWnd, $imsg, $iwParam, $ilParam)
	Local $nNotifyCode, $nID, $sText, $iInput0
	$nNotifyCode = BitShift($iwParam, 16)
	$nID = BitAND($iwParam, 0xFFFF)
	Switch $hWnd
		Case $hGui
			Switch $nID
				Case $iInput
					Switch $nNotifyCode
						Case $EN_CHANGE
							; Поиск пункта
							Local $sInp = GUICtrlRead($iInput)
							Local $iIndex = _GUICtrlListBox_FindString($hListBox, $sInp)
							_GUICtrlListBox_SetCurSel($hListBox, $iIndex)
					EndSwitch
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND
 

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
AZJIO [?]
Вводи число, будет поиск
С числами - неудачный пример, т.к. работает аналогично "встроенному" поиску Listbox.

Сначала тоже хотел предложить подобный вариант, но раз условие "прямо в Listbox" всё равно не выполняется, то решил, что фильтрация будет лучше.
 

AZJIO

Меценат
Меценат
Сообщения
2,892
Репутация
1,196
InnI [?]
С числами - неудачный пример, т.к. работает аналогично "встроенному" поиску Listbox
Попробуй набери 976 во встроенном поиске и в поиске от начала. Надеюсь увидишь разницу.

то решил, что фильтрация будет лучше.
автор чётко сказал:
но в ней поиск именно с начала строки
 

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
AZJIO [?]
Надеюсь увидишь разницу.
Не увидел. Или не понял. В обоих случаях выделяется 976 (если, конечно, не нажимать каждую цифру после паузы в пару секунд).

автор чётко сказал
А я так понял, что он посетовал... Вот, мол, есть функция, как мне надо, но она ищет с начала, а мне нужно НЕ с начала строки.

Ладно. Чего зря спорить? :beer:
$k!NNeR вообще пожелал "прямо в Listbox". Так что оба примера могут быть "не совсем то, что нужно".


Добавлено:
Сообщение автоматически объединено:

Разобрался.
При наличии стиля $LBS_SORT поиск производится по последовательности символов (набираем 976, выделяется 900-970-976). При отсутствии сортировки ищется только первый символ (976: 900-700-600).
 
Автор
$

$k!NNeR

Новичок
Сообщения
5
Репутация
0
InnI сказал(а):
При наличии стиля $LBS_SORT
Не совсем понял по поводу стиля. В обоих примерах не увидел разницу.
В принципе если будет inputbox - не страшно, его и спрятать можно.

В итоге использовал код InnI. Подменил функцию на:

Код:
Func Filter($Text)
  $iIndex = _GUICtrlListBox_FindInText($nList, $Text)
_GUICtrlListBox_SetCurSel($nList, $iIndex)
EndFunc


Большое спасибо за помощь

P.S. Подредактирую в соответствии с правилами после того как форум полноценно заработает.
 

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
$k!NNeR сказал(а):
В обоих примерах не увидел разницу.
Разница в том, что в моём примере производится фильтрация, т.е. в списке остаются только пункты, содержащие введённую подстроку. А в примере AZJIO просто выделяется пункт, содержащий подстроку. Кстати, изменив функцию, вы "превратили" мой пример в пример AZJIO :smile:
 
Автор
$

$k!NNeR

Новичок
Сообщения
5
Репутация
0
Ну не совсем. Там поиск именно с начала строки. А используя _GUICtrlListBox_FindInText как раз в контексте строки. В любом случае благодарен за советы.
 
Верх