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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 3 [Все]   Вниз
  Печать  
Автор Тема: Запрет ввода символов  (Прочитано 88282 раз)
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
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #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
Гость
« Ответ #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 Кб - загружено 919 раз.)
« Последнее редактирование: 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
Гость
« Ответ #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
Гость
« Ответ #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
Гость
« Ответ #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
Гость
« Ответ #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
Гость
« Ответ #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."
zubr
Гость
« Ответ #30 : 10-12-2008 20:16 » 

Джон, OnKeyPress у борланда - это оболочка WM_CHAR
Записан
Джон
просто
Администратор

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

« Ответ #31 : 10-12-2008 20:21 » 

А понятно, тогда всё в порядке. Просто есть ещё WM_KEY - по той все кнопки получаешь.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
RXL
Технический
Администратор

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

WWW
« Ответ #32 : 10-12-2008 21:14 » 

Джон, совершенно верно - именно по тому и нужно делать два обработчика. Как бонус - в OnKeyPress можно обработать VK_ESCAPE для выхода из диалога и 13 - для OK.

Курсорные стрелки в OnKeyPress не попадают - тут только "символы" (backspace тоже имеет определенный код символа, а стрелкам не дали), но они есть в OnKeyDown и OnKeyUp. Эти три обработчика являются аналогами WM_KEYDOWN, WM_CHAR и WM_KEYUP.
Записан

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

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

« Ответ #33 : 11-12-2008 00:11 » 

Ром, ну дык эт решение выстраданное. Ага У мнея по такому принципу построенный едит с семью разными типами работает.

BackSpace - 08
Tab - 09
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
RXL
Технический
Администратор

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

WWW
« Ответ #34 : 11-12-2008 04:31 » 

От предшественников мне достался код, где вводи что хочешь, а потом типа
Код: (C++)
try { n = StrToInt(str); } catch (...) { }
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zubr
Гость
« Ответ #35 : 11-12-2008 07:04 » 

Ну тогда удобнее StrToIntDef использовать.
Все равно считаю, что OnKeyPress - здесь лишнее.
А фишку с позицией курсора можно и в фильтре OnChange реализовать:
Если обнаружился недопустимый символ, то удаляем его и переводим курсор в позицию последнего удаленного символа. Или другой вариант - переводим курсор в конец строки (кстати, так у меня и сделано). Если же символ не удаляется, то SetWindowText не делаем (для VS).
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #36 : 11-12-2008 09:06 » 

zubr, напиши такую реализацию - потестим, проверим. Пока - не верю (с)
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zubr
Гость
« Ответ #37 : 11-12-2008 10:27 » 

Ok. Выкладываю тест. Код:
Код:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    procedure Edit1Change(Sender: TObject);
  private
    { Private declarations }
    procedure SetFloatValue(component:TEdit);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.SetFloatValue(component:TEdit);
var
  s:string;
  i, posCur:Integer;
  IsSep, IsChange: boolean;
begin
 s := component.Text;
 posCur := component.SelStart;
 i:=1;
 IsSep := False;
 IsChange := False;
 While i<=Length(s) do
 begin
  If (not (s[i] in ['0'..'9'])) and (s[i]<>',') and (s[i] <> '-') then
  begin
   Delete(s, i, 1);
   posCur := i-1;
   IsChange := True;
   continue;
  end;
  If (s[i] = '-') and (i <> 1) then
  begin
   Delete(s, i, 1);
   posCur := i-1;
   IsChange := True;
   continue;
  end
  else
  If (s[i] = '0') and (i = 1) then
  begin
   If (Length(s) > 2) and (s[i+1] <> ',') then
   begin
    Delete(s, i, 1);
    posCur := i-1;
    IsChange := True;
    continue;
   end;
  end
  else
  If s[i] = ',' then
  begin
   If IsSep then
   begin
    Delete(s, i, 1);
    posCur := i-1;
    IsChange := True;
    continue;
   end;
   IsSep := True;
  end;
  inc(i);
 end;
 If IsChange then
 begin
  component.Text := s;
  component.SelStart := posCur;
 end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
 SetFloatValue(Sender as TEdit);
end;

end.
Уже понимает минус и несколько запятых.

* Project1.rar (156.2 Кб - загружено 793 раз.)
Записан
Джон
просто
Администратор

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

« Ответ #38 : 11-12-2008 10:31 » 

Кстати да. Я вижу оптимизацию только в выносе фильтра в отдельную ф-ю. Но заморачиваться с позициями курсора...
А если например я просто удалил несколько символов? Как тогда определить позицию курсора по OnChange? Поэтому тоже бы хотелось посмотреть на решение.
Кстати "мой" вариант - экзешник из кода в теме прицеплен. Можно будет сравнить.

зы Упс, сорри опоздал.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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
Пол: Мужской

« Ответ #39 : 11-12-2008 10:39 » 

Ага.

1. Скопировать в буфер обмена: 23456sdf,2345s34

2. Вставить в контрол -> где каретка? Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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
Гость
« Ответ #40 : 11-12-2008 10:47 » 

Джон, но вариант с OnKeyPress от этого не спасет.
Записан
zubr
Гость
« Ответ #41 : 11-12-2008 10:49 » 

Да и потом, а где она (каретка) должна быть, при вставке из буфера обмена?
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #42 : 11-12-2008 10:55 » 

Таки знал, что будет Паскаль... Придется транслировать в понятный вид - не могу "читать" Паскаль.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zubr
Гость
« Ответ #43 : 11-12-2008 10:59 » 

RXL, если у меня будет время, то переведу в C++, но под VS (билдера нет).
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #44 : 11-12-2008 11:06 » 

Да я сам странслирую - просто нужно время и терпение. BCB6 у меня.
Записан

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

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

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

Джон, но вариант с OnKeyPress от этого не спасет.

При этом варианте напрочь отпадает необходимость заботиться о позиции курсора. В моём коде этого управления нет.
Так что помогает.

Да и потом, а где она (каретка) должна быть, при вставке из буфера обмена?

Попробуй без фильтра (или на любом другом контроле, редакторе текстов и тп) и ты увидишь, что каретка ВСЕГДА стот ПОСЛЕ вставленного блока.
Во всяком случае позиция каретки (длинна - 2) не лезет ни в какие ворота.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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
Пол: Мужской

« Ответ #46 : 11-12-2008 11:15 » 

Глянул, код. Классно вам с борлнадовскими контролами. Вы вон объект в качестве параметра получаете со всеми необходимыми полями. Win API так напрямую не прокатит. Всё надо будет ручками делать.
« Последнее редактирование: 11-12-2008 11:17 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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
Гость
« Ответ #47 : 11-12-2008 17:41 » 

Джон, ну если не на чистом API, а к примеру на MFC делать с использованием CString - не намного больше надо ручками делать, имхо.
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #48 : 11-12-2008 19:18 » 

Джон, при вставке все таки нужно знать SelStart и SelLength - если блок текста выделен, то вставка должна заменять его, а не весь текст.

Еще один метод для действительных чисел:

Код: (C++)
//---------------------------------------------------------------------------
bool __fastcall TfrmInstallationEdit::testRealString(AnsiString str)
{
    return (str.Length() ? !regexec(&re_real, str.c_str(), RE_MATCHES_MAX, re_matches, 0) : true);
}
//---------------------------------------------------------------------------
void __fastcall TfrmInstallationEdit::dfREALKeyPress(TObject *Sender, char &Key)
{
    TEdit *ed = dynamic_cast<TEdit*>(Sender);

    if (Key == VK_ESCAPE)
        pbCancel->Click();
    else if (Key == VK_BACK)
        return;
    else
    {
        AnsiString tmp;

        if (ed->SelLength)
        {
            int beg = ed->SelStart;
            int end = beg + ed->SelLength;

            tmp = ed->Text.SubString(0, beg) + Key + ed->Text.SubString(end, ed->Text.Length() - end);
        }
        else
            tmp = ed->Text + Key;

        if (testRealString(tmp))
            return;
    }

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

    if (!testRealString(ed->Text))
        ed->Text = "";
}

Здесь для проверки использую регулярные выражения - так проще и удобнее контролировать формат и состав строки. Подготовка выражения к использованию простая:

Всякие подсобные переменные:
Код: (C++)
    regex_t re_real;
    regmatch_t re_matches[RE_MATCHES_MAX];

Компиляция:
Код: (C++)
    char *re_real_str = "^[0-9]{0,6}(?:\\.[0-9]{0,2})?$";

    if (regcomp(&re_real, re_real_str, 0))
    {
        ShowMessage("Error rised on regexp compile.");
        Close();
    }

RE_MATCHES_MAX - макрос.
« Последнее редактирование: 11-12-2008 19:24 от RXL » Записан

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

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

« Ответ #49 : 11-12-2008 19:37 » 

zubr, ошибаешься и CString тут совершенно не при чём. Посмотри мою ф-ю, она не получает параметра. Те мне надо самому забирать текст из окошка, опрашивать позицию курсора, устанавливать её и тд. И это всё вызывая сторонние ф-ции.

Ром, ошибаешься. По OnChange ты получаешь ВЕСЬ текст контрола, уже изменённый. Куда именно была сделана вставка и как она была сделана ты уже никогда не узнаешь. Контрол только сообщил тебе, что дескать моё содержимое изменили, теперь делайте со мной что хотите. Логика фильтра сработает и в этом случае

например было 01290, потом между 2 и 9 вставили 345абвгд678 получилось 012345абвгд67890 после фильтра осталось 01234567890. Только вот куда теперь курсор ставить? Ага

По хорошему надо отлавливать операции ДО изменения контрола. Но это уже надо смотреть, об такой наворот оплатят?

зы ЭТо ессно про виндовский системны Eidt, я знаю что у борланда свой 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."
RXL
Технический
Администратор

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

WWW
« Ответ #50 : 11-12-2008 19:54 » 

Джон, да - ошибся - в нужно OnKeyPress, но не в onChange...
Записан

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

ru
Offline Offline

« Ответ #51 : 15-12-2008 15:02 » 

Большое вам всем спасибо. Но я сделала так.

procedure TForm11.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (key in ['0'..'9',',','-',#8]) then
key:=#3;
end;

А затем в событиях каждого TEdit поменяла цифру на 1.
Записан
DrGluck
Постоялец

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

« Ответ #52 : 16-12-2008 13:59 » 

Я так понимаю, что проблема была только в том, чтоб разрешить юзеру вводить числа, а все остальное не вводить? И все это для 13 контролов?

Предложение:

1. У всех контролов устанавливаем один обработчик OnKeyPress. Там пропускаем только символы '0'..'9'  ','  '-'.
2. Обрабатываем OnChange. Тоже для всех едитов.
3. Дальше with (Sender as TEdit) do begin... (это по поводу не писать код 13 раз, вообще странный вопрос был про это. учите матчасть чтоли)
4. А дальше есть волшебная функция Val. Она позволяет преобразовывать String в Integer, Real (или как они там у вас на дельфях называюца), а если строка не правильная, то нам об этом сообщат в коде ответа. Если попробовать преобразовать одну строку в разные типы, то можно узнать какого типа данные вводил юзер. И не надо самому писать жуткие фильтры.
Более того, можно запоминать для каждой строки предыдущее перед OnChange состояние, и если Val выдает ошибку для всех преобразований, то тогда возвращать Edit.Text в предыдущее состояние.
(Есть правда одно НО. В случае отката на предыдущее значение тоже вызывается OnChange со всеми вытекающими последствиями, т.е. опять будут проверки).

з.ы. Давно не лазил на дельфовый форум, а тут опять зашел посмотреть. Ничего не меняется. Дельфисты по прежнему спрашивают друг у друга как делать элементарные вещи. "Как удалить запись в DBGride", "Как запретить ввод символов в едит", ну и конечно "Как сделать круглую кнопку".

з.з.ы. А вот еще перл "Помогите, пожалуйста, решить задачу с закладками".

RTFM, мать вашу!
Записан

Good user - dead user
zubr
Гость
« Ответ #53 : 17-12-2008 05:04 » 

DrGluck,
1. Не надо повторять то что уже было сказано другими. Если ты обратишь внимание, то универсальный код для всех эдитов был указан в предыдущих постах.
2. Твой вариант не избавляет от возможности вставки из буфера обмена практически любого текста.
3. Твой вариант не избавляет от возможности ввода нескольких минусов, запятых, а также вставки их в любом месте текста, что есть криво. Все эти моменты решаются с помощью фильтра. И причем здесь функция Val? Она только преобразует текст в число аналогично StrToInt, StrToIntDef, StrToFloat, StrToFloatDef
Записан
DrGluck
Постоялец

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

« Ответ #54 : 17-12-2008 06:20 » 

1. Согласен. Не буду.
2. Из буфера вставить можно, но при этом срабатывает OnChange. И в нем мы можем проверить то, что вставилось. И, в случае неудачи, заменить на предыдущее значение (например).
3. Функция Val позволяет легко проверить строку, которая находится в Edit.Text (т.е. не нужно самому разбираться в строке). И, если проверка не проходит, то таки-да уже можно вернуть старое значение.
4. И вообще нафига было замарачиваца. Тока что проверил виндовый калькулятор. Если в него скопипастить строку символов, то он просто игнорирует это и подставляет значение 0. Что я и предложил в своем посте.
5. Реально проблема не стоила такого длинного обсуждения.
6. В связи с 5 извиняюсь что сюда отписался.
Записан

Good user - dead user
Джон
просто
Администратор

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

« Ответ #55 : 17-12-2008 11:32 » 

DrGluck, проблема обсуждалась длинно, потому что дельфийцев небыло, а С++, согласись, не одно и тоже что Паскаль. Это раз. Два - с самого начала не было понятно, что нужно было сделать фильтр. Хотя RuNTiME, судя по всему обладая незаурядными телепатическими способностями, дал практически правильный ответ на половину вопроса.

Ну и последнее, ИМХО ты перегибаешь палку в своём праведном гневе. Конечно, можно перелопатить кучу мануалов, учебников и примеров кода, чтобы прийти к нужному решению, но в данном случае неопытноый начинающий программист, девушка, студентка, спортсменка и наконец просто красавица, может позволить себе спросить более опытных товарищей об оптимальном решении, чтобы сэкономить время.
« Последнее редактирование: 17-12-2008 11:34 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
MixailK
Гость
« Ответ #56 : 19-12-2008 05:47 » 

Я так понял, что проблема состоит в том, что при неправильном вводе действительного числа возникает исключение EConvertError. Стася решила подойти к этой проблеме запретом ввода в Edit всех символов кроме цифр, минуса и запятой. А ведь у многих пользователей разделителем целой и дробной части чаще стоит "точка", а не "запятая". Я предлагаю отлавливать возникновение исключения EConvertError и сообщать об этом пользователю. Например так:
var r:real;
begin
 try
  r:=StrToFloat(Edit1.Text);
 except
  on EConvertError do begin
                                      ShowMessage('Вы ввели не действительное число! Повторите ввод.');
                                      exit;
                                   end;
 end;
end;
И если подвесить этот кусочек на событие onExit у Edit'а, то никаких проблем быть не должно. И не надо городить огород с запретом ввода, пользователь все равно будет вводить чушь всякую в Edit, а запрещать ему это делать не есть хорошо. Проще, на мой взгляд, ткнуть его носом в то, что он вводит... Улыбаюсь
Записан
DrGluck
Постоялец

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

« Ответ #57 : 19-12-2008 06:19 » 

MixailK
Я, кстати, всегда так и делаю. Потому и не имею проблем с тем, что юзер может чегото скопипастить левое.
Хотя запрет ввода в OnKeyPress тоже не помешает.

з.ы. Не забываем, что по умолчанию разделителем является '.'  Юзаем DecimalSeparator если нужно использовать в качестве разделителя другой знак.
Записан

Good user - dead user
RXL
Технический
Администратор

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

WWW
« Ответ #58 : 19-12-2008 06:38 » 

Фильтрация ввода, прежде всего - вопрос удобства и надежности GUI и простоты дальнейшей обработки. А еще это просто красиво. Вполне достаточно создать такой контрол один раз, оформить в пакет и пользоваться, не думая о сложностях ввода.

Кстати, разделитель - хорошая мысль - стоит ввод "." и "," преобразовать в DecimalSeparator - удобнее будет при вводе с numpad при включенной русской раскладке.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zubr
Гость
« Ответ #59 : 19-12-2008 07:19 » 

DecimalSeparator - не совсем красивое решение, так как это глобальная переменная. То есть устанавливая DecimalSeparator в какойто процедуре проекта, мы устанавливаем его для всего проекта. Пример казусной ситуации: мы в проекте установили для ввода вещественных чисел в качестве разделителя ',', а какая то процедура проекта получает входные данные из какого то файла, где в качестве разделителя используется '.', причем обработка входных данных и ввода пользователя производится в разных потоках - естественно вывалится исключение. Выход из данной ситуации:
1 У входных данных (как введенных пользователем, так и полученных из файла) проверяем разделитель, к примеру с помощью функции LastDelimiter
2. В зависимости от используемого разделителя, перед вызовом функции StrToFloat делаем так:
Код:
var
  fs: TFormatSettings;
  ds: char;

begin
 ds := //какой то код проверяющий используемый сепаратор
 fs.DecimalSeparator := ds;
 StrToFloat(Edit1.Text, fs);
end;
Тогда даже если обработка будет вестись в разных потоках, казуса не произойдет.
Записан
MixailK
Гость
« Ответ #60 : 19-12-2008 13:41 » 

Все гениальное просто. Не надо никаких сложных обработчиков. Стася я так понимаю студентка, и нужно её это что бы преподу сказать, типа да проверка есть на неправильный ввод и все. Во-вторых, хорошо когда пользователь может позвонить программеру и спросить почему у него запятая не вводиться в Edit, а если не может? Что делать пользователю? Хелпы наверняка нет к программке этой. А если много пользователей пользуются программой? и каждый(ая) звонит программеру и спрашивает: "что вы такое наделали?" " Ваша программа не работает", крики, истерики и т.д. А так все просто - ткнули пользователя носом и все... Можно, правда еще вытащить разделитель из системных настроек и его в сообщении указать.
Записан
Sla
Команда клуба

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

WWW
« Ответ #61 : 19-12-2008 13:44 » 

MixailK, эх, а к вечеру у поддержки еле язык ворочается
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

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

WWW
« Ответ #62 : 19-12-2008 14:01 » 

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

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
MixailK
Гость
« Ответ #63 : 22-12-2008 11:08 » 

Уговорили... Задача все равно решается намного проще: Элемент TMaskEdit(с закладки Additional) свойство EditMask делаем -99999,99;1;0. Количество "9" можно варьировать как до, так и после запятой(точки) в зависимости от задачи. Удачи всем.
Записан
MixailK
Гость
« Ответ #64 : 22-12-2008 11:18 » 

Сорри. Маленько обшибся. Правильно так #99999,99;1;0. А если еще после этого поставить проверку, как я раньше писал то вопрос закрыт окончательно.
Записан
zubr
Гость
« Ответ #65 : 22-12-2008 15:48 » 

MixailK,  и что нулями все первые ненужные разряды забивать? Криво это, имхо. Данный компонент удобен только в случае жесткого диапазона чисел по разрядности, а вообще он более удобен для ввода номеров телефона и т. п.
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #66 : 22-12-2008 17:49 » 

Цитата
EditText is the value of the text for the edit control after it is formatted using the EditMask. Before the text is fully entered into a masked edit control, the EditText includes a blank character for each unentered character. As characters are entered, the blank characters in the EditText are replaced by the values that the user types.

Не вижу, чтобы было написано, что надо забивать до упора. Кстати, формат EditMask в доке отсутствует...
Записан

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

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

« Ответ #67 : 22-12-2008 17:59 » 

RXL, я добрался до Delphi и попробовал из любопытства TMaskEdit, после того, как сам про него вспомнил. zubr был прав, неудобная эта штука для подобного ввода числа.
Записан
zubr
Гость
« Ответ #68 : 22-12-2008 19:01 » 

RXL, формат числа будет всегда постоянный, определенный маской, то есть к примеру 5 символов до запятой и 2 после, остальное будут нули, или какие нить другие символы определенные маской.
Не знаю как в билдере, а в Delphi данный формат описывается:
Цитата
Represents the mask that validates and formats user input.

Unit

MaskUtils or QMask

Delphi syntax:

type TEditMask = type string;

C++ syntax:

typedef AnsiString TEditMask

Description

TEditMask is a string that consists of three fields with semicolons separating them. The first part of the mask is the mask itself. The second part is the character that determines whether the literal characters of a mask are saved as part of the data. The third part of the mask is the character used to represent unentered characters in the mask.

These are the special characters used in the first field of the mask:

Character   Meaning in mask

 !   If a ! character appears in the mask, optional characters are represented in the text as leading blanks. If a ! character is not present, optional characters are represented in the text as trailing blanks.
 >   If a > character appears in the mask, all characters that follow are in uppercase until the end of the mask or until a < character is encountered.
 <   If a < character appears in the mask, all characters that follow are in lowercase until the end of the mask or until a > character is encountered.

 <>   If these two characters appear together in a mask, no case checking is done and the data is formatted with the case the user uses to enter the data.
\   The character that follows a \ character is a literal character. Use this character to use any of the mask special characters as a literal in the data.
 L   The L character requires an alphabetic character only in this position. For the US, this is A-Z, a-z.
 l   The l character permits only an alphabetic character in this position, but doesn't require it.

A   The A character requires an alphanumeric character only in this position. For the US, this is A-Z, a-z, 0-9.
 a   The a character permits an alphanumeric character in this position, but doesn't require it.
C   The C character requires an arbitrary character in this position.
 c   The c character permits an arbitrary character in this position, but doesn't require it.
 0   The 0 character requires a numeric character only in this position.
 9   The 9 character permits a numeric character in this position, but doesn't require it.

#   The # character permits a numeric character or a plus or minus sign in this position, but doesn't require it.
:   The : character is used to separate hours, minutes, and seconds in times. If the character that separates hours, minutes, and seconds is different in the regional settings of the Control Panel utility on your computer system, that character is used instead.
 /   The / character is used to separate months, days, and years in dates. If the character that separates months, days, and years is different in the regional settings of the Control Panel utility on your computer system, that character is used instead.

 ;   The ; character is used to separate the three fields of the mask.
 _   The _ character automatically inserts spaces into the text. When the user enters characters in the field, the cursor skips the _ character.

Any character that does not appear in the preceding table can appear in the first part of the mask as a literal character. Literal characters must be matched exactly in the edit control. They are inserted automatically, and the cursor skips over them during editing. The special mask characters can also appear as literal characters if preceded by a backslash character (\).

The second field of the mask is a single character that indicates whether literal characters from the mask should be included as part of the text for the edit control. For example, the mask for a telephone number with area code could be the following string:

(000)_000-0000;0;*

The 0 in the second field indicates that the Text property for the edit control would consist of the 10 digits that were entered, rather than the 14 characters that make up the telephone number as it appears in the edit control.

A 0 in the second field indicates that literals should not be included, any other character indicates that they should be included. The character that indicates whether literals should be included can be changed in the Edit Mask property editor, or programmatically by changing the MaskNoSave typed constant.

The third field of the mask is the character that appears in the edit control for blanks (characters that have not been entered). By default, this is the same as the character that stands for literal spaces. The two characters appear the same in an edit window. However, when a user edits the text in a masked edit control, the cursor selects each blank character in turn, and skips over the space character.

Note:   When working with multibyte character sets, each special mask character represents a single byte. To specify multi-byte characters using the L, l, A, a, C, or c specifiers, the mask characters must be duplicated as well. For example, LL would represent two single-byte alphabetic characters or a one double-byte character. Only single-byte literal characters are supported.
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #69 : 22-12-2008 19:50 » 

У меня в BCB6 в хелпах нету этого... Жаль

Уже много лет назад подсел на PCRE и с тех пор все более-менее сложное проверяю им. Как раз все это добро есть в BCB6 (а наверняка и раньше), а значит и в Delphi.
« Последнее редактирование: 22-12-2008 20:01 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
MixailK
Гость
« Ответ #70 : 23-12-2008 06:13 » 

Во-первых, порядок цифр, как правило, известен. Для "не корявого" решения этой проблемы, надо писать свой компонент с родителем Tedit, в его обработчике наводить красоту для ввода. Но из-за нескольких нулей в начале числа делать это не рационально. Не стоит изобретать велосипед. Если этой программой будут постоянно пользоваться, то на второй день пользователь будет на автомате вводить столько нулей сколько надо, а через 2 недели будет уверен, что так и должно быть и это очень удобно.
Ранее я писал о исходной постановке задачи и о том, что Вы раздули из мухи слона, в связи с этим любителей(профессионалов) Си просьба выложить код для Си Билдера, в доказательства того, что в нем это делать проще и Вы там профи(не хочу никого обидеть).
Записан
sss
Специалист

ru
Offline Offline

« Ответ #71 : 23-12-2008 07:17 » 

MixailK, я считаю себя "молодым специалистом" в BCB.... Мое мнение - для не корявого решения не надо лезть во ввод данных (есть ведь ошибки связанные не только с нажатием клавиш, напр.переполнение), а обрабатывать введенные данные и уже по ним выдавать отчеты..

Код:
void __fastcall TULongOptionsForm::BitBtn1Click(TObject *Sender)
{
  try
  {
    ActiveControl = edtLeftVal;
    uleft = StrToUlongA( edtLeftVal->Text.c_str());
   
    ActiveControl = edtRightVal;
    uright = StrToUlongA( edtRightVal->Text.c_str());

    if ( uright < uleft)
    {
      if ( SHOWYES( TEXT("Значение фильтра слева больше значения справа. Обменять ?"), NULL, Handle))
      {
        edtRightVal->Text = StrFromUlongA( uleft);
        edtLeftVal->Text = StrFromUlongA( uright);
      }
      else
      if ( SHOWYES(TEXT("Все равно продолжить ?"), NULL, Handle) == FALSE)
      {
         ActiveControl = edtLeftVal;
        return;
      }
    }

    ModalResult = mrOk;
  }
  catch( EExcept* e)
  {
    SHOWTHROW( e->GetReport( m_eReport), NULL, Handle);
    e->Release();
  }
}
Записан

while (8==8)
zubr
Гость
« Ответ #72 : 23-12-2008 07:23 » 

MixailK
1. Подобный компонент пишется один раз и за 30 минут и в дальнейшем он используется для всех остальных проектов.
2. Для программистов, использующих VS MFC, вообще данная проблема не стоит, так как там в классе CEdit данные вопросы уже решены. Для билдера же то же самое, что и для Delphi.
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #73 : 23-12-2008 08:07 » 

MixailK, заставлять пользователя делать ненужные вещи - значит не уважать его. Представь тебе подобное заявление от конструктора велосипедов: "отсутствие седла - мелочь, к которой пользователь должен привыкнуть через два дня - я в этом уверен". И я не утрирую. Есть сделанное для людей (даже термин в сети есть - СДЛ) и есть все остальное (в GUI все остальное - некачественные поделки).
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: 1 2 3 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines