在 C++Builder (VCL) 中,標準 TComboBox 的 Style = csDropDown 允許用戶輸入文字,但預設不支援「輸入時自動匹配下拉列表項目並補全」的功能。本文提供一個輕量級實現方案。
OnChange 事件:用戶輸入/刪除字元時觸發。CB_FINDSTRING 訊息在列表中尋找以目前文字開頭的項目。ItemIndex,並用 CB_SETEDITSEL 選中新增的尾部文字,方便用戶繼續輸入或接受。// 表單單元宣告
private:
WORD LastKey; // 記錄最後按下的鍵
//---------------------------------------------------------------------------
void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
AnsiString Value = ComboBox1->Text;
// 忽略刪除操作
if (LastKey == VK_BACK || LastKey == VK_DELETE) {
LastKey = 0;
return;
}
LastKey = 0;
// 僅在游標位於文字末尾時處理
if (ComboBox1->SelStart != Value.Length())
return;
// 尋找以 Value 開頭的列表項(不區分大小寫)
int Index = SendMessage(ComboBox1->Handle, CB_FINDSTRING, -1,
(LPARAM)Value.c_str());
if (Index >= 0) {
ComboBox1->ItemIndex = Index; // 設定選中項
AnsiString NewText = ComboBox1->Text;
// 高亮補全的部分(從原長度到新長度)
SendMessage(ComboBox1->Handle, CB_SETEDITSEL, 0,
MAKELPARAM(Value.Length(), -1));
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ComboBox1KeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
LastKey = Key; // 記錄按鍵供 Change 事件判斷
}
//---------------------------------------------------------------------------
CB_FINDSTRING:從指定索引(-1 表從頭)搜尋以給定字串開頭的項目,返回索引或 -1。CB_SETEDITSEL:設定編輯區選取範圍,LOWORD 為起始位置,HIWORD 為結束位置(-1 表至末尾)。LastKey 需在表單建構子中初始化為 0。OnKeyPress 過濾非法字元。