Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> В программе не работает функция 
:(
    Опции темы
sashPav
Дата 8.7.2010, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 8.7.2010

Репутация: нет
Всего: нет



Пожалуйста помогите разобраться.

Ниже приведен код программы
 Следующая программа вычисляет стоимость поездки на дачу. Исходными данными для программы являются: расстояние, цена одного литра бензина и потребление бензина на 100 км пути. Для ввода исходных данных применяются поля Edit1, Edit2 и Edit3. Функции обработки события OnKeyPress
используют функцию IsFloat для фильтрации вводимых в эти поля символов, во время работы программы в полях ввода отображаются только допустимые символы.
Диалоговое окно:
user posted image

Вопрос:программа успешно компилируется, но функция  для фильтрации вводимых в поля символов IsFloat не работает, т.е. кроме  цифр, можно набрать и буквы. Как заставить работать функцию?

Работаю в Delphi® 2010

Код

unit fazenda;

interface

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

type
  TForm1 = class(TForm)
    CheckBox1: TCheckBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
    procedure Edit2KeyPress(Sender: TObject; var Key: Char);
    procedure Edit3KeyPress(Sender: TObject; var Key: Char);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
 // проверяет, является ли символ допустимым
// во время ввода дробного числа

function IsFloat(ch : char; st: string) : Boolean;

begin
if (ch >= '0') and (ch <= '9') // цифры
or (ch = #13) // клавиша <Enter>
or (ch = #8) // клавиша <Backspace>
    then
        begin
            IsFloat := True; // символ верный
            Exit; // выход из функции
        end;
case ch of
        '-': if Length(st) = 0
            then IsFloat := True;
',': if (Pos(',',st) = 0)
      and  (Length(st) <> 0)
      and (st[Length(st)] >= '0')
      and (st[Length(st)] <= '9')
          then // разделитель можно ввести только после цифры
                // и если он еще не введен
            IsFloat := True
                else // остальные символы запрещены
                    IsFloat := False;
end;

end;

// щелчок на кнопке Вычислить
procedure TForm1.Button1Click(Sender: TObject);
var
rast : real; // расстояние
cena : real; // цена
potr : real; // потребление на 100 км
summ : real; // сумма
mes: string;
begin
rast := StrToFloat(Edit1.Text);
cena := StrToFloat(Edit2.Text);
potr := StrToFloat(Edit3.Text);
summ := rast / 100 * potr * cena;
      if CheckBox1.Checked then summ := summ * 2;
        mes := 'Поездка на дачу';
            if CheckBox1.Checked
                    then mes := mes + ' и обратно';
        mes := mes + 'обойдется в '
             + FloatToStrF(summ,ffGeneral,4,2) + ' руб.';
        Label4.Caption := mes;
end;
// нажатие клавиши в поле Расстояние
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = Char(VK_RETURN)
then Edit2.SetFocus // переместить курсор в поле Цена
else
If not IsFloat(Key, Edit1.Text) then Key := Chr(0);
end;
// нажатие клавиши в поле Цена
procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
begin
 if Key = Char(VK_RETURN)
then Edit3.SetFocus // переместить курсор в поле Потребление
else If not IsFloat(Key, Edit2.Text)
then Key := Chr (0);
end;
// нажатие клавиши в поле Потребление
procedure TForm1.Edit3KeyPress(Sender: TObject; var Key: Char);
begin
 if Key = Char(VK_RETURN)
then Button1.SetFocus // // сделать активной кнопку Вычислить
else If not IsFloat(Key, Edit3.Text) then Key := Chr (0);
end;

end.

PM MAIL   Вверх
Данкинг
Дата 8.7.2010, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: 11
Всего: 130



А почему не использовать стандартную функцию TryStrToFloat ?


--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
Proxin
Дата 9.7.2010, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 363
Регистрация: 21.6.2008

Репутация: 1
Всего: 3



или повесьте проверку на keypress, так правильней будет.
PM MAIL   Вверх
PsiMagistr
Дата 9.7.2010, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

Репутация: 1
Всего: 1



Я обычно IntToStrDef() использую.


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
LoveMeCozImBLONDE
Дата 10.7.2010, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 27.5.2009

Репутация: нет
Всего: нет



http://www.citforum.ru/programming/32less/les18.shtml
прочитайте, вам будет полезно
PM MAIL   Вверх
Proxin
Дата 10.7.2010, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 363
Регистрация: 21.6.2008

Репутация: 1
Всего: 3



зачем сюда исключения пихать-то? val вполне от ошибок защитит.
PM MAIL   Вверх
Keeper89
Дата 11.7.2010, 01:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 9
Всего: 58



Proxin, каждый решил помериться тем, что знает, а на вопрос ТС никто не ответил smile.

Предложу вариант:
Код

function IsFloat(const AEdit: TEdit; out a: Double): Boolean;
var  
  ChangeMethod: TNotifyEvent;
begin
  Result := TryStrToFloat(AEdit.Text, a);

  if not Result then
  begin
    ChangeMethod := AEdit.OnChange;
    AEdit.OnChange := nil;
    try
      AEdit.Perform(WM_CHAR, VK_BACK, 0);
    finally
      AEdit.OnChange := ChangeMethod;
    end;
  end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
var
  a: Double;
begin
  if IsFloat(Edit1, a) then
    Caption := FloatToStr(a * 2)
end;


* Copy/Paste это к сожалению не обрабатывает.

Это сообщение отредактировал(а) Keeper89 - 11.7.2010, 17:13


--------------------
PM MAIL WWW   Вверх
rytmix
Дата 11.7.2010, 21:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 2.6.2009

Репутация: нет
Всего: нет



Как уже писалось ранее, правильнее проверять при наборе значений
PM MAIL   Вверх
Keeper89
Дата 13.7.2010, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 9
Всего: 58



Правильнее? Ну приведите тогда Ваш правильный код ради интереса.


--------------------
PM MAIL WWW   Вверх
de_Nis
Дата 15.7.2010, 09:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Старательный
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 19.10.2006
Где: Молдова

Репутация: нет
Всего: 6



Допустим, для работы программы DecimalSeparator должен быть "точка (например, в программах, работающих с AutoCad-ом: AutoCad не воспринимает другой символ в качестве десятичного разделителя).
Тогда в процедуре FormActivate д. б. указано:

Код

procedure TForm1.FormActivate(Sender: TObject);
begin
... ...
     DecimalSeparator := '.';
end;
)


Далее - один обработчик для всех Edit-ов:

Код

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
// если пользователь вводит запятую - заменяем на точку:
if (Key=',') then
        Key:='.';

case Key of
'0'..'9':; //можно вводить цифры,
#8 : ; // разрешена клавиша <Backspace>
'.':  // и десятичный разделитель "точка"
  
begin
Key := DecimalSeparator;
// проверим, введен ли уже в поле Edit десятичный разделитель
if Pos(DecimalSeparator,TEdit(Sender).Text) <> 0 then
Key := Char(0);
end;

// остальные символы — запрещены
else Key :=Chr(0); // символ не отображать
end;
end;


Процедура разрешает ввод только цифр, не требует нажатия только клавиши "точка", допускает использование клавиши Backspace, не допускает ввод более одного десятичного разделителя.
Если на событие KeyPress для конкретного Edit-а (например, для Edit3) нужно "повесить" еще что-либо, в коде изменяется строчка: вместо
Код

if Pos(DecimalSeparator,TEdit(Sender).Text) <> 0 then

должно быть
Код

if Pos(DecimalSeparator,TEdit3.Text) <> 0 then

и теперь в процедуре для этого конкретного Edit3 можно дописать дополнительный код.

Это сообщение отредактировал(а) de_Nis - 15.7.2010, 09:42
--------------------
Несчастлив не тот, у кого ничего нет, а тот, кто ничего не хочет…
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0553 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.