Перейти к содержанию
Fire Monkey от А до Я
  • 0

Как запретить некоторые символов виртуальной клавиатурой.


Yarik

Вопрос

Нужна помощь. Есть компонент Edit для него выбрана цифровая клавиатура нужно чтобы вводились только цифры и больше ничего.При нажатии на точку, запятую и  ' - '  они отображаются пробовал через  case  of  и с помощью FilterChar , а так же OnChange  ничего не помогло . По событию OnKeyDown хотел узнать значение Key кнопок . На цифровых кнопках это значение равно 0 на всех цифрах. На точке, запятой и ' - ' вообще значение Key не выводится. Цифры же легко фильтруются FilterChar. Подскажите пожалуйста что можно сделать очень надо.

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

В OnKeyDown проверять и менять KeyChar

Key используется только для непечатаемых символов.

Не отслеживаются символы точки,запятой и минуса в onkeydown ни через if ни через case в этом и проблема.Попрабовал выводить параллельно текст первого edit в другой с проверкой и удалением этих символов они все равно печатаются и во втором причём удаляется только точка и то если только после ввода этих символов нажимать на клавишу какой нибудь цифры.
Ссылка на комментарий
  • 0

Приведите код из OnKeyDown. Буквально вчера реализовывал TEdit для беззнаковых/знаковых целых/дробных чисел - никаких проблем не было.

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
  var s:string;
begin
 {  if not (KeyChar in ['1'..'9']) then
     keychar:=#0;         // c цифрой 0 работает она не печатается
                          // с '.' , ',' , '-' не работает

    case KeyChar of       // с '.' , ',' , '-' не работает
      '0'..'9': ;
      else
       KeyChar:=#0;

    end;
     s:=Edit1.Text;
    Edit2.Text:=Edit1.Text;
    if pos('.',s)<>0 then
     begin
       delete(s,pos('.',s),1);
       Edit1.Text:=s;
       Edit2.Text:=s;
     end; }
end;

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
  var s:string;
begin
  {     if not (KeyChar in ['1'..'9']) then    // c цифрой 0 работает она не печатается
            keychar:=#0;                       // с '.' , ',' , '-' не работает

    case KeyChar of                         // с '.' , ',' , '-' не работает
      '0'..'9': ;
      else
       KeyChar:=#0;

    end;  }
     s:=Edit1.Text;                // цифры сразу выводятся и в Edit1.Text и в Edit2.Text
                                   // точки сразу выводятся в Edit1.Text, а удаляться и в Edit2.Text  только после нажатия цифровой клавиши
    Edit2.Text:=Edit1.Text;        // не пойму как  KeyDown и KeyUp реагирует на нажатие не цифровых кнопок
    if pos('.',s)<>0 then
     begin
       delete(s,pos('.',s),1);
       Edit1.Text:=s;
       Edit2.Text:=s;
     end;
end;
Изменено пользователем Yarik
Ссылка на комментарий
  • 0

Код в OnKeyDown у вас полностью закомментирован в {}

Если не обращать внимания на это, тогда:

KeyChar in set - не работает на юникодных версиях, всегда будет возвращать False.

Это же касается CharInSet, к сожалению.

 

Вариант с case...of выглядит корректно, раскомментируйте его и используйте.

OnKeyUp - уберите, он не нужен.

 

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

У него есть некрасивость - он зависит от свойства Tag поля ввода, в остальном - все хорошо :)

 

Использование: подключаете в uses нужной формы или фрейма/своего компонента после модуля FMX.Edit. И все. Для Delphi "ничего" не меняется, все изменения проявляются только в run-time.

Новый Edit начинает фильтровать данные, если выставлена edit.KeyboardType = NumberPad и ориентируется на Tag:

0: беззнаковые целые

1: целые со знаком

2: дробные без знака

3: дробные со знаком.

В алгоритме есть некоторые неточности (можно "извратиться" и поставить не тот символ), но мне хватает.

 

Если это излишне - смотрите реализацию KeyDown

unit uCustomEditForNumbers;

interface

uses
  System.Classes,
  FMX.Types,
  FMX.Edit;

type
  TCustomEditForNumbers = class(FMX.Edit.TEdit)
  protected
    procedure KeyDown(var Key: Word; var KeyChar: WideChar; Shift: TShiftState); override;
  end;

  TEdit = class(TCustomEditForNumbers)
  end;

implementation

uses
  System.SysUtils;

{ TCustomEditForNumbers }

procedure TCustomEditForNumbers.KeyDown(var Key: Word; var KeyChar: WideChar; Shift: TShiftState);
var
  bAllowed: Boolean;
  s: string;
  Ch: WideChar;
begin
  if KeyboardType = TVirtualKeyboardType.NumberPad then
    begin
      case Tag of
        0: // беззнаковые целые
          bAllowed := (KeyChar >= '0') and (KeyChar <= '9');
        1: // знаковые целые. Надо бы проверять и положение каретки.
          begin
            bAllowed := ((KeyChar >= '0') and (KeyChar <= '9')) or //
              ((KeyChar = '-') and (CaretPosition = 0));
          end;
        2:
          begin // беззнаковые Float
            s := Text;
            Ch := TFormatSettings.Create.DecimalSeparator;
            bAllowed := ((KeyChar >= '0') and (KeyChar <= '9')) or //
              ((KeyChar = Ch) and (Pos(Ch, s) = 0));
          end;
        3: // знаковые Float
          begin
            s := Text;
            Ch := TFormatSettings.Create.DecimalSeparator;
            bAllowed := ((KeyChar >= '0') and (KeyChar <= '9')) or //
              ((KeyChar = '-') and (CaretPosition = 0)) or //
              ((KeyChar = Ch) and (Pos(Ch, s) = 0));
          end;
      else
        bAllowed := True;
      end;
      if not bAllowed then
        KeyChar := #0;
    end;

  inherited;
end;

end.
Ссылка на комментарий
  • 0

Код закоментирован просто чтоб показать какие варианты испробовал.

 

KeyChar in set - не работает на юникодных версиях, всегда будет возвращать False.

Как уже писал в комментариях  if not (KeyChar in ['1'..'9']) then   keychar:=#0; , как и просто проверка символа с помощью if работает для цифр. В вашем коде таже проверка символов. Попробовал сейчас

Ch := TFormatSettings.Create.DecimalSeparator;
   if  keychar=ch
    then
     keychar:=#0; все равно не отлавливает ни точку ни запятую

Еще так  сделал

procedure TForm1.Edit1ChangeTracking(Sender: TObject);
var s: string;
begin
    s:=Edit1.Text;
    Edit2.Text:=Edit1.Text;
    if (pos('.',s)<>0) or (pos(',',s)<>0) or (pos(',',s)<>0) or (pos('.',s)<>0) or (pos(',',s)<>0) or (pos('.',s)<>0)
       or (pos('-',s)<>0) or (pos('-',s)<>0) or (pos('-',s)<>0) or (pos('-',s)<>0)or (pos('0',s)<>0) or (pos('0',s)<>0)
       or (pos('0',s)<>0) or (pos('0',s)<>0)then
     begin
       delete(s,pos('.',s),1);
       Edit1.Text:=s;
     end;

end;

повторяющиеся точки и запятые это просто вводил из интереса при русской и английской раскладке клавиатуры откоплилировал для виндовс чтоб побыстрее так вот из всего выражения проверяются только точки , хоть в анг. хоть в русской раскладке. И не какой реакции на остальные символы и даже на ноль :wacko: . Просто хочется разобраться покоя не дает когда что то не понятно. К сожалению недавно перешел на XE7 с Delphi7 очень много изменений. И спасибо за участие буду дальше копать.

Ссылка на комментарий

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...