数値入力専用Edit


数値入力専用のEditコンポーネント(TNumEdit)を作ってみた. 表示は右寄せであり,数字,"-"(マイナス),"." (ドット,小数点)以外のキー入力は 受け付けない.

親コンポーネントはTCustomEditとした. まず,右寄せ表示にするためにCreateParamsメソッドをオーバーライドし, Params.StyleにES_RIGHTを指定する.

procedure TNumEdit.CreateParams( var Params: TCreateParams );
begin
  inherited CreateParams( Params );
  Params.Style := Params.Style or ES_RIGHT;
end;

ただし,SDKにはES_RIGHTに関して "Right-aligns text in a multiline edit control." と書いてあるため,

  Params.Style := Params.Style or ES_RIGHT or ES_MULTILINE;

とするべきかも知れない. 実際には,ES_MULTILINEを指定しなくても特に問題ないようだ.

数字,"-",および "." 以外の入力を 受け付けないようにするには,WM_CHARメッセージが来たときに入力された文字を調べ, 規定の入力以外は無効にすればよい. 具体的にはWM_CHARのメッセージハンドラを以下のように書く.

procedure TNumEdit.WMChar( var Message: TWMChar );
const
  CharCodes = [ 8, 45, 46, 48..57 ];
begin
  if not ( Message.CharCode in CharCodes ) then
     Message.CharCode := 0
  else
     inherited;
end;

WM_CHARメッセージと一緒に送られてくるTWMChar型構造体のCharCodeメンバには 入力された文字のコードが格納されている. 上の例では,CharCodeメンバの値が入力を許す文字コードの集合に含まれていなければ0を代入し, 入力値を無効にしている. 文字コードの8はバックスペース,45は "-",46は ".",48から57は0から9までの数値である.

ただし,これだけでは "-100-" や "0.12.34" のような入力も許されてしまう. したがって,DoExitメソッドをオーバーライドし,入力フォーカスが他のウィンドウに 移る直前に入力された文字列をチェックし,正しくない入力であれば警告を表示するようにする.

procedure TNumEdit.DoExit;
var
  Dammy: Extended;
begin
   if Text <> '' then
   begin
      try
        Dammy := StrToFloat( Text );
        inherited DoExit;
      except
        on E: EConvertError do
        begin
           MessageDlg( '''' + Text + ''' は浮動小数点数ではありません',
                       mtError, [ mbOK ], 0 );
           SetFocus;
        end;
      end;
   end
   else inherited DoExit;
end;

入力をチェックするにはtry ... except ...構文を用いる. もし,入力が不正ならばStrToFloat関数の呼び出しで例外(EConvertError)が 発生するので,これをキャプチャして警告を表示したのち,入力フォーカスを戻す.

さらに,入力された文字列を数値データとして取り出したり,数値データを入力として 受け付けるためにValueプロパティを用意し, 入出力用メソッドを以下のように定義する.

type
  TNumEdit = class( TCustomEdit )
  private
    procedure SetValue( AValue: Double );
    function GetValue: Double;
  published
    property Value: Double read GetValue write SetValue;
  end;

  (略)

procedure TNumEdit.SetValue( AValue: Double );
begin
   Text := FloatToStr( AValue );
end;

function TNumEdit.GetValue: Double;
begin
   if Text <> '' then
      Result := StrToFloat( Text )
   else
      Result := 0; // Textプロパティが未設定の時は0を返す
end;


お問い合わせはメールにて: akasaka@klc.ac.jp

戻る
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送