[英]Changing Keyboard Layout inside Keyboard Hook CallBack
I have a problem with changing keyboard layout inside keyboard hook. 我在更改键盘挂钩内的键盘布局时遇到问题。 In this simple code, when pressing 'A' key, it takes a lot time, to change a language, in more complicated cases, application does wrong things..
在这个简单的代码中,按“ A”键需要花费很多时间来更改语言,在更复杂的情况下,应用程序会做错事。
Application works in tray, therefore I used hooks. 应用程序在托盘中工作,因此我使用了挂钩。 Whats wrong with my code?
我的代码有什么问题? )) Or, maybe there is different way to change keyboard layout, which works with hooks well?
))或者,也许有另外一种改变键盘布局的方法,这种方法与钩子配合得很好? Thanks for your answers.
感谢您的回答。
private static bool nextKey = false;
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
uint tpid = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
ushort currentLayout = GetKeyboardLayout(tpid);
if (nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN) {
if (nextKey) {
Console.WriteLine("changing to english...");
PostMessage(GetForegroundWindow(), 0x0050, 0, (int) LoadKeyboardLayout("00000409", 0x00000001));
nextKey = false;
}
int vkCode = Marshal.ReadInt32(lParam);
if (vkCode == 0x41 && currentLayout == 0x409) { // if language is rus and 'A' pressed
Console.WriteLine("changing to russian...");
PostMessage(GetForegroundWindow(), 0x0050, 0, (int) LoadKeyboardLayout("00000419", 0x00000001));
nextKey = true;
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
Before even trying to fix this code, I have to ask a couple of silly questions: 在尝试修复此代码之前,我必须问几个愚蠢的问题:
Now, looking specifically at your code, what you're doing is posting the WM_INPUTLANGCHANGEREQUEST
message to the foreground window. 现在,专门查看您的代码,您正在做的是将
WM_INPUTLANGCHANGEREQUEST
消息发布到前台窗口。 But this message is a notification . 但是此消息是通知 。 It informs a program that a user requested to change the input language.
它通知程序用户请求更改输入语言。 It's not designed to allow programs to make requests to other programs to change the input language.
它的目的不是允许程序向其他程序发出请求以更改输入语言。
If a program wants to change its own keyboard layout, it calls the ActivateKeyboardLayout
function. 如果程序想要更改其自己的键盘布局,则将调用
ActivateKeyboardLayout
函数。 But it's not necessary to p/invoke this function from a .NET application. 但是不必从.NET应用程序p /调用此功能。 The framework already wraps all this up in the
InputLanguage
class—highly recommended. 该框架已经将所有这些都包装在
InputLanguage
类中-强烈建议。
Aside from that, other problems inevitably exist in code that you do not show, code that belongs to other applications. 除此之外,未显示的代码中不可避免地存在其他问题,这些代码属于其他应用程序。 The foreground window to which you post the
WM_INPUTLANGCHANGEREQUEST
message has the option of either accepting the change by passing the message on to DefWindowProc
, or rejecting the change by returning 0 in response. 向其发布
WM_INPUTLANGCHANGEREQUEST
消息的前台窗口可以选择通过将消息传递给DefWindowProc
来接受更改,或者通过返回0来拒绝更改。 If a broken application just returns 0 for all those messages it does not explicitly process , it won't do the right thing. 如果损坏的应用程序仅 针对未显式处理的所有消息返回0,则它将做不到正确的事情。 Or if an application has been written to explicitly reject
WM_INPUTLANGCHANGEREQUEST
requests, it won't do what you're expecting. 或者,如果编写了一个应用程序以明确拒绝
WM_INPUTLANGCHANGEREQUEST
请求,则该应用程序将无法满足您的期望。 And so on. 等等。 You have no control over these things.
您无法控制这些事情。 Remember,
WM_INPUTLANGCHANGEREQUEST
is just a request. 请记住,
WM_INPUTLANGCHANGEREQUEST
只是一个请求。
As far as the speed issue ("it takes a lot time, to change a language"), loading an input language for the first time is not guaranteed to be a lightning fast operation. 至于速度问题(“更改语言需要花费很多时间”),不能保证首次加载输入语言是一种快速的操作。 I see about a half a second delay on my machine using the normal mechanism.
我发现使用正常机制的机器延迟了大约半秒钟。 Not usually a big bottleneck;
通常没有大的瓶颈; most people don't switch back and forth that many times.
大多数人不会来回切换很多次。 If you really need to speed this up, consider caching the return value of the
LoadKeyboardLayout
function. 如果您确实需要加快速度,请考虑缓存
LoadKeyboardLayout
函数的返回值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.