Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2 3  Все   Вниз
  Печать  
Автор Тема: Запрет ввода символов  (Прочитано 60740 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Стася
Постоялец

ru
Offline Offline

« : 09-12-2008 11:38 » 

У меня на форме располагаются 13 TEdit. Как запретить для них всех ввод с клавиатуры символов?
Записан
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 09-12-2008 12:30 » 

Стася,  тебе нужно создать обработчик события на нажатие кнопок для каждого едитбокса к примеру:
Код:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
   Shift: TShiftState);
begin
    if(Key = Ord('A')) then
        Key = 0;
end;
В Edit1 больше не будет вводиться большая буква 'A'

P.S. Если тебе надо проверять сразу несколько символов, то можно их поместить в множество.
Записан

Любимая игрушка - debugger ...
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 09-12-2008 12:34 » 

Я, конечно, тоже не экстрасенс Улыбаюсь но думаю, тут скорее речь про то, как сделать Edit-ы неактивными для ввода данных. Тогда что-то вроде
Код:
TEdit edit;
edit.enabled := false;
или, если изначально и должны быть неактивными, соответствующее свойство поправить в редакторе свойств.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 09-12-2008 12:42 » 

Согласен с Вадом, может лучше посмотреть в сторону свойства read only? Отлавливать нажатия кнопки это... Даже не знаю как это назвать. А если это альтернативный ввод?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Стася
Постоялец

ru
Offline Offline

« Ответ #4 : 09-12-2008 13:12 » 

Я в эти поля заношу числа. А запрет нужен на остальные символы кроме запятой. Я сначала хотела сделать через KeyPress,но 13 раз писать это для каждого поля...Хочется покороче.
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #5 : 09-12-2008 13:12 » 

Джон, экранная клавиатура Ага
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 09-12-2008 13:21 » 

Стася, для целых подошёл бы стиль ES_NUMBER (или как он там в дельфи называется), а вот для дробных не знаю.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 09-12-2008 13:28 » 

Чёт совсем плохие времена настали. Сиплюснутые в паскале помогают.

Стася, покороче можно сделать. В данном случае фильтры бывают двух типов. Одни запрещают определённые объекты, другие пропускают определёные объекты. В твоём случае нужен второй фильтр, который будет пропускать только символы цифр и запятую (тк их гораздо меньше, чем остальных). Этот фильтр надо сделать в родительском объекте, а твои 13 наследовать от него. Проблема только в том, что я не знаю как это сделать в паскале.
« Последнее редактирование: 09-12-2008 13:31 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 09-12-2008 13:30 » 

Джон, экранная клавиатура Ага

Макс, да что угодно. От paste до SetWindowText. Ага

ps кста, Стася, тебе надо подумать и об этом. А что если я кликну правой кнопочкой и вставлю текст из буфера?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Finch
Спокойный
Администратор

il
Online Online
Пол: Мужской
Пролетал мимо


« Ответ #9 : 09-12-2008 13:34 » 

Я не знаю, какое положение сейчас в Дельфи. Но в других фрейворках данная проблема решается с помошью регулярных выражений.  Которые задаются контролу при иницилизации, и контрол уже сам следит за корректностью данных в нем. Если есть такая возможность, то просто надо глянуть на правила регулярок, чтобы можно было точно составить строку.
« Последнее редактирование: 09-12-2008 13:37 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Стася
Постоялец

ru
Offline Offline

« Ответ #10 : 09-12-2008 13:36 » 

А мне в Delphi надо,Джон)А насчет правой кнопочки, с нас такого не спрашивают)
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 09-12-2008 13:42 » 

Тут вот подсказывают, что есть в дельфе такое TMaskEdit - там можно задать маску для ввода.
Записан
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 09-12-2008 13:53 » 

Проще всего сделать так:
Код:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
   Shift: TShiftState);
var
    filter: set of '0'..'9', '.';
begin
    if( not (key in filter) ) then
        key = 0;
end;
И на сколько я помню делфи, в диспетчере свойств можно назначать один обработчик
всем компонентам одного типа. Вот там указываешь в свойствах каждого едитбокса этот обработчик и все Улыбаюсь
Записан

Любимая игрушка - debugger ...
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #13 : 09-12-2008 13:57 » 

А насчет правой кнопочки, с нас такого не спрашивают)

Дык жисть спросит, поздно будет. Если делать, то делать хорошо, или не делать совсем. Третьего не дано. Тем более это не так сложно. Просто отловить OnPaste и проверить содержимое. Две строчки кода.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Стася
Постоялец

ru
Offline Offline

« Ответ #14 : 09-12-2008 16:06 » 

А можно поподробнее,Джон?
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #15 : 09-12-2008 17:04 » 

Все гораздо проще для данной задачи: Edit1.ReadOnly := True; или установить данное свойство в инспекторе объектов.
Чтобы автоматизировать работу, можно сделать так:
Код:
For i:=0 to Form1.ComponentCount-1 do
If Form1.Components[i] is TEdit then
(Form1.Components[i] as TEdit).ReadOnly := True;
Данный код установит ReadOnly для всех компонентов TEdit на форме.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #16 : 09-12-2008 17:07 » 

А можно поподробнее,Джон?


Стася, если ты программируешь на дельфях (по языку - это тот же паскаль), то знаешь, что в нем есть ООП структуры.
Ты соврешенно справедливо считаешь, что 13 раз писать один и тот же код это глупость. Код должен быть написан только один раз - в данном случае в родительском классе. В MFC я делаю так (тебе надо будет это спроецировать на Дельфи, ибо и там это возможно, а иначе зачем он ваще нужен).

1. Создаю свой контрол, который наследую от CEdit. Например CMyValidEdit.

2. В него встраиваю обработчики сообщения WM_CHAR (ведь нас интересуют только значки, управляющие кнопки работают как раньше) и нотификации самого контрола - EN_CHANGE, ей виндовский контрол "сигнализирует" об изменении своего содержания.

3. Создаю нужное количество объектов этого класса.

Всё.

Подробней:
логика - если это одна из цифр или запятая - разрешаем базовому (родительскому) классу обработать это сообщение
исключение для кнопки Back Space - символ с кодом 8
вот так это выглядит в коде С++:

Код:
void CMyValidEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if( (nChar>='0') && (nChar<='9')  || (nChar==',') || (nChar==VK_BACK) )  CEdit::OnChar(nChar, nRepCnt, nFlags);
}

Первая строчка, которая выполняет полностью твоё задание. Но мы хотим большего.
Все нажатия кнопок мы отловили, теперь осталось только отловить изменения содержимого помимо кнопок.

Я написал немного развёрнуто, чтобы была видна схожесть при проверки условия, или как ты уже догадалась - фильтра.
Ведь его можно сделать зависимым от стилей твоего контрола и таким образом например отсеивать шестнадцатиричные цифры, или только буквы и вобще всё что будет нужно.
Код:
void CMyValidEdit::OnEnChange()
{
CString st;
GetWindowText(st); // получаем содержимое окна

for(int i=0; i<st.GetLength(); i++)
{
                // в цикле проверяем каждый символ содержимого
char nChar = st.GetAt(i);
if((nChar>='0') && (nChar<='9')  || (nChar==','))
{
                         // удовлетворяет нашему фильтру - продолжаем
}
else
{
                        // строчка ещё не закончилась, но мы уже встретили неправильный символ
                        // я просто обнулил содержимого окна и завершил обработку - дальше меня не интересует
SetWindowText(_T(""));
return;

                        // а ещё можно показать ошибку в виде сообщения или ToolTip
                        // или просто удалить этот символ и продолжить цикл, короче всё ограничино только полётом фантазии
}
}
}

Вот и всё. Потом я на форму положил 4 контрола и создал 4 объекта типа CMyValidEdit, связанные с ресурсами на форме и всё.

   CMyValidEdit m_myEdit1;
   CMyValidEdit m_myEdit2;
   CMyValidEdit m_myEdit3;
   CMyValidEdit m_myEdit4;

Но это уже особенности среды программирования.


* TestValidEdit.zip (80.74 Кб - загружено 659 раз.)
« Последнее редактирование: 09-12-2008 17:14 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #17 : 09-12-2008 17:09 » 

zubr, не эт мы уже проходили. Не годится. Ей нужно отфильтровать цифры и запятую.

Я в эти поля заношу числа. А запрет нужен на остальные символы кроме запятой.

Помоги перевести сишный код в паскаль. Я ихние объекты не знаю.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #18 : 09-12-2008 17:39 » 

Вот мой вариант решения:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    .......
    Edit13: TEdit;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure FloatEditOnChange(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//функция фильтрующая текст
function FloatValue(data:string):string;
var
  i:Integer;
  s:string;
begin
 s:=data;
 i:=1;
 While i<=Length(s) do
 begin
  If (not (s[i] in ['0'..'9'])) and (s[i]<>',') then
  begin
   Delete(s, i, 1);
   continue;
  end;
  inc(i);
 end;
 Result:=s;
end;

//общий обработчик OnChange
procedure TForm1.FloatEditOnChange(Sender: TObject);
begin
 TEdit(Sender).Text:=FloatValue(TEdit(Sender).Text);
 TEdit(Sender).SelStart:=Length(TEdit(Sender).Text);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i:Integer;
begin
 //устанавливаем для всех эдитов обработчик OnChange
 For i:= 0 to  ComponentCount-1 do
 If Components[i] is TEdit then
 TEdit(Components[i]).OnChange := FloatEditOnChange;
end;

end.
« Последнее редактирование: 09-12-2008 17:41 от zubr » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 09-12-2008 17:49 » 

zubr, и минус ещё в начале может быть Улыбаюсь Ну как отрицательные вводить захотят? Кстати, а TMaskEdit не подойдёт? Или там невозможно запятую задать, чтобы была опционально?
Кстати, не будет проблем с двумя запятыми? Улыбаюсь
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #20 : 09-12-2008 17:52 » 

А нельзя просто сделать свой тип данных наследованный от TEdit?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #21 : 09-12-2008 17:53 » 

Вад, про минус в ТЗ ничего не стоит. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #22 : 09-12-2008 18:09 » 

Цитата
zubr, и минус ещё в начале может быть Улыбаюсь Ну как отрицательные вводить захотят? Кстати, а TMaskEdit не подойдёт? Или там невозможно запятую задать, чтобы была опционально?
Кстати, не будет проблем с двумя запятыми?
Может быть и 2 запятых и минус не учтен. Ну принцип я показал, а остальное на доработку автору темы. Насчет MaskEdit - эта штука не совсем удобна. Там надо задавать количество символов до запятой, после запятой. А если числа разные будут по разрядности.
Цитата
А нельзя просто сделать свой тип данных наследованный от TEdit?
Можно, почему нет. Ведь Delphi - объектно ориентированный язык, со всеми основниыми (инкапсулирование, наследование и т. п.) примочками. Правда множественное наследование, в отличие от C++ отсутствует.

А вообще можно использовать TSpinEdit вместо TEdit, переделав его для работы с вещественными числами. Я как-то переделывал, где то в архиве у меня лежит собственный компонентик TSpinEditReal.

Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 09-12-2008 18:14 » 

zubr, ну, насчёт разрядности - это нужно максимальную разрядность знать: как я понял, в TMaskEdit есть маска для как для обязательного наличия символа цифры, так и для опционального ('0' и '9', кажется) - разве что запятая должна обязательно быть - это смущает...
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #24 : 09-12-2008 18:27 » 

Вад, например Delphi- функция StrToFloat (перевод строки в вещественное число) выдаст ошибку в случае '00123,567'
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #25 : 09-12-2008 23:32 » 

zubr, да я это и имел ввиду. Паскаль ОО уже с версии 5.5 если не вру конечно.  Просто я не знал, об дельфийские объекты способны размножаться, есть ли у них, например, виртуальные ф-ции.

Кстати .NET тоже страдает отсутствием подобного стиля у Edit, так что серьёзная разработка контрола не помешает.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #26 : 10-12-2008 04:46 » 

Ну Net программеры из борланда писали Улыбаюсь
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #27 : 10-12-2008 17:21 » 

Решал аналогичную задачу в BCB6: нужно фильтровать ввод в OnKeyPress (разрешить ввод только символов '0'..'9' и символа забоя VK_BACK) и вставку в OnChange, т.к. данные могут быть вставлены из буфера обмена.

Реализация для BCB:
Код: (C++)
//---------------------------------------------------------------------------
void __fastcall TfrmInstallationEdit::dfNUMKeyPress(TObject *Sender, char &Key)
{
    if (Key == VK_ESCAPE)
        pbCancel->Click();
    else if (Key != VK_BACK && (Key < '0' || Key > '9'))
        ;
    else
        return;

    Key = 0;
}
//---------------------------------------------------------------------------
void __fastcall TfrmInstallationEdit::dfNUMChange(TObject *Sender)
{
    TEdit *ed = dynamic_cast<TEdit*>(Sender);

    for (int i = ed->Text.Length(); i; i--)
        if (ed->Text.c_str()[i - 1] < '0' || ed->Text.c_str()[i - 1] > '9')
            ed->Text.Delete(i, 1);
}
//---------------------------------------------------------------------------
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #28 : 10-12-2008 18:50 » 

RXL, а зачем OnKeyPress обрабатывать, когда все равно OnChange фильтруем? Согласен, с точки зрения эффективности работы приложения, есть смысл не пропускать ненужные символы на уровне KeyPress, но данная эффективность имеет смысл при больших вводимых текстах, здесь же речь о вводе чисел.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #29 : 10-12-2008 19:48 » 

zubr, не совсем так. При OnChange ты получаешь полный буфер и не знаешь в каком месте произошло изменение. Но после удаления, тебе необходимо восстановить позицию курсора. Но ты не знаешь где она была. Это операция ненужная и незаметная при вставке большого текста, доставит очень много неприятности при вводе текста с клавы. Поэтому лучше заткнуть.

Кстати всё порываюсь спросить, а почему вы реагируете на OnKeyPress? Ведь тогда придётся ещё разрешать как минимум стрелочки перемещения курсора. Для символов винда посылает WM_CHAR. Или у Борланда что-то не так?

зы Стася, ты хоть разобралась со своей проблемой? Или мы тебя грузанули?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1] 2 3  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines