Delphi Programming / Object Pascal
[掲載 2017年03月16日] [更新 2020年04月10日] Delphi サンプルプログラム集 |
454_半角の英字や数字だけの入力 |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 + Micorsoft Office IME 2010 |
|
454_Half-width_Letter.zip [3,606 KB] 2020年04月10日版 (EXE 同梱) |
TEdit 等の入力用コントロールで半角の英数字が入力可能なのは,日本語 IME が OFF の時,または,日本語 IME の [入力モード] が [半角英数] になっている場合です.これは ImeMode プロパティの値が imSAlpha の場合に相当します.
日本語 IME の入力モードが [半角英数] 以外でも,[テンキーからの入力] が [常に半角] であれば半角の数字だけの入力とすることができます.
テンキーからの入力を半角にする機能は,独自に設定可能なアプリもあります. |
[備考]
TEdit 等の入力コントロールの OnKeyPress イベントで英数字の半角たけの入力制限しても,クリップボードからの貼り付けでは,全角とししての漢字は入力できます.
|
|
図1
日本語 IME の [入力モード]
- [半角英数] にすると半角の英数字の入力制限が可能
- Micorsoft Office IME 2010 の例
|
|
図2
テンキーからの入力設定
- [常に半角] にするとテンキーから半角の数字の入力が可能
- Microsoft Office IME 2010 の例
|
01_CharInSet を使用した半角の数字だけの入力許可 |
CharInSet は,第 1 引数の ASCII 文字が,第 2 引数の ASCII 文字のセット存在するかをを判定できます.それを使用したサンプルです.
半角の英数字が入力可能な状態で以下のコードを実行すると,半角の数字だけの入力を許可するようにできます.このコードは,ネット上の記事に多く掲載されています.
アルファベットだけを許可する場合は,文字セットを 'A..z' とします.
|
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if (not CharInSet(Key, [Char(VK_BACK), '0'.. '9'])) then begin
Key := #0;
end;
end;
次のコードは,日本語 IME が ON の状態でも,テンキーから入力した場合は,全角の数字を半角の数字に変換して,TEdit にセットするサンプルです.
このようにすると,日本語 IME を OFF にする必要がありません.
|
|
図3
日本語 IME が ON の状態で入力 |
|
図4
[Enter] で確定しても漢字は入力されない |
リスト1
半角の数字だけの入力を許可
全角の数字を入力した場合は半角の数字に変換する |
//=============================================================================
// Edit1 の OnKeyPress イベント処理
// キーボードから数字以外の入力を禁止(数字だけを許可する)
//
// VK_BACK を含めておかないと [Back] キーが使用できない
//=============================================================================
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
// コードポイント値が全角の数字だったら半角の数字の値に変換
if (Key >= #$FF10) and (Key <= #$FF19) then begin
Key := Char(Ord(Key) - $FEE0);
end else begin
if (not CharInSet(Key, [Char(VK_BACK), '0'.. '9'])) then begin
Key := #0;
end;
end;
end;
全角で入力しても,半角で入力しても,数字は全て全角の数字として TEdit にセットするのであれは,例えば以下のようなコードで可能です.
|
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if (Key >= #$FF10) and (Key <= #$FF19) then begin
//
end else begin
if (not CharInSet(Key, [Char(VK_BACK), '0'.. '9'])) then begin
Key := #0;
end else begin
if (CharInSet(Key, ['0'.. '9'])) then begin
Key := Char(Ord(Key) + $FEE0);
end;
end;
end;
end;
02_TCharacter.IsNumber を使用した数字だけの入力 |
TCharacter.IsNumber メソッドを使用すると,引数の値が数字であるを判定できます.この IsNumber メソッドを利用して数字だけを入力可能にするサンプルです.
最初の TEdit では,全角の数字を入力した場合は全角の数字を,半角の数字を入力した場合は半角の数字を TEdit にセットします.
|
[備考]
TCharacter.IsNumber は単に IsNumber
と書いても同じです.少なくとも Delphi XE5 には他に同じ名前のメソッドは実装されていません.
|
|
図5
日本語 IME が ON の状態でテンキーから入力
|
|
図6
[Enter] で確定すると全角の数字になる
|
2 番目の TEdit では,全角で入力しても,半角で入力しても,数字は半角の数字として TEdit にセットします. |
|
図7
日本語 IME が ON の状態でテンキーから入力
|
|
図8
[Enter] で確定すると半角の数字になる |
リスト2
TCharacter.IsNumber を使用した数字だけの入力 |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure Edit2KeyPress(Sender: TObject; var Key: Char);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses
System.Character;
{$R *.dfm}
//=============================================================================
// Edit1 の OnKeyPress イベント処理
// キーボードから数字以外の入力を禁止(数字だけを許可する)
//
// VK_BACKを含めておかないと [Back] キーが使用できない
// TCharacter を使用する例
// uses に System.Character が必要
//=============================================================================
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (TCharacter.IsNumber(Key) or (Key = Char(VK_BACK))) then begin
Key := #0;
end;
end;
//=============================================================================
// Edit2 の OnKeyPress イベント処理
// キーボードから数字以外の入力を禁止(数字だけを許可する)
//
// VK_BACK を含めておかないと [Back] キーが使用できない
// TCharacter を使用する例
// uses に System.Character が必要
//=============================================================================
procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
begin
if not (TCharacter.IsNumber(Key) or (Key = Char(VK_BACK))) then begin
Key := #0;
end else begin
// -コードポイントの値が全角の数字だったら半角の数字の値に変換
if (Key >= #$FF10) and (Key <= #$FF19) then begin
Key := Char(Ord(Key) - $FEE0);
end;
end;
end;
end.
03_TCharHelper.IsNumber を使用した数字だけの入力 |
Delphi XE3 以降では TCharacter は非推奨になっています.代わりに TCharHelper が使用できます.TCharHelper は Char 型のヘルパーです.TCharHelper
を使用すると,Char 型の変数に対して直接 TCharHelper のメソッドが実行できます.
以下のコードは Delphi XE5 で動作を確認しています.動作は上のサンプルと同じです.
|
リスト3
TCharHelper を使用した数字だけの入力 |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure Edit2KeyPress(Sender: TObject; var Key: Char);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses
System.Character;
{$R *.dfm}
//=============================================================================
// Edit1 の OnKeyPress イベント処理
// キーボードから数字以外の入力を禁止(数字だけを許可する)
//
// VK_BACK を含めておかないと [Back] キーが使用できない
// TCharHelper の機能を利用する例
// uses に System.Character が必要
//=============================================================================
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not ((Key.IsNumber) or (Key = Char(VK_BACK))) then begin
Key := #0;
end;
end;
//=============================================================================
// Edit2のOnKeyPress イベント処理
// キーボードから数字以外の入力を禁止(数字だけを許可する)
//
// VK_BACK を含めておかないと [Back] キーが使用できない
// TCharHelper の機能を利用する例
// uses に System.Character が必要
//=============================================================================
procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
begin
if not ((Key.IsNumber) or (Key = Char(VK_BACK))) then begin
Key := #0;
end else begin
// コードポイントの値が全角の数字だったら半角の数字の値に変換
if (Key >= #$FF10) and (Key <= #$FF19) then begin
Key := Char(Ord(Key) - $FEE0);
end;
end;
end;
end.
ここまでのサンプルでは,TEdit 等の入力コントロールの OnKeyPress イベントで英数字の半角たけの入力制限の処理をしています.以下のリンクの記事のサンプルのように,OnChange イベントで処理する方法も考えられます.この方法であれば,クリップボードからの貼り付けの操作でも入力した文字の判定や処理が可能です.
クリップボードの文字列だけを処理するには,コンポーネントの継承クラスを作成して,WM_PASTE メッセージを処理します.以下は,TEdit に整数だけを入力する例です.
継承クラスを作成しているので,このサンプルでは,キー入力も継承クラスの KeyPress メソッドを使用していますが,これまでのサンプルのように,イベントで処理しても同じです.
|
このサンプルでは,継承クラスをコンポーネントとして登録しないで,添付の plChgCompo ユニットを使用して,実行時にコンポーネントを派生クラスに置き換えてテストしています.
|
|
図9
クリップボードから貼り付け |
|
図10
整数に変換できない場合 |
|
図11
整数に変換できる場合
|
リスト4
クリップボードからの貼り付を,継承クラスの WM_PASTE メッセージで捕捉する |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TplIntEdit = class(TEdit)
protected
procedure WMPaste(var Message: TWMPaste); message WM_PASTE;
procedure KeyPress(var Key: Char); override;
end;
TForm1 = class(TForm)
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
plIntEdit1 : TplIntEdit;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses
System.Character,
Vcl.Clipbrd,
plChgCompo;
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
// フォーム作成時にコンポーネントの入れ替え
plIntEdit1 := TplIntEdit(ChangeComponent(Edit1, TplIntEdit));
end;
{ TplIntEdit }
//=============================================================================
// TEdit の継承クラスの KeyPress メソッド
// キーボードから数字以外の入力を禁止(数字だけを許可する)
//
// VK_BACKを含めておかないと[Back]キーが使用できない
//=============================================================================
procedure TplIntEdit.KeyPress(var Key: Char);
begin
inherited;
if not ((Key.IsNumber) or (Key = Char(VK_BACK))) then begin
Key := #0;
end else begin
// コードポイントの値が全角の数字だったら半角の数字の値に変換
if (Key >= #$FF10) and (Key <= #$FF19) then begin
Key := Char(Ord(Key) - $FEE0);
end;
end;//
end;
//=============================================================================
// TEdit の継承クラスの WM_PASTE メッセージ処理
// クリップボードの文字列が整値に変換できれば Text プロパティに文字列をセット
// 整数に変換できない時は Text プロパティに空文字をセット
//=============================================================================
procedure TplIntEdit.WMPaste(var Message: TWMPaste);
var
LClipbrdText : string;
LInteger : Integer;
LMsgText : string;
begin
inherited;
if Clipboard.HasFormat(CF_TEXT) then begin
LClipbrdText := Clipboard.AsText;
if TryStrToInt(LClipbrdText, LInteger) then begin
Text := IntToStr(LInteger);
end else begin
Text := '';
LMsgText := LClipbrdText + sLineBreak + 'は整数に変換できません';
MessageBox(Handle, PChar(LMsgText), 'クリップボード', MB_ICONWARNING);
SetFocus;
end;
end;
end;
end.
WM_PASTE メッセージの処理で,inherited (継承元の処理) を実行しないと,クリップボードからの貼り付けはできません.inherited は継承という意味です.
|
procedure TplIntEdit.WMPaste(var Message: TWMPaste);
var
LMsgText : string;
begin
if Clipboard.HasFormat(CF_TEXT) then begin
LMsgText := 'クリップボードからの貼り付けは禁止です.';
MessageBox(Handle, PChar(LMsgText), '貼り付け禁止', MB_ICONINFORMATION);
SetFocus;
end else begin
inherited;
end;
end;
コントロールのメッセージは WndProc メソッドでも補足できます.また,サブクラス化という手法を用いると,継承クラスを作成しなくてもコントロールのメッセージが捕捉できます.
|
|