Заполнение в ComboBox (компонент)
В статье показывается, как расширить уже существующий компонент. Не обязательно создавать всегда новый компонент, можно просто улучшить уже существующий. Можно просто создать новый класс и получать из него все, что Вы хотите улучшить.
В нашем случае, мы собираемся расширить компонент TComboBox непосредственно. Мы могли бы выбрать TCustomComboBox, но у него имеются различные published свойства в разных версиях Delphi.
Delphi делает эту задачу простой, предлагая маленький мастер. Из меню File -> New... выберите Component на первой вкладке New.
Появится простой мастер. Заполните соответственно:
- Ancestor Type: TComboBox
- Class Name: TFillComboBox
- Palette Page: Samples (или любая другая, например "Standard")
- Unit File Name: Выберите папку и файл для сохранения Вашей работы
Нажмите OK. Мы установим его позже.
Мастер создаст основной компонент, включая подпрограмму установки:
procedure Register; begin RegisterComponents('Standard', [TFillComboBox]); end;
Эта подпрограмма будет вызвана Delphi, когда Вы выберите установку пакета, включая этот файл.
Первый параметр RegisterComponents называет страницу палитры, где компонент будет установлен, второй - массив компонентов, которые будут установлены.
Добавление нового свойства
К нашему новому компоненту, мы добавим новой свойство AutomaticFillIn. Когда он установлен в True, мы будем искать элемент, соответствующий вводу пользователя и добавлять остаток к текстовому полю.
Поэтому мы должны объявить одну частную переменную, которая будет хранить знечение переключателя.
Поместив переменную в Published секцию, мы позволим пользователю изменять ее значение в Инспекторе Объектов.
private FAutomaticFillin: Boolean; procedure SetAutomaticFillin(const Value: Boolean); published property AutomaticFillin: Boolean read FAutomaticFillin write SetAutomaticFillin default True; procedure TFillComboBox.SetAutomaticFillin( const Value: Boolean); begin FAutomaticFillin := Value; end;
Обработка изменения текста пользователем
Чтобы узнать, когда пользователь изменяет текст в текстовом поле, мы должны отменить заданный по умолчанию обработчик сообщения для ComboBox.
protected procedure ComboWndProc( var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer ); override;
Сначала проверяем, включена ли специальная обработка. Если да, получим текущий текст, который ввел пользователь, а затем ищем его в списке. Если есть соответствие, заменим текст существующим элементом и выделим часть, добавленную нашей функцией.
Напишите код модуля и сохраните файл:
unit FillComboBox; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TFillComboBox = class(TComboBox) private FAutomaticFillin: Boolean; procedure SetAutomaticFillin(const Value: Boolean); protected procedure ComboWndProc( var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer ); override; public published constructor Create(AOwner: TComponent); override; property AutomaticFillin: Boolean read FAutomaticFillin write SetAutomaticFillin default True; end; procedure Register; implementation procedure Register; begin RegisterComponents('Standard', [TFillComboBox]); end; { TFillComboBox } procedure TFillComboBox.ComboWndProc( var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer ); var I: Integer; CurrentText: String; begin inherited ComboWndProc(Message, ComboWnd, ComboProc); // пропускаем обработку, если отключено if not FAutomaticFillin then Exit; // сначала проверим, была ли нажата клавиша BackSpace, // в этом случае не заполняем! if Message.Msg = WM_CHAR then begin // ищем все символы от 32 (Пробел) до 127 (Upper ANSI) if TWMChar(Message).CharCode in [$20..$7F] then begin // заполняем остальную часть текста // сохраняем текущий текст, который напечатал пользователь CurrentText := Text; // получаем первую строк, которая соответствует части текста I := SendMessage(Handle, CB_FINDSTRING, -1, LongInt(PChar(CurrentText))); if I >= 0 then begin // найдено соответствие! // загружаем соответствие, и в позицию этой строки Text := Items.Strings[I]; // выделим текст, который не был напечатан SelStart := Length(CurrentText); SelLength := Length(Text) - Length(CurrentText); end; end; end; end; constructor TFillComboBox.Create(AOwner: TComponent); begin inherited Create(AOwner); FAutomaticFillin := True; end; procedure TFillComboBox.SetAutomaticFillin(const Value: Boolean); begin FAutomaticFillin := Value; end; end.
Инсталляция компонента
Теперь нужно установить компонент, который Вы только что создали.
В меню Component -> Install Component... выберите свой FillComboBox.pas в поле Unit file name и нажмите OK.
Все! Теперь Вы можете создать новое приложение и использовать компонент.
Комментарии