Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > применить код ко множеству компонентов


Автор: zercalo 5.6.2006, 14:35
я извиняюсь, видимо, за такие вопросы, ибо совсем начинающий, а в имеющейся под рукой литературе не найду ответа на свой вопрос.
Я пишу первую самостоятельную и сложную (для меня) программу на делфи и у меня есть код:
Код

procedure TForm1.Edit41KeyPress(Sender: TObject; var Key: Char);
begin
case Key of
'0'..'9',#8:
else
Key:=Chr(0);
end;
if Length(Edit41.Text)=0 then Edit42.SetFocus;
end;
Вопрос такой: У меня таких компонентов (типа Edit41) 20 штук. Как можно не переписывать код для 20 компонентов, а уместить их в одну процедуру. Я знаю есть какое-то свойство Tag, но у меня применить его не выходит..
И второй вопрос:
у меня есть 4 компонента edit. Я проделываю с ними простую фигню:
procedure TForm1.Edit1Change(Sender: TObject);
begin
Memo2.Lines.Clear;
Memo2.Lines.Add(Edit1.Text);
end;

смысл тот, что я пытаюсь синхронизировать ввод в edit с вводом в memo.
Но затем мне нужно создать Edit2Change с тем, чтобы текст из edit2 прибавился в memo в строчку к edit1.
И кроме того, нужно будет еще edit3 с таким же синхронизированным вводом, но его нужно запихать в memo строкой ниже так, чтобы edit1 и edit2 не стерлось. Еще раз извиняюсь за видимо очевидные вопросы.. .  

Автор: maxim1000 5.6.2006, 15:18
перенесено из Алгоритмов... 

Автор: Rennigth 5.6.2006, 15:28
Цитата(zercalo @  5.6.2006,  14:35 Найти цитируемый пост)
я извиняюсь, видимо, за такие вопросы, ибо совсем начинающий, а в имеющейся под рукой литературе не найду ответа на свой вопрос.
Я пишу первую самостоятельную и сложную (для меня) программу на делфи и у меня есть код:
procedure TForm1.Edit41KeyPress(Sender: TObject; var Key: Char);
begin
case Key of
'0'..'9',#8:
else
Key:=Chr(0);
end;
if Length(Edit41.Text)=0 then Edit42.SetFocus;
end;
Вопрос такой: У меня таких компонентов (типа Edit41) 20 штук. Как можно не переписывать код для 20 компонентов, а уместить их в одну процедуру. Я знаю есть какое-то свойство Tag, но у меня применить его не выходит..


для всех твоих edit-ов d ObjectInspector-e выбери из списка одну и ту же процедуру или в конструкторе формы присвой в ручную:
Код

  for i := 0 to ControlCount do
    if controls[i] is TEdit then
      TEdit(controls[i]).OnKeyPress := Edit41KeyPress;



 

Автор: zercalo 5.6.2006, 16:53
2Rennigth
Ну в общем да.. . Подходяще более или менее. Но как ты можешь заметить у меня в строке if Length(Edit41.Text)=0 then Edit42.SetFocus; после 1-й цифры идет табуляция на следующий элемент. В твоем случае табуляция будет идти всегда на Edit42.
Второй вопрос я понял уже.. .
 

Автор: Albinos_x 5.6.2006, 18:50
Цитата(zercalo @  5.6.2006,  16:53 Найти цитируемый пост)
Но как ты можешь заметить у меня в строке if Length(Edit41.Text)=0 then Edit42.SetFocus; после 1-й цифры идет табуляция на следующий элемент. В твоем случае табуляция будет идти всегда на Edit42.


очень просто:

Код
...
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var ind:integer;
    s:string;
begin
if not (key in ['0'..'9',#8]) then key:=#0 else exit; {выходим т.к. дальнейшие операции в этом случае не нужны}
if Length((Sender as TEdit).Text)=0 then
   begin
   s:=(Sender as TEdit).Name;
   delete(s,1,4);  {Edit - 4 символа удаляем}
   ind:=strToInt(s); {узнаём номер Эдита}
   inc(ind);       {вычисляем следующий номер}
   s:='Edit'+inttostr(ind);   {стряпаем ново необходимое имя}
   // чтобы не перебирать все компоненты вычисляем
   // номер текущего плюс 1, т.е. следующий
   // и будем отталкиваться от него
   ind:=(Sender as TEdit).ComponentIndex+1;
   // ищем нужный компонент от вычисленного индекса
   while Components[ind].Name<>s do
      begin
      // если нидекс превысил или авен последнему, то
      if ind>=(ComponentCount-1) then
         ind:=0    // начинаем поиск сначала
         else
         inc(Ind);  // иначе переходим к следующему
      // если прошли круг и не нашли нужный компонент, то
      // выходим из процедуры
      if ind=(Sender as TEdit).ComponentIndex then exit;
      end;
   // устанавливаем фокус на нужный компонент
   (Components[ind] as TEdit).SetFocus;
   end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
Memo1.Text:=(Sender as TEdit).Text;
end;
...


остальное сделай как сказал 
Rennigth
 

Автор: zercalo 6.6.2006, 09:53
2Albinos_x 
уфф.. . Вроде разобрался и пережёвываю. Большое спасибо - витиевато, но неплохой урок для работы с компонентами, положу в архивчик и буду использовать - но неужели нет способа проще? Ты там такие финты выделывал.. 

Автор: Albinos_x 6.6.2006, 17:47
можно... 
к примеру для упрощения можно заменить команды 
Код
...
   delete(s,1,4);  {Edit - 4 символа удаляем}    
   ind:=strToInt(s); {узнаём номер Эдита}
...

на 
Код
...
ind:=strToInt(copy(s,5,Length(s)-4);
...

далее
Код
...
ind:=(Sender as TEdit).ComponentIndex+1;
...

это можно заменить на 
Код
...
ind:=0;
...

с вытекающими тогда изменениями в коде
но тогда, каждый раз будут перебираться компоненты все сначала...

можно ещё воспользоваться функцией FindComponent... тогда можно заменить цикл и ещё пару команд на:
Код
...
(FindComponent(s) as TEdit).SetFocus;
...


итого получаем упрощённый вариант:
Код
...    
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);    
var ind:integer;    
      s:string;    
begin    
if not (key in ['0'..'9',#8]) then key:=#0 else exit; 
if Length((Sender as TEdit).Text)=0 then    
   begin    
   s:=(Sender as TEdit).Name;    
   ind:=strToInt(copy(s,5,Length(s)-4);    
   (FindComponent('Edit'+inttostr(ind+1)) as TEdit).SetFocus;
   end;    
end;    

procedure TForm1.Edit1Change(Sender: TObject);    
begin    
Memo1.Text:=(Sender as TEdit).Text;    
end;
...


не проверял... но по идее должен работать... единственное не знаю, произойдёт ли ошибка, если компонент найден не будет...  

Автор: skyboy 6.6.2006, 17:52
FindComponent при отсутствии "абонента" вернёт nil - надо проверять, иначе при доступе будет AV 

Автор: Albinos_x 6.6.2006, 18:00
тогда можно попробовать сделать так:
 
Код
...     
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);     
var ind:integer;     
      s:string;    
      Ed:TEdit;    
begin     
if not (key in ['0'..'9',#8]) then key:=#0 else exit;    
if Length((Sender as TEdit).Text)=0 then     
   begin     
   s:=(Sender as TEdit).Name;     
   ind:=strToInt(copy(s,5,Length(s)-4); 
   Ed:=(FindComponent('Edit'+inttostr(ind+1)) as TEdit);
   if Ed<>nil then Ed.SetFocus;    
   end;     
end;     

procedure TForm1.Edit1Change(Sender: TObject);     
begin     
Memo1.Text:=(Sender as TEdit).Text;     
end;    
...
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)