現在はonExitイベントで「ぁ」から「ん」まで全て検査して例外がないかどうか、という方法で検出していますが、もっと良い方法がありますか?
また、できれば、入力・確定された時点で検出できれば良いと思います。
ログぐらい読みましょうね
https://www.petitmonte.com/bbs/answers?question_id=1101
リンク先を参考に、OnKeyPressイベントに
if(pos(key, 'あいうえお')=0) then
begin
Key := #0;
end;
と記述しても
「あqwせdrftgyふじこ」みたいな文字列も入力できてしまうんですけど。2バイトひらがなのみに限定したい、という場合にKeyで検出できるんですか??
ひらがなをどうやって入力してるの?
私は「IME+ローマ字入力」しか使わないから直接ひらがなをEditに入力する方法自体がわからんのだけど。
こんな感じかな?
var
B: Boolean;
procedure TForm4.Edit1Change(Sender: TObject);
var
S: WideString;
begin
if B = False then
begin
B := True;
S := Copy(Edit1.Text,Length(Edit1.Text)-1,2);
if Pos(S,'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわんをぁぃぅぇぉゃゅょっがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽ') = 0 then
begin
Edit1.Text := Copy(Edit1.Text,1,Length(Edit1.Text)-2);
Edit1.SelStart := Length(Edit1.Text);
end;
B := False;
end;
end;
procedure TForm4.FormCreate(Sender: TObject);
begin
Edit1.ImeMode := imHira;
end;
Delphi7でテストしただけなので、もしかしたらDelphi5ではうまく動かないかも。
usesにimmを追加。
Form1に、
OldWindowProc : TWndMethod;
procedure NewWindowProc(var Message: TMessage);
を追加。
procedure TForm1.FormCreate(Sender: TObject);
begin
OldWindowProc := Edit1.WindowProc;
Edit1.WindowProc := NewWindowProc;
end;
procedure TForm1.NewWindowProc(var Message: TMessage);
var
CC: Word;
begin
if (Message.Msg = WM_IME_CHAR) then
begin
//IMEからの文字だったら処理
CC := TWMKey(Message).CharCode;
if (CC >= $829F) and (CC <= $82F1) then
begin
//「ぁ」から「ん」だったら処理
OldWindowProc(Message);
end;
Message.Result := 0;
end
else if(Message.Msg = WM_CHAR) then
begin
//WM_IME_CHARは2つのWM_CHARに分けられて飛んでくる
CC := TWMKey(Message).CharCode;
if (CC >= $20) and (CC <= $7e) and (Message.LParam and $FF0000 <> 0) then
begin
//キーボードから入力可能な文字で、かつ、キーボードから入力されたなら処理しない
end
else
begin
OldWindowProc(Message);
end;
Message.Result := 0;
end
else
begin
OldWindowProc(Message);
end;
end;
Mr.XRAYです.いつも参考にさせて頂いています.
にしのさんのやってみました.
> if (CC >= $20) and (CC <= $7e) and (Message.LParam and $FF0000 <> 0) then
> begin
> //キーボードから入力可能な文字で、かつ、キーボードから入力されたなら処理しない
> end
なるほど,これだと禁止文字を入力したので消すぞ!
という感じになっていますね.これはいいかも知れません.
文字を最初から走査して >= and <= というのが正攻法かなとも考えたのですが,
面白そうだったので,にしのさんとは違うアプローチを考えてみました.
IMEで無変換というのがありますので,これを用いました.
これでも英数字の入力ができてしまいます.そこで,強制的に変更するようにして
みました.
テストですので,ついでに,ひらがなだけ,カタカナだけ,の両方をやってみました.
テスト環境は,WindowsXP(SP3) + Delphi7 Pro + MS IME 2002 Ver8.1 です.
http://mrxray.on.coocan.jp/Delphi/plSamples/452_KanaOnlyInput.htm#02
このIMEの機能を使用する方法ですが,残念ながら,質問された方の希望である,
いわゆる「入力・確定された時点」というのはできませんね.
にしのさんの方法を使うしかないような気がします.
勝爺:「あ、マコト、そこのランプ取ってくれないか」
真琴:「これ? はい、ランプ、掃除するの?」
勝爺:「おぅ、ありがとぅ、磨いてキレイにな、…それから、ついでにソコの雑巾も」
真琴:「おじいちゃん、自分で取りにいけばいいじゃない、横着なんだから…はい、雑巾」
勝爺:「昔から言うだろぅ、"立ってるものは孫でも使え"ってな^^;」
真琴:「あのね、おじいちゃん、それって…」
春子:「おっはよ〜、タンポポも咲いて、春だよねぇ」
真琴:「おはようございます、…あの、ハルコさん、面白そうだからアタシもチョットやってみたんだけど…」
春子:「ン? ナニを?」
真琴:「Editの入力で、"ひらがな"以外は禁止する方法」
春子:「Editの入力制限? ふ〜ん、どうやったの?」
真琴:「人によって方法はイロイロだけど、アタシはこうしてみたの」
type
TEdit = class(StdCtrls.TEdit)
private
procedure WmImeComposition(var Msg: TMessage); message WM_IME_COMPOSITION;
procedure WmPaste(var Msg: TMessage); message WM_PASTE;
end;
TForm1 = class(TForm)
......
procedure TEdit.WmImeComposition(var Msg: TMessage);
function GetInputStr(Handle: THandle): Boolean;
var
Imc: HIMC;
i, Len: Integer;
S: string;
d: WORD;
begin
result := True;
Imc := ImmGetContext(Handle);
if Msg.LParam and GCS_RESULTSTR <> 0 then begin
Len := ImmGetCompositionString(Imc, GCS_RESULTSTR, nil, 0);
SetLength(S, Len);
ImmGetCompositionString(Imc, GCS_RESULTSTR, PChar(S), Len+1);
if Len = 1 then begin
result := False; // 半角カナなど 1文字の場合
exit;
end;
for i:=0 to (Len div 2)-1 do begin
d := Byte(s[i*2+1]) shl 8 + Byte(s[i*2+2]);
if (d < $829F)or(d > $82F1) then begin
result := False;
exit;
end;
end;
end;
ImmReleaseContext(Handle, Imc);
end;
begin
// フォームに貼り付けたEdit1だけをひらがな入力専用に
if (Name = 'Edit1')and(not GetInputStr(Handle)) then Msg.result := 0
else inherited;
end;
procedure TEdit.WmPaste(var Msg: TMessage);
begin
if Name = 'Edit1' then Msg.result := 0
else inherited;
end;
春子:「ナルホドね、変換確定時にひらがな以外があったら無視するってコト?」
真琴:「そうなの」
春子:「コピペも禁止?」
真琴:「うん、にしのさんが忘れてるから、イチオウ…」
春子:「あと、かな漢字混じりの文を確定したときの対処も違うじゃない?」
真琴:「どっちがイイかは、使う人によって好みが変わると思うけど」
春子:「↓これは確定文字列を1文字づつWord変数に入れてるのよね?」
d := Byte(s[i*2+1]) shl 8 + Byte(s[i*2+2]);
真琴:「そぅ、PWordで読み込みたいけど、それじゃバイト順序が逆になっちゃうから」
春子:「だったら、htons関数を使えば?」
真琴:「え? それナンなの?」
春子:「Wordのエンディアンの変更よ、本来はネットワーク通信の際のバイトオーダーの変換で使うンだけどね」
d := htons((PWord(PChar(S)+i*2))^);
真琴:「通信で使うもの? それをココで?」
春子:「そぅよ、昔から言うでしょ? "立ってるものは猫でも使え"って」
真琴:「…あの、ハルコさん、それって…」
ツイート | ![]() |