Windows 7でTEdit/TMemoなどのコントロールのImeModeが動作しない
対象となるIDEのバージョン
- RAD Studio/C++Builder/Delphi 10 Seattle以降
対象となるWindowsのバージョン
- Windows 7
問題
10 Seattle以降では、Vcl.ControlsユニットのSetIMEModeメソッドの実装が修正され、内部でSetInputScope関数を呼び出すように変更されました。
これによってWindows 10+MS-IMEの組み合わせで、TEdit/TMemoなどのコントロールを利用したアプリケーションでは、ImeModeが適切に切り替わるようになりました。
ただし、SetIMEModeメソッドの修正の副作用としてWindows 7上でアプリケーションを実行した場合、IMEのON/OFFは切り替わりますが、ImeModeが機能しません。
解決
この問題を解決したい場合は、<製品のインストールフォル>¥source¥vcl¥Vcl.Controls.pasを自身のプロジェクトフォルダへコピーし、修正してください。
修正箇所は以下の通りです。
Vcl.Controls.pas
修正前:
procedure SetImeMode(hWnd: HWND; Mode: TImeMode);
..
..
if IsMSCTFAvailable then
SetInputScope( hWnd, InputSourceModeMap[Mode] )
else
begin
IMC := ImmGetContext(hWnd);
if IMC = 0 then Exit;
ImmSetOpenStatus(IMC, TRUE);
ImmGetConversionStatus(IMC, Conv, Sent);
Conv := Conv and (not(IME_CMODE_LANGUAGE or IME_CMODE_FULLSHAPE)) or ConversionStatusModeMap[Mode];
ImmSetConversionStatus(IMC, Conv, Sent);
ImmReleaseContext(hWnd, IMC);
end;
end;
修正後:
procedure SetImeMode(hWnd: HWND; Mode: TImeMode);
..
..
IMC := ImmGetContext(hWnd);
if IMC = 0 then Exit;
if IsMSCTFAvailable and TOSVersion.Check(6,2) then
begin
SetInputScope( hWnd, INputSourceModeMap[Mode] );
ImmReleaseContext(hWnd, IMC);
Exit;
end;
ImmSetOpenStatus(IMC, TRUE);
ImmGetConversionStatus(IMC, Conv, Sent);
Conv := Conv and (not(IME_CMODE_LANGUAGE or IME_CMODE_FULLSHAPE)) or ConversionStatusModeMap[Mode];
ImmSetConversionStatus(IMC, Conv, Sent);
ImmReleaseContext(hWnd, IMC);
end;
修正したVcl.Controls.pasの適用方法は、以下のドキュメントを参照してください。