del5pro:editコントロールでひらがな以外の入力を禁止させる


ペーパープログラマ  2009-04-08 19:25:22  No: 33964

現在はonExitイベントで「ぁ」から「ん」まで全て検査して例外がないかどうか、という方法で検出していますが、もっと良い方法がありますか?
また、できれば、入力・確定された時点で検出できれば良いと思います。


すこしは  2009-04-09 08:17:52  No: 33965

ログぐらい読みましょうね
https://www.petitmonte.com/bbs/answers?question_id=1101


ペーパープログラマ  2009-04-09 09:12:04  No: 33966

リンク先を参考に、OnKeyPressイベントに

if(pos(key, 'あいうえお')=0) then
begin
 Key := #0;
end;
と記述しても
「あqwせdrftgyふじこ」みたいな文字列も入力できてしまうんですけど。2バイトひらがなのみに限定したい、という場合にKeyで検出できるんですか??


そもそも  2009-04-09 18:43:51  No: 33967

ひらがなをどうやって入力してるの?
私は「IME+ローマ字入力」しか使わないから直接ひらがなをEditに入力する方法自体がわからんのだけど。


KHE00221  2009-04-09 19:04:52  No: 33968

こんな感じかな?

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;


にしの  2009-04-09 22:08:27  No: 33969

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  2009-04-10 04:51:37  No: 33970

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


Mr.XRAY  2009-04-10 14:20:03  No: 33971

このIMEの機能を使用する方法ですが,残念ながら,質問された方の希望である,
いわゆる「入力・確定された時点」というのはできませんね.

にしのさんの方法を使うしかないような気がします.


立ってるものは○でも…  2009-04-11 23:59:17  No: 33972

勝爺:「あ、マコト、そこのランプ取ってくれないか」
真琴:「これ? はい、ランプ、掃除するの?」
勝爺:「おぅ、ありがとぅ、磨いてキレイにな、…それから、ついでにソコの雑巾も」
真琴:「おじいちゃん、自分で取りにいけばいいじゃない、横着なんだから…はい、雑巾」
勝爺:「昔から言うだろぅ、"立ってるものは孫でも使え"ってな^^;」
真琴:「あのね、おじいちゃん、それって…」
春子:「おっはよ〜、タンポポも咲いて、春だよねぇ」
真琴:「おはようございます、…あの、ハルコさん、面白そうだからアタシもチョットやってみたんだけど…」
春子:「ン? ナニを?」
真琴:「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))^);

真琴:「通信で使うもの? それをココで?」
春子:「そぅよ、昔から言うでしょ? "立ってるものは猫でも使え"って」
真琴:「…あの、ハルコさん、それって…」


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加