Sorting it all Out Michael Kaplan's random stuff of dubious value Be sure to read the disclaimer here first!
Over in the Suggestion Box, John Daintree asks:
Could you please follow up the missing functionality of LoadKeyboardLayout() on Windows Vista? I need to be able to load a specific layout for my application as the app starts.
The missing functionality in question is I believe what I described in Cutting the cord while someone else is shoring it up, which is the ability to load IMEs via a call to LoadKeyboardLayout, partially ameliorated by Office 2007 which adds three of them back:
Perhaps "add" is the wrong word since these three values don't exist in any prior version, but they do enable the LoadKeyboardLayout-style bootstrapping technique of loading up the appropriate IME....
At the time, I suggested:
(The question itself is one I'll provide some answers for another time -- since it involves for the IME a TSF sample!)
However, when I looked into creating such a sample, I noticed a topic in MSDN entitled Language Bar, which states:
An application cannot add items to the language bar; only a text service can add items to the language bar. An application can affect how certain items on the language bar appear.
This is a clear departure from prior versions, since in the TSF world you have to have the IME "installed" to the Language Bar to make use of it, but the decision to place it in the Language Bar has clearly been moved to be considered a user decision, not an application one (back in the world of doing this via LoadKeyboardLayout it was obviously an easy application decision)....
With that said, I ma curious about a situation where a user
And interestingly, switching to an installed IME is an easy operation via an ActivateKeyboardLayout call, and the ability to add a keyboard layout or TSF TIP using the same technique as Regional Options does has now been documented, by calling the InstallLayoutOrTip function in input.dll.
The latter function call provides the way to directly install or uninstall any keyboard layout or TIP from the Language Bar (it is also the same function that is used by MSKLC 1.4 to support the automatic install and uninstall of keyboard layouts in the automatically provided setup!).
The function takes the same strings as Regional Options unattend does (discussed previously in On building a list of keyboards).
The technique only works in Vista, Server 2008, and above (the function does not exist downlevel), though this is the only place that the LoadKeyboardLayout method is broken, so it is at least a step in right direction in terms of keeping functionality working....
And I will be talking about some of the rest of these now-documented functions (now listed here along with previously documented TSF functions!) inupvoming blogs.
This post brought to you by ಊ (U+0c8a, aka KANNADA LETTER UU)
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 Cuser32.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 Cuser32.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 Cdyalog.exe!MessageLoop(int (void)* readfn=0x00676ed0)
Okay, that issue goes a little beyond the scope of what I was trying to cover here, so I moved it over to the suggestion box, here....
OK, I guessed as much. Thanks.
If you are a regular reader, you may recall either Cutting the cord while someone else is shoring it
Joost van Doorn asks (via the Contact link): Hello Michael, Since your name appears in a lot of MSDN
Michael,
I'm trying to use InstallLayoutOrTip to install Tips for the current user, but they seem to only go to local machine. Can you provide a sample of the correct calling convention to have it apply to the current user. From the above discussion I'm unclear on how you use ActivateKeyboardLayout if it is not proceeded by LoadKeyboardLayout.
Thanks,