Delphi function

streamdown

Member
Joined
Feb 28, 2005
Messages
234
Reaction score
58
Age
40
Location
Москва
Всем привет! У меня такой вопрос:
есть обработка ввода в Edit:
procedure TToch.xKeyPress(Sender: TObject; var Key: Char);
begin
Case Key of
'0'..'9', #8:;
'.',',':
begin
Key := DecimalSeparator;
if pos (DecimalSeparator, x.Text) <> 0
then Key := Char(0);
end;
else Key := Char(0);
end;
end;
(Таких Edit-ов у меня штук 30) Можно ли вынести эту обработку как функцию, и потом просто везде ее вызывать? Или тогда как бороться с обращением (то что подчеркнуто) на конкретный Edit?
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
Можно, только это надо сделать процедурой, а не функцией (хотя в коде стоит именно процедура :) ). А вместо конкретного Edit-а используй Sender (только его надо к Edit-у привести). Т.е. замени везде конкретный Edit на TEdit(Sender). Ну а потом вызывай свою процедуру, передавая ей в Sender нужный Edit.
Удачи.
 

N3tM4n

Member
Joined
Oct 10, 2005
Messages
11
Reaction score
1
Location
localhost
Если создаешь Edit'ы динамически, то можно так:
<Имя_Edit'a>.OnKeyPress:=<Твоя_Собственная_Процедура-Обработчик>
 

Hans_Cristian

Member
Joined
Aug 9, 2004
Messages
20
Reaction score
1
Age
47
Location
xUSSR
Так процедура-то уже есть. Надо ее этим 30 Edit-ам назначить и все... Хоть в design-time, хоть в run-time
 

streamdown

Member
Joined
Feb 28, 2005
Messages
234
Reaction score
58
Age
40
Location
Москва
Hans_Cristian said:
назначить и все
А как назначить? Если отдельно вынести - нужно как-то перечислить все Edit-ы.
 

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
Если совсем все, то можно в RunTime так:
Code:
var 
  i, h: integer;
  q: TEdit;
...
  with TToch do begin      
    for i:=0 to ComponentCount-1 do begin
      if Components[i] is TEdit then begin
        q:=Components[i] as TEdit;
        q.OnKeyPress:=TToch.xKeyPress;
      end;
    end;
  end;
...
Не забудь X в обработчике заменить на (Sender as TEdit)!
 
Last edited by a moderator:

streamdown

Member
Joined
Feb 28, 2005
Messages
234
Reaction score
58
Age
40
Location
Москва
так, еще раз...извините если че не так писал ранее:
Есть функция:
Code:
function  goblin(Sender: TObject; var Key: Char): Char;
var 
  vrPos, vrLength, vrSelStart: byte;
const
  I: byte = 1;
 begin

  with Sender as TEdit do
  begin
    vrLength := Length(Text);
    vrPos := Pos(',', Text); 
    vrSelStart := SelStart; 
  end;

  case Key of

    '0'..'9':
      begin
          if (vrPos > 0) and (vrLength - vrPos > I) and (vrSelStart >= vrPos) then
          Key := #0;
      end;
    ',', '.':
      begin
          if (vrPos > 0) or (vrSelStart = 0) or (vrLength = 0) then
          Key := #0
        else
          Key := #44; 
      end;
    #8: ; 
  else
    Key := #0;
  end;
end;

Как и с какими параметрами мне ее надо вызывать для конкретного Edit-а?


Code:
procedure TToch.TKeyPress(Sender: TObject; var Key: Char);
begin
goblin([B][SIZE="3"]???????????[/SIZE][/B]);
end;
 

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
А зачем эту функцию в обработчике вызывать, если её можно сделать методом и тогда она сама и будет обработчиком? Она же ничего не возвращает?
То есть в классе TToch (насколько я понял, это форма) описать:
TTouch=class(TForm)
...
procedure goblin(Sender: TObject; var Key: Char);
...
end;

Затем можно хоть в инспекторе объектов, хоть в RunTime присваивать эту процедуру свойству OnKeyPress любого компонента.

Если же ты хочешь всё таки иметь отдельный обработчик для каждого TEdit'а, то вызывать её надо с параметрами goblin(Sender, Key). Но ведь получится куча лишнего кода?! И всё равно не понятно, почему она функция.

P.S. Замени типы byte на Integer. И скорость повысишь (поможешь оптимизатору и избежишь кучи преобразований типов), и от возможных ошибок убережёшься.
 
Last edited by a moderator:

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
streamdown,
тебе вроде как уже раза три тут все объяснили :) То, что ты пытаешься сделать функцией, нужно сделать процедурой, конкретный Edit ей везде передавать через Sender.
Единственное замечание. Подумай, стоит ли обрабатывать KeyPress! Вот помини мое слово, обязательно найдется умник, который тебе влепясит в Edit чего-нибудь через буфер обмена :) Я бы сделал обработку уже окончательно введенного в Edit текста. Хотя, все зависит от того, что нужно.
 

maidan

Member
Joined
Jan 6, 2005
Messages
93
Reaction score
4
Age
55
может конструкция
Code:
(sender as tedit).text:='Edit1';
понятнее будет???
 

N3tM4n

Member
Joined
Oct 10, 2005
Messages
11
Reaction score
1
Location
localhost
Подумай, стоит ли обрабатывать KeyPress! Вот помини мое слово, обязательно найдется умник, который тебе влепясит в Edit чего-нибудь через буфер обмена
Так можно сделать удаление в Edit.Text ненужных символов в обработчике на событие OnChange.
 
Last edited by a moderator:

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
Можно, но зачем? По мне, правильнее было бы обрабатывать все введенное один раз, непосредственно перед использованием. Разница - введен текст в 100 символов, при обработке на OnChange ты будешь проделывать обработку минимум сто раз (если он все правильно сразу ввел, а не правил много раз), а так - один.
 

Lord Phoenix

Member
Joined
Mar 10, 2006
Messages
83
Reaction score
18
Location
Freenet
N3tM4n said:
Да можно как хочешь сделать =) Это дело вкуса.
Ognev прав - эконимия проц.времени .Код хорош токо когда он оптимизирован и полностью безглючно исполняет свою функцию:)
 
Last edited by a moderator:

VVThanatos

New member
Joined
May 11, 2011
Messages
1
Reaction score
0
Всем привет! У меня такой вопрос:
есть обработка ввода в Edit:

(Таких Edit-ов у меня штук 30) Можно ли вынести эту обработку как функцию, и потом просто везде ее вызывать? Или тогда как бороться с обращением (то что подчеркнуто) на конкретный Edit?

обрабатывай senser
 

agent smith

New member
Joined
Jan 15, 2009
Messages
3
Reaction score
0
1. Создаешь свою процедуру обработки данных в TEdit, например:
procedure AnalyseDataInEdit(aTargetEdit: TEdit; aText: String);
2. Объявляешь в форме 2 глобальные переменные:
varDataStr: String;
varCurrentControl: TEdit;
3. Создаешь для одного из своих Edit-ов метод edtMainFieldOnChange(Sender: TEdit);
4. В этом методе присваиваешь некоторой своей глобальной переменной текст из Edit-a, например:
procedure TfrmToch.edtMainFieldOnChange(Sender: TObject);
begin
varDataStr := edtMainField.Text; // Запоминаем текст в глобальной переменной.
varCurrentControl := TEdit(Sender);// Запоминаем сработавший TEdit в пеерменной.
tmrCheckData.Enable := FALSE; // на форме располагаешь таймер с интервалом в
tmrCheckData.Enable := TRUE; // 500 и в его обработчике вызываешь метод...
end;

procedure TfrmToch.OnTimer(Sender: TObject);
begin
Timer.Enabled := FALSE; // отключаешь таймер на время его обработки.
if (varDataStr <> '') and (varCurrentControl <> nil)
then AnalyseDataInEdit(varCurrentControl: TEdit; varDataStr: String);
varCurrentControl := nil; // чистим переменную сработавшего контрола.
end;

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

4. Создаешь ещё одну процедуру, как упоминалось ранее, которая при активации формы пробегается по циклу (перебирает все компоненты на твоей форме и как только находит TEdit, то присваивает этому контролу на его метод OnChange тот, что ты создал уже в п.1.). При размещении на форме всех TEdit-ов, которые требуют обработки, хорошо бы в их Property "Tag" ставить значение, отличное от "0" и в цикле проверять ещё и это значение. Тогда не для всех подряд Edit-ов можно назначать обработчик в цикле, а лишь для нужных тебе.

Добавлено через 1 минуту
Кстати, если объявил глобальные переменные, то можно их тогда вообще в обработчике таймера не передавать в твой метод. Он и так будет иметь к этим переменым доступ.
 
Last edited by a moderator:

goga2

New member
Joined
Feb 1, 2007
Messages
2
Reaction score
0
Age
56
Location
Sumy
Глобальные переменные лучше не использовать. Запросто можно обойтись локальными.
 

toddams

New member
Joined
Oct 14, 2013
Messages
2
Reaction score
0
Также можно просто передавать как параметр в функцию.
 
Top