Как осуществить ввод текста в компоненте Label



Все, конечно, слышали выражение "программа партии". А что было бы, если бы политические партии действительно писали программы?
Программа КПРФ
Последние версии документированы как совместимые с другими программами, но на самом деле после инсталляции стремятся их уничтожить. Интерфейс текстовый, белые буквы на красном фоне. Ядро написано более ста лет назад, с тех пор не только не исправлены старые глюки, но и добавлены многие новые. Считает, что все файлы должны быть одинакового размера. Периодически объявляет какое-нибудь расширение вредным и удаляет файлы с этим расширением по всему диску. Запросы на подтверждение имеют единственный вариант ответа: "Даешь!" Пытается выделять под свои задачи ресурсы, не заботясь об их физическом наличии, и в случае неудачи блокирует вывод сообщений об ошибках. При запросе диагностики выводит заранее сформированный файл, сообщающий, что все хорошо. Hе принимает электронную почту извне и прибивает задачи, пытающиеся ее отправить. Hе совместима с современной техникой. Hе может быть деинсталлирована легальными средствами.
Программа ЛДПР
Имеет яркий, аляповатый интерфейс и неотключаемые звуковые эффекты повышенной громкости. Может быть инсталлирована хоть на ХТ, однако заявляет о чрезвычайно высоких требованиях к системным ресурсам и на любой машине стремится захватить их как можно больше. В сообщениях активно использует нецензурную лексику, в особенности если пользователь - женщина. Постоянно грозится взломать сервер Пентагона и устроить mail-bombing президенту США, но физически не содержит модулей, способных на что-то подобное. Выводит множество предупреждений и сообщений об ошибках, в том числе самых невероятных, но никогда не виснет, не падает и не выгружается из памяти, даже если пользователь очень захочет. При выводе диагностики начинает торговаться с пользователем, обещая вывести хорошие результаты, если ей выделят больше ресурсов. Запрашивает высокую цену за инсталляцию и вдвое большую - за деинсталляцию.
Программа "Яблока"
Имеет красивый, стильный, но не всем понятный интерфейс. Отказывается работать с другими программами. Содержит мощный диагностический модуль, всегда готова дать пользователю подробный совет в любой ситуации, но на предложение выполнить конкретную операцию неизменно выдает сообщение с аргументированным объяснением, почему данная операция выполнена быть не может. Работает только на компьютерах фирмы Apple.
Программа HДР
Hекогда была главным системным модулем и по-прежнему пытается выполнять эту функцию. Имеет непонятный интерфейс и нечитабельную документацию. Сообщения об ошибках приписывает предыдущим и последующим версиям, а также внешним процессам. Пытается решить проблему нехватки ресурсов, постоянно прося пользователя вставить новую дискету и обещая впоследствии отдать две. Когда задача запрашивает память, сообщает, что память успешно выделена, но на самом деле выделяет ее не раньше чем через полгода, отобрав у других задач. В конечном итоге наглухо вешает машину.

Многие программисты задавая такой вопрос получают на него стандартный ответ "используй edit box." На самом же деле этот вопрос вполне решаем, хотя лейблы и не основаны на окне и, соответственно не могут получать фокус ввода и, соответственно не могут получать символы, вводимые с клавиатуры. Давайте рассмотрим шаги, которые были предприняты мной для разработки данного компонента.

Первый шаг, это кнопка, которая может отображать вводимый текст:


type
TInputButton = class(TButton)
private
procedure WmChar (var Msg: TWMChar); message wm_Char;
end;
procedure TInputButton.WmChar (var Msg: TWMChar);
var
Temp: string;
begin
if Char (Msg.CharCode) = #8 then
begin
Temp := Caption;
Delete (Temp, Length (Temp), 1);
Caption := Temp;
end
else
Caption := Caption + Char (Msg.CharCode);
end;

С меткой (label) дела обстоят немного сложнее, так как прийдётся создать некоторые ухищрения, чтобы обойти её внутреннюю структуру. Впринципе, проблему можно решить созданием других скрытых компонент (кстати, тот же edit box). Итак, посмотрим на объявление класса:


type
TInputLabel = class (TLabel)
private
MyEdit: TEdit;
procedure WMLButtonDown (var Msg: TMessage); message wm_LButtonDown;
protected
procedure EditChange (Sender: TObject);
procedure EditExit (Sender: TObject);
public
constructor Create (AOwner: TComponent); override;
end;

Когда метка (label) создана, то она в свою очередь создаёт edit box и устанавливает несколько обработчиков событий для него. Фактически, если пользователь кликает по метке, то фокус перемещается на (невидимый) edit box, и мы используем его события для обновления метки. Обратите внимание на ту часть кода, которая подражает фокусу для метки (рисует прямоугольничек), основанная на API функции DrawFocusRect:


constructor TInputLabel.Create (AOwner: TComponent);
begin
inherited Create (AOwner);
MyEdit := TEdit.Create (AOwner);
MyEdit.Parent := AOwner as TForm;
MyEdit.Width := 0;
MyEdit.Height := 0;
MyEdit.TabStop := False;
MyEdit.OnChange := EditChange;
MyEdit.OnExit := EditExit;
end;
procedure TInputLabel.WMLButtonDown (var Msg: TMessage);
begin
MyEdit.SetFocus;
MyEdit.Text := Caption;
(Owner as TForm).Canvas.DrawFocusRect (BoundsRect);
end;
procedure TInputLabel.EditChange (Sender: TObject);
begin
Caption := MyEdit.Text;
Invalidate;
Update;
(Owner as TForm).Canvas.DrawFocusRect (BoundsRect);
end;
procedure TInputLabel.EditExit (Sender: TObject);
begin
(Owner as TForm).Invalidate;
end;


Далее: Комбинация TLabel и TEdit »»