Перейти к содержанию
Fire Monkey от А до Я
  • 0

MaskEdit


DirtyBorov

Вопрос

Случилось так, что потребовался мне ввод номера телефона. Компонента, аналога TMaskEdit в FMX нет, так что пришлось "изобретать на коленке". Компонент писать было лень, потому просто покажу как я решил это в конкретном диалоге с использованием TEdit. Может кому то пригодится. Из кода я убрал все лишнее, оставил только то что относится к делу.

uses
  ....
  System.MaskUtils, System.Character;

type
  TFormRegistry = class(TForm)
    edtPhone: TEdit;
    procedure edtPhoneValidating(Sender: TObject; var Text: string);
    procedure edtPhoneKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
    procedure edtPhoneEnter(Sender: TObject);
    procedure edtPhoneTyping(Sender: TObject);
  private
    const Mask = '+7(000)000-00-00;0;*';  /// '+0(000)000-00-00;0;*' - для других стран, например для Украины +3(999)....
  private
    PhoneNumber: string;
    function GetCaretPos: Integer;
    function GetMaxLength: integer;
  public
  end;

procedure TFormRegistry.FormCreate(Sender: TObject);
begin
  edtPhone.Text := FormatMaskText(Mask, PhoneNumber);
end;

function TFormRegistry.GetCaretPos: Integer;
var
  i: integer;
begin
  Result := 0;
  for i := 0 to Mask.Length-1 do
   begin
     if not (MaskGetCharType(Mask, i) in [mcDirective, mcMask]) then
       Result := Result + 1;
     if (Result + PhoneNumber.Length) = i then
         Break;
   end;
  Result := Result + PhoneNumber.Length - 1;
end;

function TFormRegistry.GetMaxLength: integer;
var
  i: integer;
begin
  Result := 0;
  for i := 0 to Mask.Length-1 do
    if (MaskGetCharType(Mask, i) in [mcMask]) then
      Result := Result + 1;
end;

procedure TFormRegistry.edtPhoneKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
begin
  if (Key = 8) and (PhoneNumber.Length > 0) then
     PhoneNumber := Copy(PhoneNumber, 1, PhoneNumber.Length-1)
  else
  if (PhoneNumber.Length < GetMaxLength) and (Key = 0) and IsDigit(KeyChar) then
      PhoneNumber := PhoneNumber + KeyChar
  else
     KeyChar := #0;
end;

procedure TFormRegistry.edtPhoneEnter(Sender: TObject);
begin
  edtPhone.CaretPosition := GetCaretPos;
end;

procedure TFormRegistry.edtPhoneTyping(Sender: TObject);
begin
  edtPhone.CaretPosition := GetCaretPos;
end;

procedure TFormRegistry.edtPhoneValidating(Sender: TObject; var Text: string);
begin
  Text := FormatMaskText(Mask, PhoneNumber);
end;

end.

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Каретка только при входе в эдит не туда устанавливается :)

А происходит это потому что сначала отрабатывается событие OnEnter, а потом edit устанавливает каретку, т.е. делать это нужно не в событии OnEnter, а после того как эдит сам установил каретку. Вопрос как.

 

UPD: событие MouseUp подходит, только там видно как сначала каретка устанавливается в конец эдита, а потом прыгает на место.

Изменено пользователем xenon54
Ссылка на комментарий
  • 0
// ---------------------------------------------------------------------------

#include <fmx.h>
#pragma hdrstop

#include "Unit1.h"
// ---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;

// ---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
	Mask = "+7(00)000-00-00;0;*";
	PhoneNumber = "";
}

// ---------------------------------------------------------------------------
void __fastcall TForm1::edtPhoneTyping(TObject *Sender) {
	edtPhone->CaretPosition = GetCaretPos();
}

// ---------------------------------------------------------------------------
int __fastcall TForm1::GetCaretPos() {
	int i;
	int Result = 0;
	for (i = 0; i < Mask.Length(); i++) {
		if (!(MaskGetCharType(Mask, i) == mcDirective || MaskGetCharType(Mask,
			i) == mcMask))
			Result += 1;
		if ((Result + PhoneNumber.Length()) == i)
			break;
	}
	Result = Result + PhoneNumber.Length() - 1;
	return Result;
}

int __fastcall TForm1::GetMaxLength() {
	int Result = 0;
	for (int i = 0; i < Mask.Length(); i++)
		if (MaskGetCharType(Mask, i) == mcMask)
			Result = Result + 1;
	return Result;
}

void __fastcall TForm1::edtPhoneKeyDown(TObject *Sender, WORD &Key,
	System::WideChar &KeyChar, TShiftState Shift) {
	if ((Key == 8) && (PhoneNumber.Length() > 0))
		PhoneNumber = PhoneNumber.SubString(1, PhoneNumber.Length() - 1);
		else if ((PhoneNumber.Length() < GetMaxLength()) && (Key == 0)
			&& IsDigit(KeyChar))
			PhoneNumber = PhoneNumber + KeyChar;
		else
			KeyChar = 0;
}
// ---------------------------------------------------------------------------
void __fastcall TForm1::edtPhoneKeyUp(TObject *Sender, WORD &Key, System::WideChar &KeyChar,
		  TShiftState Shift)
{
	edtPhone->CaretPosition = GetCaretPos();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::edtPhoneValidating(TObject *Sender, UnicodeString &Text)
{
	Text = FormatMaskText(Mask, PhoneNumber);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
	edtPhone->Text = FormatMaskText(Mask, PhoneNumber);
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
#include <System.MaskUtils.hpp>
#include <FMX.Controls.Presentation.hpp>
#include <FMX.Edit.hpp>
#include <FMX.StdCtrls.hpp>
#include <FMX.Types.hpp>
#include <System.Character.hpp>
#include <string.h>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
	TEdit *edtPhone;
	TButton *Button1;
	void __fastcall edtPhoneTyping(TObject *Sender);
	void __fastcall edtPhoneKeyDown(TObject *Sender, WORD &Key, System::WideChar &KeyChar,
          TShiftState Shift);
	void __fastcall edtPhoneKeyUp(TObject *Sender, WORD &Key, System::WideChar &KeyChar,
          TShiftState Shift);
	void __fastcall edtPhoneValidating(TObject *Sender, UnicodeString &Text);
	void __fastcall FormCreate(TObject *Sender);
private:	// User declarations
public:
	String PhoneNumber;
	String Mask;
    int __fastcall GetCaretPos();
	int __fastcall GetMaxLength();	// User declarations
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Для тех кому нужен на C++

Ссылка на комментарий
  • 0

Присоединяюсь к вопросу про андроид. Попробовал пример приведённый Axbor для C++ Builder: под Windows прекрасно работает, под Android совсем не работает. 

Изменено пользователем pill
Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

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

×
×
  • Создать...