delphi2009のIME制御についで教えてください。
Win Xp-Pro上でDelphi2009によりFormにEdit1、Edit2を作ります。
Edit1は、英数字のみを入力するため、ImeModeをimDisableに、
Edit2は、全ての文字種を受け入れる為、ImeModeをimDontCareに設定します。
IMEはMsのNatural Input 2002 ver2.1です。
このとき、Edit2でのImeの入力モードがなんであっても、Kanaキーロックがいずれでも
Edit2からEdit1へFocusgが移ると、Edit1でのIMEは、半角英数入力になります。
これは、望んでいる動作です。
ところが、このEXEをWin7のPCへインストールすると
Edit2からEdit1へFocusが移ったときのIMEの入力モードはWin Xpと動作が異なります。
たとえば、
Edit2が、ひらがな入力で、Kanaキーロックが外れているときにEdit1へFocusが移動するとIMEはひらがな入力のままですが、入力は半角英数になります。
また、Edit2が、ひらがな入力で、Kanaキーロックが外れていないときにEdit1へFocusが移動するとIMEはひらがな入力のままで、入力は半角カタカナになってしまいます。
納得いかないのは、Edit1での入力モードの表示が入力値と合っていない。
Kanaキーロックの状態のかかわらず、英数入力にならないの2点です。
これは、自分のPCだけではなく、友人のPCのWin7でも同じになります。
これを、Win Xpと同じように動作するようにするにはどのようにすればよいでしょうか。
よろしくお願いいたします。
サトウ
私なら
Edit1は、英数字のみを入力するため、ImeModeをimCloseに、
Edit2は、全ての文字種を受け入れる為、ImeModeをimHiraなど頻度の多い状態に設定します。
かずさん こんばんは
見ていただいてありがとうございます。
でも、ちょっと私が問題としている点とちょっと違っているようです。
ImeModeをimCloseにすると、ユーザーは自分でIMEをOpenできてしまいます。
また、Edit2は、ユーザの好みにによって漢字で入力したり、かなで入力したりと、その人の好みに任せたいと考えていますので、imHiraに決め付けたくないのでimDontCareを選んでいます。
いろいろ、自分でも調べていますが、Keybd_eventコマンドでできるかなと確かめてみましたが、WinXPでは動いてくれますがWin7ではやっぱり望んだようにうごいてくれません。
メーカのHPを見ると、Delphi2010がWin7対応と出ていましたが、そのためでしょうか?
もう少し、自分でも確かめたいと思っています。
サトウ
フォームの変数に
FPrevIME: HIMC;
を追加して、FormのOnCreate辺りで
FPrevIME := ImmAssociateContext(Edit1.Handle, 0);
OnDestroyで
ImmAssociateContext(Edit1.Handle, FPrevIME);
てやれば、とりあえずIMEを無効には出来ますね。ただカナロックに関しては変わらないです。
で、このIMEの挙動に関してはXEでも一緒ですね。
先のやり方だとEditが作り直された時なんかに対応出来ないのと、入れ替えた入力コンテキストが中に浮いちゃうのでまずい気がします。
ちゃんとやるなら、Editを継承したのを作るしかないのかも。SetIMEとResetIMEがvirtualなら良かったんですがね
私の場合は、漢字入力を行う可能性があるEdit等からフォーカスが外れる時に
強制的にIMEをオフにしてしまっています。
私もかずさんの様に漢字入力を行う項目ではImeModeをimHiraにしてしまうので
これでも問題はありませんが、サトウさんの場合はEdit2でIMEをオンにした後
Edit1に移動し、さらにEdit2に戻った時にIMEがオンに戻って欲しいのならば
ちょっと工夫がいるかもしれません。
ちなみにIMEをオフにするには下記のイベントをOnExitに割り当てています。
usesにImmの追加が必要です。
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
procedure CustomEditExit(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
procedure TForm1.CustomEditExit(Sender: TObject);
var
imc: HIMC;
begin
imc := ImmGetContext((Sender as TWinControl).Handle);
if imc <> 0 then
begin
if ImmGetOpenStatus(imc) then
ImmSetOpenStatus(imc, False);
ImmReleaseContext((Sender as TWinControl).Handle, imc);
end;
end;
かなり無理矢理ですけど下みたいな感じかな。
TFormの宣言の前に追加してください。
TEdit = class(StdCtrls.TEdit)
private
FOldIMC: HIMC;
FKanaMode: Boolean;
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;
if FKanaMode And ((GetKeyState(VK_KANA) And 1) = 0) then
begin
keybd_event(VK_KANA, 0, 0, 0);
keybd_event(VK_KANA, 0, KEYEVENTF_KEYUP, 0);
end;
end;
end;
end;
procedure TEdit.WMSetFocus(var Message: TWMSetFocus);
begin
inherited;
if ImeMode = imDisable then
begin
FOldIMC := ImmAssociateContext(Handle, 0);
FKanaMode := (GetKeyState(VK_KANA) And 1) = 1;
if FKanaMode then
begin
keybd_event(VK_KANA, 0, 0, 0);
keybd_event(VK_KANA, 0, KEYEVENTF_KEYUP, 0);
end;
end else begin
if FOldIMC <> 0 then
begin
ImmAssociateContext(Handle, FOldIMC);
FOldIMC := 0;
end;
end;
end;
AUさん、QUESTさん ありがとうございます。
今会社から帰ってきたばかりで、確認は明日の晩に行います。
ただ、日曜素人プログラマーには少し難しそうですね。
今日、動きを確認してみました
IMEのOn/Off、Kanaロックとも望んだ動きをしました。ただ、なぜそのように動くかが理解できていませんので、これからHelp等をあさって見ます。
AUさん、QUESTさんありがとうございます。
なんとかAUさんのコードを読み解きました。
しかし、ImmAsociateContextが理解できません。多分IMEの制御情報だろうとおもい、ネットで検索してみましたが、私の理解の範囲を明らかに超えています。これ以上追わないことにします。(笑)
それと、AUさんのコードからコンポーネントを新たに作成しないで、一時的にカスタマイズする方法を知りました。これは私にとって非常に使いでのある手法です。今後使わせていただきます。
AUさん、QUESTさん ありがとうございます。
一応IMEの表示が変わらない件についてQCに登録しておきました。
http://qc.embarcadero.com/wc/qcmain.aspx?d=94701
Delphi2009はWin7対応してないよって言われちゃったので修正はされないでしょうけど、XEの方は修正して欲しいですねぇ。
カナロックに関しては、XPでもATOKだとロック効いたままになったりしたのでIMEによって動作が違うのかもしれません。
XEとWin7との環境だけでチェックしてくれるようですね。
まあ しょうがないですね。
でも、ここ数年毎年のようにUpgradeがあると、仕事で使っている人はいいとしても個人的使っている人にはつらいものがあります。
Delphiを使っている人は、Delphiに惚れて使っていることと思われます。Delphiから離れていく人がでないような施策を打ってほしいですね。
ツイート | ![]() |