15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Автозаполнение в TComboBox.

Компилятор: C++ Builder

В данной статье объясняется, как можно реализовать автозаполнение в TComboBox наподобие того, как это сделано в строке "Адрес" в браузере. Для этого нам потребуется перехватить в TComboBox события OnKeyDown и OnChange. В обработчиках этих событий мы будем производить поиск, замену и выделение. Вообще-то Win32 ComboBox уже имеет встроенную возможность автозаполнения, однако она не всегда включена. Для этого Win32 API имеет несколько сообщений:

CB_FINDSTRING - Осуществляет поиск строки, основанный на чувствительном к регистру поиске первых нескольких букв.

CB_FINDSTRINGEXACT - Находит первую строчку в списке (list box) комбобокса, которая удовлетворяет указанной строке.

CB_SELECTSTRING - Ищет в списке строку которая начинается с символов в указанной строке. Если удовлетворяющий пункт в списке найден, то он копируется в поле редактирования.

Мы будем использовать только CB_FINDSTRING. В этом примере, для заполнения списка, данные загружаются из таблицы customers.db из BCDEMOS, а затем перехватыватся события OnKeyDown и OnChange.

Перед тем, как начать поиск, CB_FINDSTRING получает в первом параметре (wParam) номер пункта. Так как мы ищем по всему списку, то устанавливаем его в -1. Второй параметр, это адрес строки для поиска.

-------------Код--------------
//cb это ComboBox
//lastKey - приветный мембер TForm1


__fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  Table1->Open(); 			//получаем данные из таблицы
  Table1->First();
  while (!Table1->Eof)
  {
    cb->Items->Add(Table1->FieldByName("Contact")->AsString);
    Table1->Next();
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cbKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
  lastKey = Key; //получаем последнюю клавишу, нажатую в ComboBox
}
//---------------------------------------------------------------------------

void __fastcall TForm1::cbChange(TObject *Sender)
{
  String srch = cb->Text; //текст, который будем искать
  if ((lastKey == 0x08) || (lastKey == VK_DELETE)) //если была нажата backspace
  {						   //или delete, то выходим отсюда

    lastKey = 0; 
    return;
  }
  lastKey = 0;

  int ix = cb->Perform(CB_FINDSTRING,-1,(LPARAM)srch.c_str()); //ищем строку в списке
  if (ix != CB_ERR)
  {
    cb->ItemIndex = ix;  		//устанавливаем соответствующий текст ComboBox
    cb->SelStart = srch.Length();
    cb->SelLength = (cb->Text.Length()-srch.Length()); //выделяем соответствующий текст
  }
}
//---------------------------------------------------------------------------