by Michael S. Kaplan, published on 2008/02/03 10:46 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2008/02/03/7413169.aspx
If you are a regular reader, you may recall either Cutting the cord while someone else is shoring it up or Cutting the cord, revisited -- and documenting how to get the job done!, or maybe even both. Between them they pretty clearly show how the Text Services Framework has really been supplanting the former glory of
Anyway, in a comment to that second post, John Daintree noted another problem related to LoadKeyboardLayout:
Hi Michael,
Interesting stuff, thanks for talking through this. What I'm seeing on Vista is that if I call ActivateKeyboardLayout (or LoadKeyboardLayout), to activate an already installed layout, "at some time later" the keyboard reverts back to the default.
What seems to happen is that next time I get to the Message Queue something in msctf.dll (Text Services I guess) switches the layout back (C stack is attached). Do you have any ideas about what could be causing this?
What I've done here is put a breakpoint on a Window proc when it gets a WM_INPUTLANGCHANGE message.
The culprit seems to be:msctf.dll!PostInputLangRequest() + 0xc9 bytes
Thanks for your continued input (pardon the pun),
/john> dyalog.exe!Session_wnd_proc(HWND__ * hWnd=0x002608fc, unsigned int msg=0x00000051, unsigned int wParam=0x00000000, long lParam=0x08090809) Line 1879 C
user32.dll!_InternalCallWinProc@20() + 0x23 bytes
user32.dll!_UserCallWinProcCheckWow@32() + 0xb3 bytes
user32.dll!_CallWindowProcAorW@24() + 0x51 bytes
user32.dll!_CallWindowProcW@20() + 0x1b bytes
dyalog.exe!OwnerProc(HWND__ * hWnd=0x002608fc, unsigned int msg=0x00000051, unsigned int wParam=0x00000000, long lParam=0x08090809) Line 456 C
user32.dll!_InternalCallWinProc@20() + 0x23 bytes
user32.dll!_UserCallWinProcCheckWow@32() + 0xb3 bytes
user32.dll!_DispatchClientMessage@20() + 0x4b bytes
user32.dll!___fnDWORD@4() + 0x24 bytes
ntdll.dll!_KiUserCallbackDispatcher@12() + 0x2e bytes
user32.dll!_NtUserActivateKeyboardLayout@8() + 0xc bytes
msctf.dll!PostInputLangRequest() + 0xc9 bytes
msctf.dll!SyncActivateAssemblyByAsm() + 0x1b914 bytes
msctf.dll!SyncActivateAssembly() + 0x76 bytes
msctf.dll!ActivateAssemblyPostCleanupCallback() + 0x22 bytes
msctf.dll!CCleanupShared::~CCleanupShared() + 0x2a bytes
msctf.dll!CCleanupShared::`scalar deleting destructor'() + 0xd bytes
msctf.dll!CThreadInputMgr::_CleanupContextsWorker() + 0x69 bytes
msctf.dll!CThreadInputMgr::_CleanupContexts() + 0x38 bytes
msctf.dll!ActivateAssembly() + 0xa4 bytes
msctf.dll!SetFocusDIMForAssembly() + 0x5e bytes
msctf.dll!CThreadInputMgr::_SetFocus() + 0x133 bytes
msctf.dll!SetDIMFocus() + 0x55 bytes
msctf.dll!_GetMsgHook() + 0x4afd bytes
msctf.dll!_TF_Notify@12() + 0x91 bytes
user32.dll!_CtfHookProcWorker@16() + 0x21 bytes
user32.dll!_CallHookWithSEH@16() + 0x21 bytes
user32.dll!___fnHkINLPMSG@4() + 0x25 bytes
ntdll.dll!_KiUserCallbackDispatcher@12() + 0x2e bytes
user32.dll!_NtUserGetMessage@16() + 0xc bytes
user32.dll!_GetMessageW@16() + 0x2b bytes
dyalog.exe!w3_next_message() Line 848 + 0x10 bytes C
dyalog.exe!MessageLoop(int (void)* readfn=0x00676ed0)
Now my prior posts I had been mostly focusing on how the Text Services Framework and its changes to the input stack and (let's be frank) the input model affected the loading of Input Method Editors, but John's issue kind of points out a situation where the state that USER32/win32k keeps may not always be consulted by TSF (I guess it thinks that it knows better?).
Looking at the stack, I am not so eager to blame that msctf.dll!PostInputLangRequest call, though.
That function has a purpose, and it appears to be succeeding at it, The blame would have to lie with whatever decided that getting this function involved was the answer!
It appears that there is some component (maybe an input thread?) in TSF that is getting recycled and as a part of its shutdown it seems to be making sure that USER32/win32k have their story right -- so it is setting the input language.
Clearly this looks like a bug, especially since in this case a clearly documented member of the Win32 API and the lower level input stack has the correct notion of what is going on, and TSF really has no excuse to be changing it.
And I don't disagree with the assessment that this is a bug.
But more than that, it seems like those last two posts and this one are successively more encroaching warnings to stop relying on LoadKeyboardLayout and all of the lower level stuff. The higher level TSF component and the model that it provides atop that older model just does not seem quite compatible with the notion of making changes out from under it.
How many problems do we have to run across before we move on to TSF? Will we delay the migration until we finally get after a future version of Window inspires an MSKB article with a title like LoadKeyboardLayout will physically harm the user or something like that?
When will all of us (including me) finally get the hint? :-)
This post brought to you by । (U+0964, aka DEVANAGARI DANDA)