TComboBoxのIME制御

解決


サトウ  2014-04-22 06:08:45  No: 46276

TComboBoxのIME制御がうまくいきません。

環境:Win7 Pro & DelphiXE3 Update2

Form上にTEditを2つ、TComboBoxを1つ置き、FromのCreate時に
procedure TForm1.FormCreate(Sender: TObject);
begin
  Edit1.ImeMode     :=  imHira;
  ComboBox1.ImeMode :=  imDisable;
  Edit2.ImeMode     :=  imDisable;
end;
とIMEModeを設定しました。Tab順はEdit1,ComboBox1,Edit2の順です。

Edit1からComboBox1にFocusが移動しても、IMEがDisabeになりません。
ComboBox1からEdit2にFocusが移動すると、IMEはDisabeになります。
ComboBox1にFocusuがあるときに、半角キーを押すとDisableになります。

以前、TEditでも同様なことがあり、TEditのWMSetFocusでIME制御をかけて解決しました。
今回も、同様の解決方法で行おうとし、以下のコードを作成しました。

procedure TComboBox.WMSetFocus(var Message: TWMSetFocus);
var
  Imc          : HIMC;
  dwConversion : Cardinal;
  dwSentence   : Cardinal;
begin
  inherited;
  if ImeMode = imDisable then
    begin
    Imc := ImmGetContext(Handle);
    ImmGetConversionStatus(IMC, dwConversion, dwSentence);
    FKanaMode := (dwConversion or IME_CMODE_ALPHANUMERIC) <> 0;
    if FKanaMode then
      begin
      keybd_event(VK_KANA, 0, 0, 0);                     // 半角キー
      keybd_event(VK_KANA, 0, KEYEVENTF_KEYUP, 0);
      end;
    end;
end;

しかし、解決できませんでした。
ComboBoxは、Text部分とList部分から作られていると聞いています。
たぶんその関係だろうと想像はするのですが、私の理解力では解決できません。

解決のためのヒントをいただければ幸いです。


Mr.XRAY  2014-04-26 20:48:48  No: 46277

DelphiXE3 Update2 ですね.でしたら,
以下のような処理ではどうでしょうか.

begin
  if Sender = Edit1 then begin
    SetImeMode(Edit1.Handle, imHira);
  end else
  if Sender = ComboBox1 then begin
    Win32NLSEnableIME(ComboBox1.Handle, False);
  end else
  if Sender = Edit2 then begin
    SetImeMode(Edit2.Handle, imDisable);
  end;
end;


Mr.XRAY  2014-04-26 20:49:56  No: 46278

あら,最初の部分が...

procedure TForm1.Edit1Enter(Sender: TObject);
begin
  if Sender = Edit1 then begin
    SetImeMode(Edit1.Handle, imHira);
  end else
  if Sender = ComboBox1 then begin
    Win32NLSEnableIME(ComboBox1.Handle, False);
  end else
  if Sender = Edit2 then begin
    SetImeMode(Edit2.Handle, imDisable);
  end;
end;


サトウ  2014-04-29 08:06:31  No: 46279

Mr.Xrayさん  リプライありがとうございます。
以前にもお世話になりましたが、同様な件でまたお世話いただきありがとうございます。

Mr.Xrayさんの方法は、ComboBoxのOnEnterでWin32----を発行するものであろうと思い、実行してみましたが、IMEはDisableになりませんでした。

自分でも少しソースを見、ComboBoxのEdit部分に対しWin32----を発行してみたらどうかと思い、ComboboxのはんどるではなくEditHandleni対し発行してみましたが、やはりDisableにはなりませんでした。

とりあえずの対処として
procedure TComboBox.DoEnter;
begin
  inherited;
  if ImeMode = imDisable then
      begin
      keybd_event(25, 0, 0, 0);                     // 半角キー
      keybd_event(25, 0, KEYEVENTF_KEYUP, 0);
      end;
end;
でなんとか、Disableになりましたので、これで我慢します。
ただ、Shift+TabでEnterになるとやっぱりDisableになりませんがOKとします。

最終的には自分でもう少し調査し、なんとか対処します。
ありがとうございます。


Mr.XRAY  2014-04-29 09:50:23  No: 46280

>実行してみましたが、IMEはDisableになりませんでした。

オブジェクトインスペクタか,ほかの場所,他の場所,例えばフォームの OnCreate 等で
imDisable を使用していませんか ?
そもそも,imDisable の動作が正常に動作しないのですから,imDisable を使用してしまっては
意味がないことになりますが.
もし,間違っていたら,ゴメンナサイ.


Mr.XRAY  2014-04-29 17:02:34  No: 46281

遅くなりましたが,当方の動作確認環境です.

Windows 7 U64(SP1) + Delphi XE3(UP2) Pro + Microsoft Office IME 2010


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

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






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