Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2009年04月09日] [更新 2014年01月25日] Delphi サンプルプログラム集
452_[ ひらがな ] または [ カタカナ ] だけを入力させる
動作確認等 Windows 7 U64(SP1) + Delphi XE Pro + Micorsoft Office IME 2007
452_KanaOnlyInput.zip [1,088 KB] 2014年01月25日版 (EXE 同梱)







01_[ ひらがな ] または [ カタカナ ] だけを入力させる


カナ漢字入力時に「ひらがな」または「カタカナ」だけを入力させるサンプルです.
例えば氏名等の入力の際,ふりがなの部分を入力確定後にチェックしてもいいですが,入力時にふりがなだけしか入力させない,という考え方もできます.

このサンプルコードは,単に変換モードを [無変換] にしているだけです.したがって,実際には全角の英数字も入力できてしまいます.英数字も禁止するのであれば,例えば TEdit の OnChange イベント等で処理することになります.
文字列をコピーして貼り付ける場合も,「ひらがな」「カタカナ」以外の文字が入力できてしまいます.これも何らかの処理がが必要です.



[備考]
ImmGetConversionStatus 関数は,Windows 8 以降では正常に動作しません.




図1
設計時画面
図2
「ひらがな」だけ入力可能
図3
「カタカナ」だけ入力可能

リスト1
[ひらがな] または [カタカナ] だけを入力させる
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses IMM;

{$R *.dfm}

//=============================================================================
//  フォーム表示開始時の処理
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
  Edit1.ImeMode := imHira;
end;

//=============================================================================
//  Edit1の入力文字をひらがなのみとする
//  単に無変換にしているだけ
//  usesにIMMが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  Imc          : HIMC;
  dwConversion : DWORD;
  dwSentence   : DWORD;
begin
  //入力コントロールにフォーカス移動
  Edit1.SetFocus;
  Edit1.Clear;

  //IMEをオープン
  SetImeMode(Edit1.Handle, imOpen);
  //入力コンテキストを取得
  Imc := ImmGetContext(Edit1. Handle);

  try
    //パラメータを設定
    dwConversion := IME_CMODE_NATIVE or IME_CMODE_FULLSHAPE;
    dwSentence   := IME_SMODE_NONE;

    //IMEの状態を設定
    ImmSetConversionStatus(Imc, dwConversion, dwSentence);
  finally
    //ImmGetContextしたら必ず解放する
    ImmReleaseContext(Edit1.Handle, Imc);
  end;
end;

//=============================================================================
//  Edit1の入力文字をカタカナのみとする
//  単に無変換にしているだけ
//  usesにIMMが必要
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  Imc          : HIMC;

  dwConversion : DWORD;
  dwSentence   : DWORD;
begin
  //入力コントロールにフォーカス移動
  Edit1.SetFocus;
  Edit1.Clear;

  //IMEをオープン
  SetImeMode(Edit1.Handle, imOpen);
  //入力コンテキストを取得
  Imc := ImmGetContext(Edit1. Handle);

  try
    //パラメータを設定
    dwConversion := IME_CMODE_KATAKANA or IME_CMODE_NATIVE or IME_CMODE_FULLSHAPE;
    dwSentence   := IME_SMODE_NONE;

    //IMEの状態を設定
    ImmSetConversionStatus(Imc, dwConversion, dwSentence);
  finally
    //ImmGetContextしたら必ず解放する
    ImmReleaseContext(Edit1.Handle, Imc);
  end;
end;

end.




02_入力モードを強制的に変更


次のサンプルは,入力モードを途中で切り換えた場合に強制的に元のモードにしてしまう例です.
IME を OFF にした場合は入力できないようにしてみました.
TApplicationEvents コンポーネントの OnMessage イベントで処理しています.やり方はいろいろあると思いますが,1 つの方法です.



[備考]
ImmSetConversionStatus 関数は,Windows 8 以降では正常に動作しません.



図4
設計時画面

リスト2
[ひらがな] または [カタカナ] だけを入力させる
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, AppEvnts;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    ApplicationEvents1: TApplicationEvents;
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure ApplicationEvents1Message(var Msg: tagMSG;
      var Handled: Boolean);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
  private
    { Private 宣言 }
    HiraConv : Cardinal;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses IMM;

{$R *.dfm}

//=============================================================================
//  フォーム表示開始時の処理
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
  Button1Click(nil);
end;

//=============================================================================
//  Edit1の入力文字をひらがなのみとする
//  単に無変換にしているだけ
//  usesにIMMが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  Imc          : HIMC;
  dwConversion : Cardinal;
  dwSentence   : Cardinal;
begin
  //入力コントロールにフォーカス移動
  Edit1.SetFocus;

  //IMEをオープン
  SetImeMode(Edit1.Handle, imOpen);
  //入力コンテキストを取得
  Imc := ImmGetContext(Edit1.Handle);

  try
    //パラメータを設定
    dwConversion := IME_CMODE_NATIVE or IME_CMODE_FULLSHAPE;
    dwSentence   := IME_SMODE_NONE;
    //モードを保持しておく
    HiraConv := dwConversion;

    //IMEの状態を設定
    ImmSetConversionStatus(Imc, dwConversion, dwSentence);
  finally
    //ImmGetContextしたら必ず解放する
    ImmReleaseContext(Edit1.Handle, Imc);
  end;
end;

//=============================================================================
//  Edit1の入力文字をカタカナのみとする
//  単に無変換にしているだけ
//  usesにIMMが必要
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  Imc          : HIMC;
  dwConversion : Cardinal;
  dwSentence   : Cardinal;
begin
  //入力コントロールにフォーカス移動
  Edit1.SetFocus;

  //IMEをオープン
  SetImeMode(Edit1.Handle, imOpen);
  //入力コンテキストを取得
  Imc := ImmGetContext(Edit1.Handle);

  try
    //パラメータを設定
    dwConversion := IME_CMODE_KATAKANA or IME_CMODE_NATIVE or IME_CMODE_FULLSHAPE;
    dwSentence   := IME_SMODE_NONE;
    //モードを保持しておく
    HiraConv := dwConversion;

    //IMEの状態を設定
    ImmSetConversionStatus(Imc, dwConversion, dwSentence);
  finally
    //ImmGetContextしたら必ず解放する
    ImmReleaseContext(Edit1.Handle, Imc);
  end;
end;

//=============================================================================
//  ApplicationEvents1のOnMessageイベント処理
//
//  Edit1でキーが押下される度にIMEの状態をチェック
//  前に設定した(入力モードであるHiraConv)と異なる値だったら強制的に変更
//  usesにIMMが必要
//=============================================================================
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
var
  Imc          : HIMC;
  dwConversion : Cardinal;
  dwSentence   : Cardinal;
begin
  if Msg.message = WM_KEYDOWN then begin
    if Msg.hwnd=Edit1.Handle then begin
      //IMEがOFFならキー入力は無視
      if HiraConv = 0 then begin
        Msg.wParam := 0;
      end else begin
        //入力コンテキストを取得
        Imc := ImmGetContext(Edit1.Handle);
        try
          if ImmGetOpenStatus(Imc) then begin
            //入力モードを取得
            ImmGetConversionStatus(Imc, dwConversion, dwSentence);
            //前に設定した値と違う場合は再設定
            if dwConversion <> HiraConv then begin
              Msg.wParam   := 0;
              dwConversion := HiraConv;
              dwSentence   := IME_SMODE_NONE;
              //IMEの状態を設定
              ImmSetConversionStatus(Imc, dwConversion, dwSentence);
            end;
          end else begin
            //IMEをOFFにしてしまった場合のキー入力は無視
            Msg.wParam := 0;
          end;
        finally
          //ImmGetContextしたら必ず解放する
          ImmReleaseContext(Edit1.Handle, Imc);
        end;
      end;
    end;
  end;
end;

//=============================================================================
//  テンキーの設定が半角入力にしてある場合を考慮して入力禁止にする
//  上のApplicationEvents1Messageで処理してもよい
//=============================================================================
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if (Key >= '*') and (Key <= '=') then Key := #0;
end;

end.