2011年12月20日火曜日

Windows7 のアプリ互換問題について( IME 問題 )

Windows 7 のアプリ互換問題について( IME 問題 )


仮想化したアプリを Windows 7 32Bit版で動かした場合に
IME にからむ問題が発生する事があります。


具体的には、Excel 2000 , Access 2000 , Word 2000
VB5 / VB6で開発されたアプリ
GrapeCity 社製の入力拡張系 ActiveX / OCX
InputMan Pro 等を利用している場合等

どのような問題かというと
入力モードを、入力欄に合わせて切り替えるアプリや
変換候補を取得したり、半角カタカナや全角、日本語入力ONや
直接入力に切り替える場合です。

------宣伝-----
※VMware ThinApp (アプリケーション仮想化)に興味のある方は、こちらを
御覧ください。

[VMware ThinApp 製品概要と活用 解説書 (日本語 SoftBankBB製) の紹介]

http://tunemicky.blogspot.jp/2013/08/vmware-thinapp-softbankbb.html
------宣伝-----


対処方法としては、IMM32 に対応している IME を利用することになります。
・ Google IME
・ MS-IME 2010 [テキストサービスを使用しない]に設定
・ ATOK 2010 まで
・ ATOK 2011 からは、[テキストサービスを使用しない]に設定


※2012/02 追加情報 Windows7 SP1 64Bit版では、何もしなくても問題なく動作しました。


※ Windows Vista / 7 標準の IME では対応できません。
  また、MS-IME 2007も対応できません。
Google IMEはバージョンにより、IMM32とTSFの2つがあるようです。
Google IMEの問題と言うか、実装方法とその影響度をかなり考えてくれていることが
垣間見えるかと思います。ちなみに今このBlogを書いているIMEはGoogleIMEです。
http://googlejapan.blogspot.com/2010/11/google-0135210-0135371.html

 もちろん、コードを改修してTSF 対応にする方が良いですが。

何故このような事が発生するか、調べたところ、以下の NyaRuRu さんのBlogに
素敵な内容があったので紹介させていただきます。

TSF を使う (1) - Windows Input Method の歴史
http://d.hatena.ne.jp/NyaRuRu/20070309/p1

Windows Vista IMM32 関係まとめ
http://d.hatena.ne.jp/NyaRuRu/20070308/p1


まとめると、
Windows Vista から IME 操作系 API の標準実装が変更されました。
TSF に統一( Text Services Framework)

Windows XP の頃は、IMM32 による操作と TSF の2つ、
昔から熟れた実装方法としては IMM32 を利用することになり
Windows Vista / 7 での TSF も互換性を考慮し、ある程度 IMM32 の呼び出しを
エミュレートしてくれているようです。
しかしながら、全てを完璧にエミュレートしてくれているわけでは無いため
細かい制御を行った場合に、どうしても差異が発生してしまうようです。
DirectX を利用するゲームでは致命的な問題になっていたようです。


その教訓なのかはわかりませんが、Google IME では敢えて IMM32 をベースに実装を変更し、
MS-IME 2010 では IMM32 モードを復活させたようです。
ATOK も然りですね。

Office も 2000 までは IMM32 を利用していて、
OfficeXP (2002)からは TSF を利用するようになったようです。
そのため、Excel2000等をWindows 7で動作させるためには
IME操作の中核となる、IMEShare.dll等が必要だったりします。
http://www.mozilla-x86-64.com/archives/2005/06/how_to_get_ime.html


MS-IME 2010 の IMM32 モードへの変更方法
MS-IME 2010 での IMM32 利用方法ですが、プロパティ画面から
「その他」タブを選択し、「詳細なテキストサービス」から
「詳細なテキストサービスを使用しない」に変更し
Windows を再起動します。


蛇足的な IMM32 を利用したIME 制御 日本語ON/OFF(C++コード)
コンボボックスにFocusが当たった場合にIMEをOFFにして
Focusが外れた場合に、前の状態に戻す
(IMEがONだったらON戻す/元々OFFだったらそのままOFF)
※このコードはTSF環境でも正常に動作します。簡単なON/OFFしか行なっていないため。

#include "imm.h"
#pragma comment(lib, "imm32.lib") 
void CComboEdit::OnKillFocus (CWnd* pNewWnd)
{
 if(m_bIME)
 {
  HIMC hIMC = ::ImmGetContext(this->m_hWnd);
  ::ImmSetOpenStatus(hIMC,m_bIME);
  ::ImmReleaseContext(this->m_hWnd, hIMC);
 }
    CEdit::OnKillFocus (pNewWnd);
}
///////////////////////////////////////////////////////////////////////////////
void CComboEdit::OnSetFocus (CWnd* pOldWnd)
{
 HIMC hIMC = ::ImmGetContext(this->m_hWnd);
 m_bIME=::ImmGetOpenStatus(hIMC);
 if(m_bIME)
  ::ImmSetOpenStatus(hIMC, FALSE); // OFF
 ::ImmReleaseContext(this->m_hWnd, hIMC);
    CEdit::OnSetFocus (pOldWnd);
}




参考:
http://www.microsoft.com/japan/office/2010/ime/default.mspx
http://finali.sakura.ne.jp/akaneko/archives/tag/windows-7
http://d.hatena.ne.jp/NyaRuRu/20070309/p1
http://d.hatena.ne.jp/NyaRuRu/20070308/p1
http://www.ma.ccnw.ne.jp/tsmatsu/vista7.html
http://msdn.microsoft.com/ja-jp/library/cc422019.aspx