Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  06:26[Войти] | [Зарегистрироваться]
Ответ на вопрос № 68289

03-02-2009 10:36
Доброго времени суток!
На главной форме 9 компонентов TEdit, для каждого из которых установлен програмный фильтр ввода, подобный представленному ниже. Проблема в том, что этот код повторяется в обработчике нажатия клавиши для каждого TEdit'а с изменением только имени компонента. Подскажите пожалуйста, возможно ли подобный код вынести в отдельную процедуру (желательно чтобы она находилась в отдельном модуле) - общую для всех TEdit'ов, а затем в обработчике только вызывать её?

procedure TForm.L_AKeyPress(Sender: TObject; var Key: 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;
        if (vrLength=1) and (L_A.Text='0') and (vrSelStart=1)then Key:=#0;
        if (vrPos=0) and (vrLength=3) and (vrSelStart=3) and (not (L_A.Text='100'))
          then Key:=#0;
        if (L_A.Text='100') and (vrSelStart=3) and (Key<>'0') then Key:=#0;
        if (L_A.Text='1000')and (vrSelStart=4) then Key:=#0;
      end;
    ',', '.':
      begin
        if (vrPos > 0) or (vrSelStart = 0) or (vrLength = 0) then
          Key := #0
        else
          Key := #44;
        if (L_A.Text='1000') then Key:=#0;
      end;
    #8: ;
  else
    Key := #0;
  end;
end;

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

05-02-2009 00:31
Поскольку я с классами работать не умею, то мне очень интересно, можно ли такой фильтр реализовать через создание своего класса на основе TEdit или TCustomEdit.

Повторяю: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1367

04-02-2009 19:27
Если уж создавать свой класс, то не наследника TEdit, а универсальный TValidator от TObject. Такое было сделано еще в приснопамятном TurboVision. Аналогичное решение есть и под Windows, только платное (конкретную ссылку сейчас не дам, поскольку не вспомню, а искать нет ни желания, ни времени).

04-02-2009 15:15
>>> Поскольку я с классами работать не умею, то мне очень интересно, можно ли такой фильтр реализовать через создание своего класса на основе TEdit или TCustomEdit.

Можно. И гораздо легче, чем вы могли бы подумать... Но, думаю, лучше этого пока не делать. Причины - две:
1. К этому лучше переходить, уже имея некоторый опыт работы с классами.
2. В данном конкретном случае этого просто не нужно, только усложнит дело.

Достаточно часто более-менее объёмный код из обработчиков я выношу в отдельные пороцедуры, оставляя в самом обработчике только несколько строчек, примерно так, как сделали вы в приведённом коде. Это резко повышает читабельность. Однако я думаю, что вы это сделали по другой причине...

>>> А в обработчике события писал лишь

Эта фраза наводит на мысль о том, что вы видите выигрыш в в том, что весь код не придётся  писать в каждом обработчике, а оставить в каждом обработчике только одну строчку. Вот здесь и есть главная тонкость, которую вы, на мой взгляд, всё-таки не уловили.
Обработчики (в том числе и OnKeyPress) - это указатели на методы, имеющие определённый набор параметров. Конкретно OnKeyPress объявлен так:

property OnKeyPress: TKeyPressEvent;

В свою очередь тип TKeyPressEvent - это указатель на процедуру, являющуюся методом (а не просто отдельную процедуру), имеющую такие параметры:

type TKeyPressEvent = procedure (Sender: TObject; var Key: Char) of object;

Вы можете всем нужным TEdit назначить в качестве обработчика указатель на одну-единственную процедуру. И вот тут для определения того, от кого пришёл вызов, в дело и вступает параметр Sender...
Подробнее об этом почитайте мои ответы на »вопрос КС №50218«

Если вам понадобится фунционал процедуры Filter в других модулях, то логично будет просто вынести её в какой-нибудь модуль, где вы складируете полезные процедуры, а в нужных формах создавать один обработчик с одной строчкой и назначать его нужным элементам этой формы. Такой вариант гораздо проще и удобнее, чем писать отдельный класс...

P.S. Хотя язык и позволяет не указывать список параметров процедур и функций в разделе реализации, всё-таки этой возможностью лучше не пользоваться, поскольку читабельность кода резко ухудшается.

04-02-2009 14:17
Можно. Найдите книгу В. Фаронова "Искусство создания компонент в Делфи". Она вам поможет

04-02-2009 11:56 | Сообщение от автора вопроса
Спасибо за ваши ответы! Наверно это они меня надоумили.
Решил этот вопрос так:

unit ...;

interface
  procedure Filter(Sender: TObject; var Key: Char);

implementation
uses MainForm, StdCtrls;

procedure Filter;
const
  I: byte = 1;
var
  vrPos, vrLength, vrSelStart: byte; 
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;
        if (vrLength=1) and ((Sender as TEdit).Text='0') and (vrSelStart=1)then Key:=#0;
        if (vrPos=0) and (vrLength=3) and (vrSelStart=3) and (not ((Sender as TEdit).Text='100'))
          then Key:=#0;
        if ((Sender as TEdit).Text='100') and (vrSelStart=3) and (Key<>'0') then Key:=#0;
        if ((Sender as TEdit).Text='1000')and (vrSelStart=4) then Key:=#0;
      end;
    ',', '.':
      begin
        if (vrPos > 0) or (vrSelStart = 0) or (vrLength = 0) then
          Key := #0
        else
          Key := #44;
        if ((Sender as TEdit).Text='1000') then Key:=#0;
      end;
    #8: ;
  else
    Key := #0;
  end;
end;

end.



А в обработчике события писал лишь

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  Filter(Edit1, Key);
end;



Поскольку я с классами работать не умею, то мне очень интересно, можно ли такой фильтр реализовать через создание своего класса на основе TEdit или TCustomEdit.

03-02-2009 14:47
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1367

03-02-2009 11:12 | Комментарий к предыдущим ответам
with Sender as TEdit do - если вы используете возможности Sender, то все-таки неплохо бы было проверять, а действительно ли Sender - это TEdit и только потом делать приведение типов.

03-02-2009 10:38 | Вопрос к автору: запрос дополнительной информации
Судя по коду, работать с параметром Sender вы умеете. Непонятно, что же всё-таки вам мешает использовать Sender везде, не упоминая имя TEdit'а, и назначить всем своим TEdit'ам один обработчик.

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Кто съел Красную шапочку?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования