Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.11.26;
Скачать: CL | DM;

Вниз

Разр-тка TDigitEdit = class(TCustomEdit), как побороть сво-воText   Найти похожие ветки 

 
ru_efim   (2006-04-04 12:10) [0]

Здравствуйте. Разрабатываю свой компонент на базе TcustomEdit для ввода десятичных чисел.
TDigitEdit = class(TCustomEdit)
Возникла следующая проблема. У TcustomEdit есть свойство Text унаследованное от TControl. Надо закрыть доступ к этому свойству. Чтобы оно не отображалось в инспекторе объектов, как сделать понятно, я его просто не публикую. Но в теле программы ни что не мешает мне вставить оператор DigitEdit1.Text:=  ‘1u2’ ;, вот этого и надо предотвратить. Например, если не публиковать в TDigitEdit свойство MaxLength(оно введено непосредственно в TcustomEdit), то DigitEdit1.MaxLength:= .. выполнить будет не возможно.
Или какой метод надо переопределить, чтобы перед изменением свойства Text проводилась проверка нового значения этого свойства, ну и естественно, если значение не прошло проверку, была возможность отменить изменения. Дайте совет, пожалуйста.


 
MBo ©   (2006-04-04 12:48) [1]

А какие особые свойства должен иметь твой компонент? Если позволять вводить только числа - достаточно к стилю добавить ES_NUMBER


 
icWasya ©   (2006-04-04 16:18) [2]

пиши так
property Text write SetText;

и в процедуре SetText делай нужные проверки» Юрий Зотов:» Свойства невиртуальны, поэтому при изменении своего свойства Text метод SetText не вызовется. Кроме того, он статический да еще и приватный, так что перекрыть его тоже не получится. SetTextBuf тоже невиртуальный, перекрыть его тоже не выйдет.


 
ru_efim   (2006-04-04 23:22) [3]

Спасибо за советы. Добавить к стилю  ES_NUMBER поробую, возможно позволит освободится от ряда проверок. Но этого к сожалению не достаточно. На счет того что
"property Text write SetText; и в процедуре SetText делай нужные проверки", так что-то не получается. Мы заменяем TControl.Text, своим свойством ни как не связанным с наследуемым. Т.е. при присваивании нашему свойству Text значения, TControl.Text остается без изменений в то время как наш  компонент отображает именно TControl.Text. Метод TControl.SetText перегрузить тоже не получится т.к. это метод класса TControl, а в базовом классе его нет. Дак что же делать.


 
icWasya ©   (2006-04-05 11:19) [4]

ну остаётся посмотреть исходники


procedure TControl.SetText(const Value: TCaption);
begin
 if GetText <> Value then SetTextBuf(PChar(Value));
end;

procedure TControl.SetTextBuf(Buffer: PChar);
begin
 Perform(WM_SETTEXT, 0, Longint(Buffer));
 Perform(CM_TEXTCHANGED, 0, 0);
end;

procedure TControl.DefaultHandler(var Message);
var
 P: PChar;
begin
 with TMessage(Message) do
   case Msg of
     WM_GETTEXT:
       begin
         if FText <> nil then P := FText else P := "";
         Result := StrLen(StrLCopy(PChar(LParam), P, WParam - 1));
       end;
     WM_GETTEXTLENGTH:
       if FText = nil then Result := 0 else Result := StrLen(FText);
     WM_SETTEXT:
       begin
         P := StrNew(PChar(LParam));
         StrDispose(FText);
         FText := P;
         SendDockNotification(Msg, WParam, LParam);
       end;
   end;
end;



и попытаться переопределить реакцию на WM_SETTEXT» Юрий Зотов:» Вот это уже другое дело, но есть и более простое решение - перекрыть Change.


 
DimaBr   (2006-04-05 11:45) [5]

Создайте своё свойство Text


property Text: string read GetText;

function TDigitEdit.GetText:string;
begin
 Result := inherited Text;
end;


оно будет только для чтения и присвоить ему не получится» Юрий Зотов:» TCustomEdit(MyEdit).Text := "Вова";
Что получится?


 
Юрий Зотов ©   (2006-04-05 11:49) [6]

Перекрыть Change - и весь вопрос. Например, тупо "в лоб":

procedure TDigitEdit.Change;
var
 OldPos: integer;
begin
 OldPos := SelStart;
 try
   StrToInt64(Text);
   FOldText := Text;
   inherited
 except
   on E: EConvertError do
   begin
     Text := FOldText;
     SelStart := OldPos - 1
   end
   else
     raise
 end
end;
» Юрий Зотов:» FOldText - поле компонента.


 
DimaBr   (2006-04-05 20:02) [7]


> » TCustomEdit(MyEdit).Text := "Вова";

ну, конечно я Вас уважаю, но можно в потомке и CNCommand(var Message: TWMCommand); message CN_COMMAND;
переопределить и в Change вообще не попадём.


 
Юрий Зотов ©   (2006-04-05 20:37) [8]

> DimaBr   (05.04.06 20:02) [7]

Можно. И это правильно. Значит, разработчик потомка и не хотел, чтобы код попадал в Change - на то он и разработчик потомка. Component writer, а не прикладной батонокидатель. Но он обязан это сделать так, что уж если код не попадает в Change, то он не должен попадать туда никогда, каким бы образом к компоненту ни обращались и к какому бы типу его ни приводили. Иначе он полный чайник, а никакой не component writer.

А прикладному батонокидателю ничто не мешает написать в своей программе приведения типа а-ля
TCustomEdit(FindComponent(...)).Text := "Вова"
и при этом он в полном праве ожидать корректного поведения компонента. А компонент вдруг поведет себя некорректно - и бедняга будет долго ломать голову над неожиданным багом, а потом скажет пару теплых слов в адрес разработчика компонента, который сделал поведение свойства зависимым от того, каким образом происходит обращение к этому свойству.. Приводим к TDigitEdit - работает, приводим к TСustomEdit - не работает. Налицо нарушение основополагающего принципа ООП.

Подчеркнутое и есть суть. Такого быть не должно.



Страницы: 1 вся ветка

Текущий архив: 2006.11.26;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.028 c
15-1162820991
сисадмин
2006-11-06 16:49
2006.11.26
тема: "вирь - убийца спаммеров"


15-1162669363
antonn
2006-11-04 22:42
2006.11.26
про апачи и прочее для создания сайта на пхп...


3-1159253506
ScoPal
2006-09-26 10:51
2006.11.26
DOA Oracle не могу получить ошибку привызове процедуры.


15-1162931282
Ice
2006-11-07 23:28
2006.11.26
Помогите потестить программу.


15-1163052832
Layner
2006-11-09 09:13
2006.11.26
Привязка к MAC адресу, версии BOIS программы... за и против