Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2005年04月20日] [更新 2021年09月02日] Delphi サンプルプログラム集
450_ローマ字入力とかな入力の切換
動作確認等 Windows 10 ビルド 19042 + Delphi XE5(UP2) Pro + Microsoft IME
450_ChangeRomanKana.zip [2.6 MB] 2021年09月02日版 (EXE 同梱)







01_ローマ字入力とかな入力の切換え


カナ漢字変換の際に,ローマ字入力とカナ入力を切り換えるサンプルです.
Delphi の入力コントロールには imeMode というプロパティがあり,入力モードを切り換えることができます.これは,下図のような内容を切り換えるもので,ローマ字入力とかな入力を切り換えるものではありません.


図1
ImeMode で設定可能な入力モード

仮想キーコードの VK_KANA を送信することによって日本語 IME の入力方式を切り換える方式です.
この設定はシステム全体の設定となります.アプリ単位ではありません.終了時に元に戻す処理はありません.注意してください.
本サンプルの TEdit の imeMode プロパティの値は imHira にしています.


図2
EXE 起動時の画面
図3
[切り換え] ボタンをクリック
  • [かな入力] になったので,起動時は [ローマ字入力方式]
図4
かな入力方式で入力中

リスト1
ローマ字入力とかな入力の切換
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
  Vcl.Buttons;

type

  TForm1 = class(TForm)
    Edit1: TEdit;
    SpeedButton1: TSpeedButton;
    Panel1: TPanel;
    procedure SpeedButton1Click(Sender: TObject);
  private
    { Private 宣言 }
    procedure CheckInputMethod;
    function IsImmOpen(AWnd: HWND): Boolean;
    procedure SetImmOnOff(AWnd: HWND; AOnOff: Boolean);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Winapi.Imm;

{$R *.DFM}

//=============================================================================
//  かな漢字入力方式の切換え(トグル)
//=============================================================================
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  LisOpen : Boolean;
begin
  // VK_KANA を送信すると IME が ON になるのでその対策
  LisOpen := IsImmOpen(Handle);

  // VK_KANA を送信
  // この後すぐに入力方式を検出するのでメッセージキューを直ちに処理
  Keybd_event(VK_KANA, MapVirtualKey(VK_KANA, 0), 0, 0);
  Keybd_event(VK_KANA, MapVirtualKey(VK_KANA, 0), KEYEVENTF_KEYUP, 0);
  Application.ProcessMessages;

  // 現在の入力方式を検出して表示
  CheckInputMethod;

  // IME の ON / OFF の状態を元に戻す
  SetImmOnOff(Edit1.Handle, LisOpen);
end;

//-----------------------------------------------------------------------------
//  [ローマ字入力] [かな入力] かを検出して表示
//-----------------------------------------------------------------------------
procedure TForm1.CheckInputMethod;
begin
  if (GetKeyState(VK_KANA) and 1) = 0 then begin
    Panel1.Caption := '現在の入力方式 : ローマ字';
  end else begin
    Panel1.Caption := '現在の入力方式 : かな';
  end;
end;

//-----------------------------------------------------------------------------
//  IME の ON / OFF を検出
//-----------------------------------------------------------------------------
function TForm1.IsImmOpen(AWnd: HWND): Boolean;
var
  LhImc : HIMC;
begin
  LhImc := ImmGetContext(AWnd);
  try
    Result := ImmGetOpenStatus(LhImc);
  finally
    ImmReleaseContext(AWnd, LhImc);
  end;
end;

//-----------------------------------------------------------------------------
//  IME の ON / OFF を設定
//-----------------------------------------------------------------------------
procedure TForm1.SetImmOnOff(AWnd: HWND; AOnOff: Boolean);
var
  LhImc : HIMC;
begin
  LhImc := ImmGetContext(AWnd);
  try
    ImmSetOpenStatus(LhImc, AOnOff);
  finally
    ImmReleaseContext(AWnd, LhImc);
  end;
end;

end.




02_ローマ字入力とかな入力の切換えのショートカットキー


上のコードには,現在の入力方式が「ローマ字入力] か [かな入力] かを表示するための処理が含まれています.実際に切り換えに必要なのは以下のコードだけです.
TSpeedButton を使用しているのは,フォーカスの移動を回避するためです.


//=============================================================================
//  かな漢字入力方式の切換え(トグル)
//  自アプリの IME が OFF の時は ON になる
//  IME が ON になる時 [IME 入力モード切替の通知] を表示する
//=============================================================================
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  Keybd_event(VK_KANA, MapVirtualKey(VK_KANA, 0), 0, 0);
  Keybd_event(VK_KANA, MapVirtualKey(VK_KANA, 0), KEYEVENTF_KEYUP, 0)
end;


以下のコードも入力方式の切り換えに使用できます.どちらも自アプリでは自動的に IME が ON になりますが,下に示すコードでは [IME 入力モード切替の通知] の「A」や「あ」を表示しません.$F2 は,[カタカナ / ひらがな / ローマ字] キーの仮想キーコードの値です.


//=============================================================================
//  かな漢字入力方式の切換え(トグル)
//  自アプリでは,IME が OFF の時は ON になる
//  IME が ON になる時 [IME 入力モード切替の通知] を表示しない
//
//  [Shift] + [Ctrl] + [ひらがな] をエミュレート
//  $F2 は,[カタカナ / ひらがな / ローマ字] キーの仮想キーコードの値
//=============================================================================
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
  Keybd_event(VK_SHIFT,   MapVirtualKey(VK_SHIFT, 0),   0, 0);
  Keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
  Keybd_event($F2,        MapVirtualKey($F2, 0),        0, 0);

  Keybd_event($F2,        MapVirtualKey($F2, 0),        KEYEVENTF_KEYUP, 0);
  Keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);
  Keybd_event(VK_SHIFT,   MapVirtualKey(VK_SHIFT, 0),   KEYEVENTF_KEYUP, 0);
end;


シュートカットキー [A;t] + [ひらがな] も入力方式の切り換えに使用できますが,これは IME が ON の状態の時にだけ使用可能です.このショートカットキーを実行すると,下図のダイアログが現れます.このダイアログで [はい] をクリックします.[今後、このダイアログを表示しない] をチェックすればこのダイアログは現れなくなります.
もし,[今後、このダイアログを表示しない] をチェックして [いいえ] を選択すると,それ以後,このショートカットキーは使用できなくなります.つまり,常に [いいえ] を選択することと同じになります.元の状態に戻すには,IME のプロパティの設定ダイアログで [すべての設定を標準状態に戻す] の操作をします.すると,すべてのプロパティが初期の状態になります.



図5
切り換え確認のダイアログ
  • [今後、このダイアログを表示しない] をチェックして [いいえ] をクリックすると、ショートカットキーが無効になる

//=============================================================================
//  かな漢字入力方式の切換え(トグル)
//  IME が ON の時だけ有効
//
//  [Alt] + [ひらがな] をエミュレート
//  VK_MENU は [Alt] キーの仮想キーコード
//  $F2 は,[カタカナ / ひらがな / ローマ字] キーの仮想キーコードの値
//=============================================================================
procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
  Keybd_event(VK_MENU, MapVirtualKey(VK_MENU, 0), 0, 0);
  Keybd_event($F2,     MapVirtualKey($F2, 0),     0, 0);

  Keybd_event($F2,     MapVirtualKey($F2, 0),     KEYEVENTF_KEYUP, 0);
  Keybd_event(VK_MENU, MapVirtualKey(VK_MENU, 0), KEYEVENTF_KEYUP, 0);
end;


//=============================================================================
//  かな漢字入力方式の切換え(トグル)
//  IME が ON の時だけ有効
//
//  $F5 = [Alt] + [ひらがな] をエミュレート
//=============================================================================
procedure TForm1.SpeedButton4Click(Sender: TObject);
begin
  Keybd_event($F5, MapVirtualKey($F5, 0), 0, 0);
  Keybd_event($F5, MapVirtualKey($F5, 0), KEYEVENTF_KEYUP, 0);
end;


[備考 1]
[Alt] + [ひらがな] のショートカットキーは,Windows 10 ビルド 2004 以降ではデフォルトで無効になっています.Microsoft IME のプロパティを変更しないと利用できません.


[備考 2]
[IME 入力モード切替の通知] の機能は,Windows 10 ビルド 2004 の Microsoft IME でば実装されなくなりました.2004 よりも前のバージョンでは,プロパティの設定によって表示しないようにできます.





03_他のアプリの日本語 IME の ON / OFF 操作


最初のサンプルで,日本語 IME の ON / OFF の操作を行っています.WM_IME_CONTROL メッセージを使用すると,他のアプリの IME の ON / OFF の操作ができます.その例です.
このサンプルではメモ帳を操作しています.メモ帳を起動してから実行してください.
これらの Windows API による設定は恒久的な設定ではありません.操作対象のアプリを閉じると元の日本語 IME の設定に戻ります.



図6
他のアプリの日本語 IME の ON / OFF 操作

リスト2
他のアプリの日本語 IME の ON / OFF 操作例
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

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

  function IsImeOnWnd(AWnd: HWND): Boolean;
  procedure ImeOnOffWnd(AWnd: HWND; IsOn: Boolean);

var
  Form1: TForm1;

implementation

uses
  Winapi.Imm;

{$R *.dfm}

const
  IMC_GETCONVERSIONMODE = $01;
  IMC_SETCONVERSIONMODE = $02;
  IMC_GETOPENSTATUS     = $05;
  IMC_SETOPENSTATUS     = $06;

//=============================================================================
//  他のアプリの日本語 IME を ON にする
//  対象のアプリをアクティブにしなくても操作可能
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LTargetWnd : HWND;
begin
  LTargetWnd := FindWindow('notepad', nil);
  if LTargetWnd = 0 then begin
    MessageBox(Handle, 'メモ帳が起動していません。', '情報', MB_ICONINFORMATION);
    Exit;
  end;

  ImeOnOffWnd(LTargetWnd, True);
end;

//=============================================================================
//  他のアプリの日本語 IME を OFF にする
//  対象のアプリをアクティブにしなくても操作可能
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LTargetWnd : HWND;
begin
  LTargetWnd := FindWindow('notepad', nil);
  if LTargetWnd = 0 then begin
    MessageBox(Handle, 'メモ帳が起動していません。', '情報', MB_ICONINFORMATION);
    Exit;
  end;

  ImeOnOffWnd(LTargetWnd, False);
end;

//=============================================================================
//  他のアプリの入力モードを [全角カタカナ] にする
//  対象のアプリをアクティブにしなくても操作可能
//  対象のアプリの日本語 IME が ON の時に有効になる
//
//  入力モードは,Delphi ではコントロールの imeMode プロパティで設定できる
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
  LTargetWnd  : HWND;
   LhIMC     : HIMC;
  LConversion : DWORD;
begin
  LTargetWnd := FindWindow('notepad', nil);
  if LTargetWnd = 0 then begin
    MessageBox(Handle, 'メモ帳が起動していません。', '情報', MB_ICONINFORMATION);
    Exit;
  end;

  LhImc := ImmGetDefaultIMEWnd(LTargetWnd);
  LConversion := IME_CMODE_NATIVE or IME_CMODE_FULLSHAPE or IME_CMODE_KATAKANA;
  SendMessage(LhImc, WM_IME_CONTROL, IMC_SETCONVERSIONMODE, LConversion);
end;

//-----------------------------------------------------------------------------
//  他のアプリの日本語 IME の ON / OFF を調べる
//  自アプリにおける検出は不可
//-----------------------------------------------------------------------------
function IsImeOnWnd(AWnd: HWND): Boolean;
var
  LhIMC : HIMC;
begin
  LhImc  := ImmGetDefaultIMEWnd(AWnd);
  Result := Boolean(SendMessage(LhImc, WM_IME_CONTROL, IMC_GETOPENSTATUS, 0));
end;
//-----------------------------------------------------------------------------
//  他のアプリの日本語 IME を ON / OFF を切り換える
//  自アプリに対する操作は不可
//-----------------------------------------------------------------------------
procedure ImeOnOffWnd(AWnd: HWND; IsOn: Boolean);
var
  LhIMC : HIMC;
begin
  LhImc := ImmGetDefaultIMEWnd(AWnd);
  SendMessage(LhImc, WM_IME_CONTROL, IMC_SETOPENSTATUS, LPARAM(IsOn));
end;

end.