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 同梱)
カナ漢字変換の際に,ローマ字入力とカナ入力を切り換えるサンプルです.
Delphi の入力コントロールには imeMode というプロパティがあり,入力モードを切り換えることができます.これは,下図のような内容を切り換えるもので,ローマ字入力とかな入力を切り換えるものではありません.
図1
ImeMode で設定可能な入力モード
仮想キーコードの VK_KANA を送信することによって日本語 IME の入力方式を切り換える方式です.
この設定はシステム全体の設定となります.アプリ単位ではありません.終了時に元に戻す処理はありません.注意してください.
本サンプルの TEdit の imeMode プロパティの値は imHira にしています.
図2
EXE 起動時の画面
図3
[切り換え] ボタンをクリック
[かな入力] になったので,起動時は [ローマ字入力方式]
図4
かな入力方式で入力中
copy code
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 操作例
copy code
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 .