На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> Проверка ввода символов в Edit (edit-oв много)
    На форме содержиться несколько Edit и в каждом надо проверять вводимые символы (только цифры и минус).
    Проблема в том, что я не знаю как оптимизировать код (громоздким не делать). Т.е. для каждого edit нужно писать вот этот кусочег кода
    ExpandedWrap disabled
      case key of
      '0'..'9': ;
      '-'     : if length(Edit1.Text)<>0 then key:=#0;
      else key:=#0;
      end;

    Можно, конечно, и сделать отдельную процедуру, в которую будем передавать вводимый символ и сам editN. вот так это будет:
    ExpandedWrap disabled
      type
        TForm1 = class(TForm)
          Edit1: TEdit;
          Edit2: TEdit;
          Edit3: TEdit;
          procedure k1(Sender: TObject; var Key: Char);
          procedure k2(Sender: TObject; var Key: Char);
          procedure k3(Sender: TObject; var Key: Char);
        private
          { Private declarations }
        public
          { Public declarations }
        end;
       
      var
        Form1: TForm1;
       
      implementation
       
      {$R *.dfm}
      Procedure control(var ch: char; var edt: TEdit);
      begin
      case ch of
      '0'..'9': ;
      '-'     : if length(edt.Text)<>0 then ch:=#0;
      else ch:=#0;
      end;
      end;
       
      procedure TForm1.k1(Sender: TObject; var Key: Char);
      begin
      control(key, Edit1);
      end;
       
      procedure TForm1.k2(Sender: TObject; var Key: Char);
      begin
      control(key, Edit2);
      end;
       
      procedure TForm1.k3(Sender: TObject; var Key: Char);
      begin
      control(key, Edit3);
      end;
       
      end.

    Нельзя ли как нибудь это упростить?
    хм, только щас заметил, а почему все заголовки процедур состоят только из TForm1.k*? а где же ещё название edit'a? разьве не должно быть так TForm1.Edit1k1(.....var key:char);?

    Событие onKeyPress обрабатывается.
      сдедай для одного Edit а всем остальным укажи тот же метод.
      Цитата Continental @
      хм, только щас заметил, а почему все заголовки процедур состоят только из TForm1.k*? а где же ещё название edit'a? разьве не должно быть так TForm1.Edit1k1(.....var key:char);?

      методы называются
      TForm1.CompanentNameMethode(Sender: TObject...........)
        Спасибо, что помогли. Я понял, впринципе, любому обекту можно один и тот же метод назначить. :)

        Добавлено
        а как же тогда проверять длинну строки в edit'e?
        чтобы минус написать только первым и не "пять" раз есть вот такая проверка:
        ExpandedWrap disabled
          procedure TForm1.contr(Sender: TObject; var Key: Char);
          begin
          case key of
          '0'..'9', #8: ;
          '-' : if length(Edit1.Text)<>0 then key:=#0; <------- length
          else key:=#0;
          end;
          end;

        И если несколько edit'oв пользуются одним методом, то что надо написать в Length(?)
          length(TEdit(Sender).Text)
            [quote=Continental,1221139547,2066876]'-' : if length(Edit1.Text)<>0 then key:=#0; <------- length[/quote]
            Параметр Sender это и есть Edit, в который вводится символ
            ExpandedWrap disabled
              '-' : if length((Sender as TEdit).Text)<>0 then key:=#0; <------- length[/quote]


            PS: опоздал ..
            Сообщение отредактировано: leo -
              Если такая задача становится достаточно часто, то можно написать свой компонент - потомок от TEdit :)
                А почему можно написать в скобках
                Цитата Shaggy @
                TEdit(Sender).Text
                и с помощью as
                Цитата leo @
                (Sender as TEdit).Text
                Т.е. это где-то играет роль в каких-либо определённых случаях, или это просто такая обширность у языка?
                Цитата and85 @
                Если такая задача становится достаточно часто, то можно написать свой компонент - потомок от TEdit

                Пока что мне до этого далеко.


                А вот можете пожалуйста помочь ещё с одним вопросом. В моём случае есть три edit'a и кнопка вычислить (сложить всё что во всех полях), причём если хоть один edit не заполнен - кнопка Button1.Enabled:=false;
                Я проверял поля при помощи onChange:
                ExpandedWrap disabled
                  procedure TFm_Tover.Pr(Sender: TObject);
                  begin
                  if Edt_name.Text<>'' then
                     begin
                     if Edt_price.Text<>''then
                        begin
                        if Edt_count.Text<>''then Btn_Calc.Enabled:=true else
                           Btn_Calc.Enabled:=false;
                        end else Btn_Calc.Enabled:=false;
                     end else Btn_Calc.Enabled:=false;
                   
                  end;

                т.е. я с помошью if .. else проверял каждое поле и устанавливал кнопке значение Enabled. Вот только при трёх полях, алгоритм уже плохо читается. Есть какой-нибудь способ, чтобы сократить данный код?

                Тему новую не стал создавать, так как посчитал, что речь идёт почти про одно и то же, так что не сочтите мусором.
                  для определённости:
                  1) TEdit(Sender)
                  и
                  2) (Sender as TEdit)

                  1)
                  a) стоит исползовать только если Sender - это именно TEdit(в данном случае)
                  т.е. фактически это инструкция компилятору - "заткнись и делай, что велено..."
                  б) никаких проверок не производится, и если на самом деле Sender это не TEdit, то в результате получищь кучу глуков - от: странное поведение программы, до AV

                  2) так называемое "безопасное приведение типов", т.е. производится проверка: Sender - это на самом деле TEdit?
                  и если нет, возбуждается исключение EInvalidCast
                    Цитата Shaggy @
                    никаких проверок не производится, и если на самом деле Sender это не TEdit, то в результате получищь кучу глуков - от: странное поведение программы, до AV

                    А я видел как Sender использовался с Button.
                    ExpandedWrap disabled
                      ....
                      procedure TForm1.DigitBtnClick(Sender: TObject);
                      var
                          Btn: TButton;
                          ch: Char;
                      begin
                        Btn := Sender as TButton;
                        ch  := Chr(48+Btn.Tag);
                      .....
                      ......

                    это значит относится ко второму пункту ---->
                    Цитата Shaggy @
                    2) так называемое "безопасное приведение типов", т.е. производится проверка: Sender - это на самом деле TEdit?
                    и если нет, возбуждается исключение EInvalidCast
                      Continental думаю помочь решить проблему может написание собственого компонента с рассшренными возможностями по контролю ввода ... ;)

                      з.ы.: в архиве прилагается мое видение решения данной проблемы ...
                      Прикреплённый файлПрикреплённый файлXPEdit.rar (8.88 Кбайт, скачиваний: 394)
                        Цитата Continental @
                        Есть какой-нибудь способ, чтобы сократить данный код?

                        ExpandedWrap disabled
                          Btn_Calc.Enabled:=(Edt_name.Text<>'') and
                                            (Edt_price.Text<>'') and
                                            (Edt_count.Text<>'');

                        Хотя думается в данном случае лучше не дизэйблить кнопку, а вынести проверки в обработчик нажатия Btn_CalcClick и если один из эдитов не заполнен то выдавать сообщение или бип и переводить фокус на пустой эдит
                        ExpandedWrap disabled
                          procedure TForm1.Btn_CalcClick(Sender: TObject);
                            function IsEmpty(e:TEdit;const what:string):boolean;
                            begin
                              Result:=e.Text = '';
                              if Result then
                              begin
                                beep;
                                MessageDlg('Введите значение: '+what,mtWarning,[mbOk],0);
                                FocusControl(e);
                              end;
                            end;
                          begin
                            if IsEmpty(Edt_name,'Наименование') or IsEmpty(Edt_price,'Цена') or IsEmpty(Edt_count,'Количество') then
                              Exit;
                            ...
                          end;
                          Если начать сначала.
                          я так и не понял, как сделать чтоб в edit`ы можно было вводить только цифры???
                          в каком событии писать
                          ExpandedWrap disabled
                            case ch of
                            '0'..'9': ;
                            '-'     : if length(edt.Text)<>0 then ch:=#0;
                            else ch:=#0;

                          ????

                          и сразу же второе,
                          как сделать это сразу для нескольких edit`ов?
                          как работать с методами
                          ExpandedWrap disabled
                            TForm1.CompanentNameMethode(Sender: TObject...........)


                          ????
                          заранее спасибо ........пис
                            Нужно создать один обработчик Edit1KeyPress и назначить его нескольким эдитам. Причем если в обработчике используется обращение к св-вам эдита (например Text), то для того, чтобы этот обработчик был универсальным, нужно вместо прямых ссылок типа edt.Text использовать (Sender as TEdit).Text
                            ExpandedWrap disabled
                              procedure TForm1.Edit1KeyPress(Sender:TObject;var Key:Char);
                              begin
                                if not (Key in ['-','0'..'9']) or
                                   (Key = '-') and (Length((Sender as TEdit).Text) <> 0) then
                                  Key:=#0;
                              end;
                              Есть маленькое замечание. Нигде не обрабатывается вставка из буфера винды. Тоесть, если у меня в буфере белиберда 'алдывраывлоарыдлаорывдлаорыва', то нажав Shift+Insert, я смогу эту бяку к себе в эдит вставить:)

                              P.S. У andrew.virus это похоже учитывается:)
                              Сообщение отредактировано: and85 -
                                Минутку, а backspace? почему не работает? можно удалять только кнопкой "delete".??
                                Объясните пожалуйста, как сделать, чтоб в определенное количество едитов. можно было вводить только цифры, и стирать кнопкой backspace???
                                Сообщение отредактировано: subsonic -
                                  Цитата and85 @
                                  Есть маленькое замечание. Нигде не обрабатывается вставка из буфера винды. Тоесть, если у меня в буфере белиберда 'алдывраывлоарыдлаорывдлаорыва', то нажав Shift+Insert, я смогу эту бяку к себе в эдит вставить:)

                                  Не сможешь.

                                  Цитата subsonic @
                                  как сделать, чтоб в определенное количество едитов. можно было вводить только цифры, и стирать кнопкой backspace???

                                  ExpandedWrap disabled
                                    procedure TForm1.Edit1KeyPress(Sender:TObject;var Key:Char);
                                    begin
                                      if not (Key in [#8, '-','0'..'9']) or
                                         (Key = '-') and (Length((Sender as TEdit).Text) <> 0) then
                                        Key:=#0;
                                    end;
                                    Цитата subsonic @
                                    можно было вводить только цифры, и стирать кнопкой backspace???

                                    Просто добавить символ бэкспейса (#8) в число разрешенных
                                    ExpandedWrap disabled
                                      if not (Key in [#8,'-','0'..'9'])


                                    Добавлено
                                    Цитата and85 @
                                    Есть маленькое замечание. Нигде не обрабатывается вставка из буфера винды. Тоесть, если у меня в буфере белиберда 'алдывраывлоарыдлаорывдлаорыва', то нажав Shift+Insert, я смогу эту бяку к себе в эдит вставить:)

                                    P.S. У andrew.virus это похоже учитывается:)

                                    Проще добавить обработчик OnChange, чем городить спец.контрол, да еще и "с нуля" ;)
                                    PS: Кстати виндовый стиль эдита ES_NUMBER также не отслеживает вставку "белиберды" из буфера обмена :(
                                      Backspace - символ #8. Просто допусти и его
                                        Цитата
                                        Просто добавить символ бэкспейса (#8)

                                        а как узнать символы каждой кнопки на клаве?
                                          Цитата subsonic @
                                          а как узнать символы каждой кнопки на клаве?

                                          Поставь брейкпойнт в обработчике, запусти прогу, и смотри, чему равен Key :)
                                            Символы - то, что написано. Плюс #7 - табуляция.
                                            Остальные по кодам идут, это OnKeyUp обычно контролирует. VK_F1 и остальные
                                              Цитата Continental @
                                              Есть какой-нибудь способ, чтобы сократить данный код?

                                              цикл сделать по коллекции ParControl.Controls, где ParControl - контрол на котором лежат Едиты (форма или панель, что там у вас)
                                              ParControl.ControlCount - кол-во дочерних контролов
                                                Цитата Romkin @
                                                Плюс #7 - табуляция

                                                Вообще-то табуляция VK_TAB = #9 ;)
                                                  Цитата leo @
                                                  Вообще-то табуляция VK_TAB = #9

                                                  Ой. Точно. А 7 - это бип :)
                                                    вообще то проще посмотреть в ASCII таблице :)
                                                      Вот, как раз только что делал такую штуку. Подумал-подумал, и решил, что для цифрового поля должны вводиться
                                                      1)Цифры
                                                      2)Backspase
                                                      3)Ну и стрелки назад-вперед, видимо - иначе представляю, как юзверь будет материться, вогнав длинную строку, и поняв, что сделал ошибку.

                                                      И тогда то, что здесь описывалось, будет выглядеть так.

                                                      ExpandedWrap disabled
                                                        unit klavishi;
                                                         
                                                        interface
                                                        procedure klavishi1(var key:char);
                                                        implementation
                                                        procedure klavishi1 (var key:char);
                                                           begin
                                                            case key of
                                                             '0'..'9':;
                                                             chr(8),chr(37),chr(39):;
                                                            else key:=Chr(0);
                                                           end;
                                                        end;
                                                        end.


                                                      До того, чтобы компонент писать, я вот пока не дошел. Но модуль отдельный как раз сделал - подключаешь его, и пишешь в событие поля ввода на OnKeyPress

                                                      ExpandedWrap disabled
                                                        klavishi;
                                                        Цитата inmast @
                                                        chr(8),chr(37),chr(39):;

                                                        А при чем тут chr(37) - знак процента %, и chr(39) - одиночный апостроф '

                                                        Цитата inmast @
                                                        3)Ну и стрелки назад-вперед,

                                                        Стрелки назад-вперед это не символы, а управляющие клавиши. Поэтому в OnKeyPress они не попадают, только в OnKeyDown\OnKeyUp
                                                          Еще вариант до кучи по мотивам темы
                                                          ExpandedWrap disabled
                                                            procedure TForm1.FormCreate(Sender: TObject);
                                                            var J: Integer;
                                                            begin
                                                              for J := 0 to ComponentCount-1 do
                                                                if Components[J] is TEdit then
                                                                  TEdit(Components[J]).OnKeyPress  := klavishi1;
                                                            end;
                                                             
                                                            procedure TForm1.klavishi1(Sender: TObject; var Key: Char);
                                                            begin
                                                              if not (Key in [#8 ,'-', '0'..'9', Chr(VK_DELETE), Chr(VK_LEFT), Chr(VK_UP), Chr(VK_RIGHT), Chr(VK_DOWN)]) then
                                                                Key := #0;
                                                            end;
                                                          Сообщение отредактировано: SourceUser -
                                                            А не проще ли глобально для всех контролов что лежат на форме обрабатывать.
                                                            У формы на которой лежат контролы делаем KeyPreview := True и вешаем обработчик на OnKeyPress

                                                            ExpandedWrap disabled
                                                              procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
                                                              begin
                                                                if not (Key in [#8 ,'-', '0'..'9', Chr(VK_DELETE), Chr(VK_LEFT), Chr(VK_UP), Chr(VK_RIGHT), Chr(VK_DOWN)]) then
                                                                  Key := #0;
                                                              end;


                                                            и не заморачеваемся с перебором класов и т.д.
                                                            Хотя это от ситуации зависит.
                                                              Цитата SourceUser @
                                                              if not (Key in [#8 ,'-', '0'..'9', Chr(VK_DELETE), Chr(VK_LEFT), Chr(VK_UP), Chr(VK_RIGHT), Chr(VK_DOWN)])

                                                              Угу, прежде чем ерунду писать сначала попробовал бы вывести все эти символы VK_.. в едит
                                                              ExpandedWrap disabled
                                                                Etit1.Text:=Chr(VK_DELETE)+Chr(VK_LEFT)+Chr(VK_UP)+Chr(VK_RIGHT)+Chr(VK_DOWN);

                                                              тогда бы сразу увидел что они означают: .%&'(
                                                              Повторяю для непонятливых:
                                                              Цитата leo @
                                                              Стрелки назад-вперед это не символы, а управляющие клавиши. Поэтому в OnKeyPress они не попадают, только в OnKeyDown\OnKeyUp

                                                              а VK_... это не коды символов, а виртуальные коды клавиш клавиатуры
                                                              Сообщение отредактировано: leo -
                                                                Ну да, leo прав ;)
                                                                Ну значит точно, делаем у формы KeyPreview := True и в OnKeyPress ловим тру символы, а в OnKeyDown управляющие клавиши. Вуаля :)
                                                                  Цитата SourceUser @
                                                                  а в OnKeyDown управляющие клавиши. Вуаля

                                                                  А ты опять не прав ;)
                                                                  Зачем вообще ловить управляющие клавиши, если нам не нужно их запрещать ?! По умолчанию они и так разрешены, и ограничение на ввод символов в OnKeyPress на них никак не влияет - зачем тогда вообще что-то ловить в OnKeyDown ?!
                                                                  Сообщение отредактировано: leo -
                                                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                  0 пользователей:


                                                                  Рейтинг@Mail.ru
                                                                  [ Script execution time: 0,0738 ]   [ 16 queries used ]   [ Generated: 17.06.24, 17:29 GMT ]