by Michael S. Kaplan, published on 2008/03/20 09:01 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2008/03/20/8326152.aspx
Content of Michael Kaplan's personal blog not approved by Microsoft (see disclaimer)!
The other day, Qian asked me via the Contact link:
Hi Michael,
I've been reading your blog for the past several months and find it really helpful. I've been able to crush several quite puzzling bugs just by reading the archives. Thank you for sharing such valuable knowledge.
I wonder if you can shed some light on a problem I've come across. I've been trying to use the ImmIsIME function to determine if the currently active input language uses an IME. I've got a plain US English XP (32-bit) system with the Simplified Chinese Pinyin IME installed. And in my code I'm doing the following:
HKL hKeyLayout = GetKeyboardLayout(0);
BOOL bIsIME = ImmIsIME(hKeyLayout) != 0;
If I look at the HKL value, I see that I get 0x4090409 for the English layout and 0x8040804 for the Chinese. But I get TRUE for ImmIsIME for both of them.
This didn't seem right to me, so I googled a bit and found this thread:
http://groups.google.com/group/microsoft.public.win32.programmer.international/browse_thread/thread/6431db45bf81e718/e8111909da418549?hl=en&lnk=st&q=ImmIsIme#e8111909da418549
In it you said,
"All IME's have a 0xE000000 prefix in front of them when you look at the HKL value. You can easily use the GetKeyboardLayout API to retrieve the active keyboard layout and test for whether it has such a prefix in the HKL."
And the OP of the thread indicated that this method worked for him. He was using a Japanese IME on an English XP system, so I installed the Japanese IME and got an HKL value of 0x4110411 for the Japanese layout. Obviously neither the Japanese nor the Chinese HKL on my system had an 0xE000000 prefix, so this test for IME didn't work either.
I haven't been able to find any information on why ImmIsIME would return TRUE for the US English layout. I've also not been able to find any other references to the 0xE000000 prefix. Do you see anything that I'm doing wrong or have any insight into why I'm not getting the expected values here?
I've also tested my code on Vista (32 and 64-bit) with exactly the same results. So if I'm screwing up somewhere, at least I'm doing it consistently. :)
I'd greatly appreciate any pointers you can give me on this. And thanks again for all the great info on your blog.
Best,
Qian
Well, I guess it can't ever hurt to have people say nice things about you, especially when you're feeling under-valued. :-)
In this case the problem is once again that the move from the IMM (Input Method Manager) based to the TSF (Text Services Framework) based IMEs has made an old behavior one could rely on go away forever. :-(
There are now a huge ton of IMEs that do not follow that "E" prefix rule, since their support is entirely through TSF now.
Now if one knows all of the GUIDs and such one could probably use ITfInputProcessorProfiles::IsEnabledLanguageProfile to see if the IME in question is enabled, and one could probably use ITfInputProcessorProfiles::EnumInputProcessorInfo to enumerate all of the Input Processor Profiles on the machine and look for the one that was desired here.
But the real problem is not answering this one particular question.
It is that there is no link in documentation between the Input Method Manager and the Text Services Framework.
Not even a notice to developers that lots of the IMM won't work anymore.
Let alone a huge map akin to the Microsoft Win32 to Microsoft .NET Framework API Map that I mentioned here and suggested corrections to here.
Let alone what would best of all, which would be a little link in each Input Method Manager topic that provided the best way to accomplish the same thing in the Text Services Framework.
People over here talk all the time about gaps in international support, but calling this lack of information not only in how to migrate but in the fact that migration is needed is a lot more than a gap. It's a huge chasm!
And this problem is not one you can just aim a doc writer at -- not even a doc writer ninja or doc writer ninja II. This requires developers and testers, people who actually know the answers to the questions here and who know enough about the IMM "wrappers" put in for compatibility that they could even find and perhaps fix bugs in the current backcompat work that happens.
There is an old story about the four friends -- Everybody, Anybody, Nobody and Somebody. There was an important job to be done and Everybody was sure that Somebody would do it. In truth, Anybody could have done it, but Nobody did it. Somebody got angry about that because it was Anybody's job and the fact that Nobody did it was incredibly irresponsible (something that Everybody knew). In the end, Nobody did the work and Everybody got blamed for not taking responsibility.
I just wonder how long these four friends are going to rule the IMM/TSF documentation situation?
I don't want to minimize the importance of this prolem with humor, and to be honest I wish more developers around the world and especially in East Asia would complain about this more loudly and force Microsoft to do something about it. The lack of assistance here is unpardonable considering the sizes of the markets affected....
This blog brought to you by ꇥ (U+a1e5, aka YI SYLLABLE GAP)
Qian on 20 Mar 2008 11:23 AM:
Michael, thank you for replying to my message. I had figured out that the problem was caused by the IMM/TSF transition little while back after rereading some of the IME releated posts that you made before. Another score for the archives. But I'll definitely check out IsEnabledLanguageProfile and see if that'll do the trick. When I last looked at the TSF docs, my feeling was that it was too much trouble to go through to accomplish what I wanted (the feature's not a must have). Also, since TSF may not be installed on Win2000, I'd still need the IMM code as well. Like you said, there's definitely a chasm in the documentation. I'm just glad I have to option of punting the problem for now.
Ankur Mohan on 7 Apr 2008 6:38 PM:
Hello Michael,
your posts on IME/Keyboard related stuff have been extremely useful for me as well. I'm working on implementing our own IME UI for windows XP and Vista. This requires obtaining information from Windows about the contents of different IME windows (reading window, candidate window etc) and then displaying them properly using our rendering pipeline.
I've used IMM for implementing IME on Windows XP and TSF for Vista. However, after installing Office 2007 and all the Language packs for it (which replace some of the existing IME's), I find that the new IME's are hopelessly broken- as in, some of the important information such as candidate list contents is never sent. The behaviour of these IME's also seem suspiciosly similar to Vista IME's, which makes me thing that I should use TSF with these newer IME's. However, I haven't been able to use TSF successfully on XP- specifically, a pointer to ThreadManagerEx interface that's needed for IME implementation using TSF can't be obtained on XP- QI'ng the ThreadManager for IID_ITfThreadMgrEx always returns No_Interface..
Documentation for ThreadManagerEx says that it's implemented on XP..any ideas?
referenced by