Разное > Программирование
Помощь по Delphi
BlueHairLady:
На старом форуме находилась очень полезная тема: http://magicteam.mybb.ru/viewtopic.php?id=4&p=6 . Думаю, её стоит продолжить. Тем более, что у меня появилось затруднение. Постараюсь сформулировать попонятнее.
Хочу наконец научиться создавать собственные компоненты. А конкретнее, собираюсь создать небольшой простенький компонент (HexEasy), который бы позволял работать с числом как в десятичном, так и в шестнадцатеричном представлениях. Не мудрствуя, в качестве базового взяла Edit. Сочла наиболее удобным создать отдельное поле (FValue: Integer), непосредственно содержащее число, десятичное или шестнадцатеричное изображение которого выведено на монитор. По моей задумке, когда фокус находится на данном компоненте, любое нажатие клавиши должно либо игнорироваться, либо приводить к изменению данной переменной. Т.е. обработка события KeyPress должна состоять как бы из трёх этапов:
1. Предварительный анализ введённого символа на его допустимость.
2. Изменение свойства Text элемента.
3. Анализ изменённого свойства Text: преобразование его в значение FValue и в случае необходимости дальнейшая корректировка.
Я пыталась это сделать примерно таким образом:
procedure THexEasy.KeyPress (var key: Char);
begin
. . . . . . . . . . . . //предварительная обработка символа key
inherited KeyPress(key);
If Text='' then begin
FValue := 0;
EXIT;
end;
FValue := StrToInt(Text);
If FValue>FValueMax then begin //если число больше максимально допустимого...
FValue := FValueMax;
Text := IntToStr(FValue);
end; //всё это упрощённо, когда работа идёт с десятичным числом
end;
Но в результате вставки в программу примерно такого кода обнаружилось, что свойство Text компонента изменяется лишь после того, как данная процедура полностью закончит свою работу. Т.е. анализируемое в последней части свойство Text имеет содержание, которое было до того, как пользователь нажал клавишу, а мне нужно обработать именно последствия нажатия. Можно ли как-то форсировать изменение свойства Text?
Никогда не создавала компоненты и даже классы, не ругайтесь сильно, если где-то глуплю.
Джинни:
{
!!УБРАТЬ!!
. . . . . . . . . . . . //предварительная обработка символа key
inherited KeyPress(key);
If Text='' then begin
FValue := 0;
EXIT;
end;
!!УБРАТЬ!!
}
if Key in ['$', 'x', #13] then Key := #0;
if Key in ['0'..'9', 'A'..'F', 'a'..'f'] then
begin
FValue := StrToIntDef(Text + Key, FValueMax); //в случае ошибки будет возвращать FValueMax
Key := #0;
If FValue>FValueMax then begin //если число больше максимально допустимого...
FValue := FValueMax;
end; //всё это упрощённо, когда работа идёт с десятичным числом
Text := IntToStr(FValue);
end;
//всё это будет работать и с шестнадцатиричными числами в формате $123 или 0x123
BlueHairLady:
Прости, Джинни, но данный алгоритм кривоватенький, поскольку новый символ всегда добавляется в конец, вне зависимости от места расположения курсора. Да и сам курсор после каждого нажатия перемещается на первую позицию поля ввода, что сбивает с толку.
Насколько я знаю, есть свойство SelStart, которое находит/устанавливает позицию курсора. С его помощью данный алгоритм, наверное, получится довести до ума, хотя всё это и будет выглядеть громоздко. Не знаю..., здесь тоже есть подводные камни... Но неужели нет более простого способа непосредственно прочитать уже изменённое свойство Text?
Джинни:
Это вообще не алгоритм, а спонтанная демонстрация возможностей. :)
SelStart есть, да. Но значение Text вообще лучше в KeyPress не обрабатывать. Есть событие OnChange - там текст уже изменённый после KeyPress.
BlueHairLady:
Спасибо, сейчас попробую. Мне в любом случае нужно было писать обработчик события onChange :), поскольку значения могут заноситься в поле ввода не только набором с клавиатуры, но и копированием. Мне нравится, когда всё учтено. o:)
Навигация
Перейти к полной версии