他のアプリのIMEの制御

解決


FUJI  2010-11-25 18:42:31  No: 39596

他のアプリの入力補助をするプログラムを作りたいと考えています。
(例えば、カタカナの半角・全角制御などです。)
次のプログラムを作りましたが、IMEのON/OFFを得られません。
どなたか何かご存知でしょうか。

function GetImeStatus(Hdl: HWND): boolean;
  var
    imc : HIMC;
  begin
    imc := ImmGetContext(Hdl);
    try
      if ImmGetOpenStatus(imc) then
        result := True
      else
        result := False;
    finally
      ImmReleaseContext(Hdl, imc);
    end;
  end;


けど  2010-11-26 07:28:40  No: 39597

SpeedButton(Buttonは不可) と Memo を貼り付けた状態の
OnClick イベントハンドラ

uses IMM;
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  imc: HIMC;
begin
  imc := ImmGetContext(Handle);

  if ImmGetOpenStatus(imc) then
    Memo1.Lines.Add('IME on')
  else
    Memo1.Lines.Add('IME off');

  ImmReleaseContext(Handle, imc);
end;

Memo1 をクリックして(アクティブにして)から IME ON/OFF にて確認

D5+vista32+ATOK2010


けど  2010-11-26 07:29:34  No: 39598

すんません、読み違えてた
忘れてください


FUJI  2010-11-26 10:17:35  No: 39599

けどさん、試していただいてありがとうございます。
「他のアプリ」上で動作しているIMEの制御をしたいので、
例えば、メモ帳の日本語入力を制限するとか、です。

当方の環境は、WindowsXP + Delphi7 です。


Mr.XRAY  2010-11-26 15:10:32  No: 39600

こんにちは.Mr.XRAYです.

>当方の環境は、WindowsXP + Delphi7 です。

ということですので,同じ環境で以下のコードをテストしてみました.

>IMEのON/OFFを得られません。

ということですが,その前に,imc の値が取得できないハズです.
他のアプリのIMEの状態取得や設定は,提示された関数ではできません.
(他のアプリの操作関係は難しいです)
そこで,IMEはデフォルトのものと仮定し,考えられるのはメッセージ処理です.

これ以外のメッセージについては,MSDNの記事を参考にしてください.
IME関係は,WM_IME_XXXXX となっています.
では,健闘をお祈りいたします.

//=============================================================================
//  ハンドルがhMemoEditのIMEのON,OFFを調査
//  メモ帳の場合,メモ帳のハンドルではなく編集コントロールのハンドルなので注意
//  またシステムのデフォルトのIMEを使用していると仮定
//  usesにIMMが必要
//
//  WM_IME_CONTROL等のメッセージについてはMSDNの記事を参照
//  例えばWM_IME_CONTROLは
//  http://msdn.microsoft.com/en-us/library/ms906448.aspx
//  定数値はMicrosoft SDKのヘッダファイル(拡張子は.h)を参照
//  IME関係はimm.h
//  Microsoft SDKのダウンロードリンクは以下の記事を参照
//  http://mrxray.on.coocan.jp/Delphi/CompoInstall/TypeLibraryDD.htm#02
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
  IMC: HIMC;
begin
  IMC := ImmGetDefaultIMEWnd(hMemoEdit);

  if LongBool(SendMessage(IMC, WM_IME_CONTROL, IMC_GETOPENSTATUS, 0)) then begin
    Memo1.Lines.Add('IME ON')
  end else begin
    Memo1.Lines.Add('IME OFF')
  end;
end;


Mr.XRAY  2010-11-26 15:43:45  No: 39601

失礼.ちょっと訂正

>他のアプリのIMEの状態取得や設定は,提示された関数ではできません.

同じスレッド,同じプロセス内であれば可能なようです.
今回は,既に起動しているメモ帳が対象と解釈しました.


FUJI  2010-11-26 18:04:08  No: 39602

Mr.XRAYさま、回答ありがとうございます。
ホームページいつもお世話になっております。
お陰さまで上手く動作しました。

他の方へ、参考までに、以下、私のコードです。

function GetImeStatus(Hdl: HWND): boolean;
  var
    IMC: HIMC;
  begin
    IMC := ImmGetDefaultIMEWnd(Hdl);

    if LongBool(SendMessage(IMC, WM_IME_CONTROL, 
                            5{IMC_GETOPENSTATUS}, 0)) then begin
      result := True
    end else begin
      result := False;
    end;
  end;

{///   IMEの起動(※上手くいかない 2010.11.25 FUJI)   ///}
procedure SetImeStatus(Hdl: HWND; OnOff: boolean);
  var
    IMC: HIMC;
  begin
    IMC := ImmGetDefaultIMEWnd(Hdl);

    SendMessage(IMC, WM_IME_CONTROL, 
                6{IMC_SETOPENSTATUS}, Ord(OnOff));
  end;


解決  2010-11-26 18:05:11  No: 39603

チェック忘れました。


注意!  2010-11-26 18:06:45  No: 39604

上のコードの次のコメントは無視してください。

{///   IMEの起動(※上手くいかない 2010.11.25 FUJI)   ///}


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加