Windows7とDelphiとImeMode

こちら掲示板での質問なんですが、Delphi2009のアプリをWindows7で動かすとImeModeをimDisableにしたEditコントロールにフォーカスが移動しても見た目が変わらないんですね。動作としてはちゃんとIMEが無効になってるんですけども。下の図のようにIMEを有効にした状態からimDisableなEditにフォーカスが移動しても見た目が変わりません。

結構IMEの見た目というか、IMEのオンオフをマウスクリックで切り替えたりする人もいる事を考えると、この問題は中々に困った事になる可能性もあります。そして残念ながらこの問題は、DelphiXEでも発生します。
という事でQCに登録しましたので、気になる方はvoteよろしくお願いします。

Report No: 94701 Status: Open
When a focus moved to Edit box(ImeMode=imDisable), IME does not become the disabled showing in Windows 7.
http://qc.embarcadero.com/wc/qcmain.aspx?d=94701
QCWIN:Defect_No=94701

原因は恐らくIMEの有効/無効の切り替えにWINNLSEnableIMEを使ってるからじゃないかと思います。この関数いつからかは判りませんがobsoleteに成ってるんですね。

一応の解決法は掲示板に投稿した通り以下をFormの宣言の前に追加するんですが、カナロックに関する部分はIMEによる気がするんで省いておきます。

  TEdit = class(StdCtrls.TEdit)
  private
    FOldIMC: HIMC;
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  public
    destructor Destroy; override;
  end;

destructor TEdit.Destroy;
begin
  if FOldIMC <> 0 then
    ImmAssociateContext(Handle, FOldIMC);
  inherited;
end;

procedure TEdit.WMKillFocus(var Message: TWMKillFocus);
begin
  inherited;
  if ImeMode=imDisable then
  begin
    if FOldIMC <> 0 then
    begin
      ImmAssociateContext(Handle, FOldIMC);
      FOldIMC := 0;
  end;
end;

procedure TEdit.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;
  if ImeMode = imDisable then
  begin
    FOldIMC := ImmAssociateContext(Handle, 0);
  end else begin
    if FOldIMC <> 0 then
    begin
      ImmAssociateContext(Handle, FOldIMC);
      FOldIMC := 0;
    end;
  end;
end;

ただ、この問題TWinControlに問題があるので入力を受け付けるコントロールはTEditだけで無く全て影響を受けると思います。TWinControlを修正出来ればそれが一番簡単なんですが残念ながらソースを直接書き換える以外の方法が思い浮かびません。良い方法があれば教えて下さい。
というわけで、上の方法を使う場合はimDisableを使用するコントロール全てについて処理を置き換える必要があります。

2011/10/06追記

DelphiXE2 Update1で修正されてるのを確認しました。無印のXE2で修正されてたのかは確認忘れてたので判りません。