procedure TCustomComboBox.KeyPress(var Key: Char); function HasSelectedText(var StartPos, EndPos: DWORD): Boolean; begin SendMessage(Handle, CB_GETEDITSEL, Integer(@StartPos), Integer(@EndPos)); Result := EndPos > StartPos; end; procedure DeleteSelectedText; var StartPos, EndPos: DWORD; OldText: String; begin OldText := Text; SendMessage(Handle, CB_GETEDITSEL, Integer(@StartPos), Integer(@EndPos)); Delete(OldText, StartPos + 1, EndPos - StartPos); SendMessage(Handle, CB_SETCURSEL, -1, 0); Text := OldText; SendMessage(Handle, CB_SETEDITSEL, 0, MakeLParam(StartPos, StartPos)); end; var StartPos: DWORD; EndPos: DWORD; OldText: String; SaveText: String; Msg : TMSG; LastByte: Integer; begin inherited KeyPress(Key); if not AutoComplete then exit; if Style in [csDropDown, csSimple] then FFilter := Text else begin if GetTickCount - FLastTime >= 500 then FFilter := ''; FLastTime := GetTickCount; end; case Ord(Key) of VK_ESCAPE: exit; VK_TAB: if FAutoDropDown and DroppedDown then DroppedDown := False; VK_BACK: begin if HasSelectedText(StartPos, EndPos) then DeleteSelectedText else if (Style in [csDropDown, csSimple]) and (Length(Text) > 0) then begin SaveText := Text; LastByte := StartPos; while ByteType(SaveText, LastByte) = mbTrailByte do Dec(LastByte); OldText := Copy(SaveText, 1, LastByte - 1); SendMessage(Handle, CB_SETCURSEL, -1, 0); Text := OldText + Copy(SaveText, EndPos + 1, MaxInt); SendMessage(Handle, CB_SETEDITSEL, 0, MakeLParam(LastByte - 1, LastByte - 1)); FFilter := Text; end else begin while ByteType(FFilter, Length(FFilter)) = mbTrailByte do Delete(FFilter, Length(FFilter), 1); Delete(FFilter, Length(FFilter), 1); end; Key := #0; Change; end; else // case if FAutoDropDown and not DroppedDown then DroppedDown := True; if HasSelectedText(StartPos, EndPos) then SaveText := Copy(FFilter, 1, StartPos) + Key else SaveText := FFilter + Key; if Key in LeadBytes then begin if PeekMessage(Msg, Handle, 0, 0, PM_NOREMOVE) and (Msg.Message = WM_CHAR) then begin if SelectItem(SaveText + Char(Msg.wParam)) then begin PeekMessage(Msg, Handle, 0, 0, PM_REMOVE); Key := #0 end; end; end else if SelectItem(SaveText) then Key := #0 end; // case end; |