C++ Builder: задаем ограничение на ввод символов

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

Первое и наиболее распространенное – создание события KeyPress с проверкой на вводимые символы. Например, пропустим буквы «а» и «е». Выглядеть это будет так:

void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)
{
if((Key=='а') || (Key=='е')) // если вводимый символ равен «а» или «е»
Key='\0'; // тогда вводимый символ отсутствует
}

Естественно, такой способ не подойдет, если букв нужно пропустить много или набор допустимых символов заранее строго определен. Например, в текстовое поле можно вводить только цифры. Тогда кусок кода будет иметь такой вид:

void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)
{
char *str = "0123456789"; // задание строки допустимых элементов
if (((int)Key==8) || ((int)Key==13)) return; // разрешение использовать BackSpace и Enter
if (!( AnsiStrScan( str, Key))) // проверка на соответствии вводимого элемента допустимым элементам приведенным в строке
Key = NULL; // если вводимый символ не обнаружен в строке допустимых элементов, значит он отсутствует
}

В этом куске кода мы разрешаем пользователю использовать BackSpace и Enter в нашем текстовом поле (для этого мы используем десятичные значения данных клавиш, для BackSpace это 8, а для Enter’а – 13).

Надеюсь, заметка была вам полезна )))

10 comments on “C++ Builder: задаем ограничение на ввод символов

  1. Когда мне кто-то ответит скорее всего ответ уже будет бесполезено, но все таки…
    Проблема в том что этих самых эдитов у меня аж 6 и для каждого писать как во втором примере… некамельфо. Попытался винести мясо функции наружу что бы потом просто ее вызывать внутри функции кейпрес, не вышло, не допер как вообще такое сделать. То есть вот это у нас в одной функции:

    1
    2
    3
    4
    
    char *str = "0123456789"; 
    if (((int)Key==8) || ((int)Key==13)) return; 
    if (!( AnsiStrScan( str, Key))) 
    Key = NULL;

    А в самом обработчике Edit1KeyPress мы только вызываем эту функцию.
    Еще интересно как сделать так что бы считывало какой-то символ только 1 раз, например только одну запятую при необходимость считать и конвертировать из строки флоат.

    1. Перефразируйте вопрос, потому что я ничего не поняла. Вы можете задать один обработчик для всех своих Эдитов. Это не проблема. Вам нужно их как-то различать? Используйте либо переменные, либо проверку заполненности. Скорее всего, есть и функция для определения источника события, но, навскидку, я ее не назову (
      По поводу считывания одного символа. Вам нужно запретить пользователю вводить две запятые? Или считать только первый символ введенный пользователем?

      1. Едитов много, но обработчик должен быть один для всех. Я непутевый студент и потому не додумался как это сделать.
        В этот обработчик я думал вписать возможность ограничить количество введенных конкретных символов (в эдиты вводятся данные типа флоат, таким способом я пытался ломиком заставить пользователя вписывать значения в правильном формате). То есть мы вводим какой-то символ определенное количество раз, после того как «лимит» введения символа достигнут — обработчик должен запрещать ввод этого символа.
        В целом задача просто сделать так что бы пользователь в те едиты ничего кроме флоат в правильном формате не мог вписать просто физически… Но я так понимаю это будет сложнее и шире одной простой функции и пары проверок.
        Надеюсь достаточно понятно. Вроде бы находил что-то похожее на нужное, но не разобрался и второй раз найти не смог. Вот только у Вас достаточно понятно и просто.

        1. По поводу обработчика:
          вариант 1 — выделяете все эдиты на форме, переходите в Object Inspector -> Events, там выбираете нужное событие — дважды щелкаете в пустом поле и вуаля — у вас один обработчик для всех.
          вариант 2 — создать обработчик для одного эдита, а потом остальным эдитам просто выбирать имеющийся обработчик в разделе событий.

          По поводу маски ввода для чисел: я бы вам посоветовала просто перехватывать ошибку и предлагать пользователю исправить введенное число (т.е. разрешить ввод чисел и «,») — остальное проверять.

          Как вариант, можно, в принципе, проверять наличие запятой во введенной строке и разрешать ввод лишь при ее отсутствии (а в случае, если это единственный символ — ставить перед ним ноль), но это значительно сложнее в плане реализации (в сравнении с просто выбросом окна пользователю) =)

          1. Вот проверку как раз и пробовал, но не смог написать так что бы билдер его правильно прожевал и не сохранил тот код… Х( Обработчик я сдуру сделал для каждго свой просто код вставил одинаковый, не додумался, хоть и знал как можно. Тот курсач(собственно по нему и спрашивал) уже сдал, но надеюсь смогу сделать именно «ломиком», так как прога с курсача вышла такая крутая что мне ее и на диплом доработать предложили. О запятых я простой трай+кеч и сделал кстати, но вот как-то коробит что не вышло сразу как хотел.
            Спасибо за Ваши ответы.

          2. По поводу маски чисел я бы посоветовал бы не мучить пользователя, а использовать TMaskEdit или любой другой компонент, который регулярные выражения понимает. В МаскЭдите есть ряд готовых масок для ввода.

            1. Тут все зависит от задачи. Вашим же текстом: не всегда рационально продуктивно использовать более тяжелый компонент.

    2. Элементарно пишется.
      Надо для всех едитов сделать единственный обработчик.
      А ко всем едитам обращаться, как (Sender as TEdit)

      Есть еще вариант — написать свой компонент в виде пакета.
      Затем его надо добавить в BCB. Тогда его можно будет
      использовать в других программах.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *