JuanFer
JuanFer

Reputation: 3

Is there a way to mimic a credit card machine screen?

I would like to input numbers, so they appear from right to left. It should start with the two decimals, moving on to the amount. I'm using buttons to enter data into a memo box. So far, I have managed to format the input of the 10 buttons (1, 2, 3...0), so that any amount is set to appear with two subsequent zeroes.

The problem is that I can only enter amounts starting from the units, not from the decimals. So when I click on the button '2', it should show (0.02), instead of (2.00). On top of that, once I enter more than seven digits, it goes from this (1234567,00) to this (12345678,0), to this (,123456789) and (1234567890).

Some considerations: The MaxLength is 12. There should be no decimal separator button, since card machines don't have them. ReadOnly is set to true, and BiDiMode to bdRightToLeft. The memo box should only use one line. The amount and processedamount are String variables. I'm using both of them, until I'm sure that processedamount works as expected (I need a variable with the amount for a different method)

procedure TForm1.NumberButtonClick(Sender: TObject); //Number 1-9 use this Event OnClick
begin
  if Memo1.Lines[0] = '0' then
  begin
    SetLength(amount, LENGTH(amount)-1);
    amount := amount + (Sender as TButton).Caption;
    processedamount := FormatFloat('0.00', (strtofloat(amount)));
    Memo1.Lines[0] := processedamount;
  end
  else
  begin
    amount := amount + (Sender as TButton).Caption;
    processedamount := FormatFloat('0.00', (strtofloat(amount)));
    Memo1.Lines[0] := processedamount;
  end;
end;
procedure TForm1.Boton0Click(Sender: TObject); //Number 0 Event OnClick
begin
  if Memo1.Lines[0] = '0' then
  begin
    amount := amount; //To prevent two zeroes on screen, there's nothing else in this block
  end
  else
  begin
    amount := amount + (Sender as TButton).Caption;
    processedamount := FormatFloat('0.00', (strtofloat(amount)));
    Memo1.Lines[0] := processedamount;
  end;
end;
procedure TForm1.DeleteClick(Sender: TObject);
begin
  SetLength(amount, LENGTH(amount)-1);
  if amount = '' then //I noticed that when the amount is '' it means that there is only one digit before the ','
  begin
    amount := '0'; //It deletes by placing a zero instead of the unit 
    processedamount := FormatFloat('0.00', (strtofloat(amount)));
    Memo1.Lines[0] := processedamount;
  end
  else
  begin
    processedamount := FormatFloat('0.00', (strtofloat(amount)));
    Memo1.Lines[0] := processedamount;
  end;
end;

Upvotes: 0

Views: 202

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595971

Using the BiDiMode property is not appropriate in this situation. To line up your text on the right side, set the Alignment property to taRightJustify instead.

To get the kind of input behavior you want, I suggest using simple integer operations instead of string operations. For example:

var
  // monetary value scaled by 1/100 to avoid
  // rounding issues during arithmetic operations
  amount: Int64 = 0;
  Fmt: TFormatSettings;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Fmt := TFormatSettings.Create;
  Fmt.DecimalSeparator := '.';
end;

procedure TForm1.NumberButtonClick(Sender: TObject);
var
  Digit: integer;
begin
  //Number 0-9 use this Event OnClick
  //Set the Button's Tag to match its Caption
  Digit := (Sender as TButton).Tag;
  if (Digit <> 0) or (amount <> 0) then
  begin
    amount := (amount * 10) + Digit;
    Memo1.Lines[0] := FormatFloat('0.00', Double(amount) / 100.0, Fmt);
  end;
end;

procedure TForm1.DeleteClick(Sender: TObject);
begin
  amount := amount div 10;
  Memo1.Lines[0] = FormatFloat('0.00', Double(amount) / 100.0, Fmt);
end;

Upvotes: 2

Related Questions