win32 window 阻止键盘布局更改
win32 window blocking keyboard layout changes
我遇到了用户无法在应用程序处于焦点时更改键盘布局的问题。单击任务栏中的语言首选项或使用快捷键 Alt+Shift 时,它不起作用。我也没有收到任何我期望的 WM_INPUTLANGCHANGEREQUEST
或 WM_INPUTLANGCHANGE
事件。
#include <Windows.h>
#include <stdio.h>
static int close_requested = 0;
static LRESULT CALLBACK wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_CLOSE:
close_requested = 1;
break;
case WM_INPUTLANGCHANGE:
puts("WM_INPUTLANGCHANGE");
break;
case WM_INPUTLANGCHANGEREQUEST:
puts("WM_INPUTLANGCHANGEREQUEST");
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int main(void)
{
const HINSTANCE hInst = GetModuleHandle(NULL);
const WNDCLASS wc = {
.hInstance = hInst,
.hIcon = LoadIcon(NULL, IDI_APPLICATION),
.lpszClassName = TEXT("test-class"),
.lpfnWndProc = wnd_proc,
};
RegisterClass(&wc);
const HWND hWnd = CreateWindowEx(0, TEXT("test-class"), TEXT("Test"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 1920, 1080, NULL, NULL, hInst, NULL);
while (!close_requested) {
MSG msg;
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
DestroyWindow(hWnd);
return 0;
}
我不确定是什么导致我的应用程序阻止用户更改其键盘布局。我一直在使用 US International
和 Microsoft IME
键盘进行测试。如果键盘保持不变,我也无法更改语言首选项,例如 English (United States)
和 English (United Kingdom)
具有相同的键盘布局 (US International
)。
是否有任何我应该处理的 Windows 消息,或者在创建 window 时我是否需要设置任何额外的标志?
我认为您使用的消息循环导致了问题。修改消息循环为:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
它对我有用,我建议你参考Using Messages and Message Queues来弄清楚这两种消息循环的区别。
编辑:
您也可以使用:
while (!close_requested) {
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
错误原因由IInspectable给出:The dangers of filtering window messages
我遇到了用户无法在应用程序处于焦点时更改键盘布局的问题。单击任务栏中的语言首选项或使用快捷键 Alt+Shift 时,它不起作用。我也没有收到任何我期望的 WM_INPUTLANGCHANGEREQUEST
或 WM_INPUTLANGCHANGE
事件。
#include <Windows.h>
#include <stdio.h>
static int close_requested = 0;
static LRESULT CALLBACK wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_CLOSE:
close_requested = 1;
break;
case WM_INPUTLANGCHANGE:
puts("WM_INPUTLANGCHANGE");
break;
case WM_INPUTLANGCHANGEREQUEST:
puts("WM_INPUTLANGCHANGEREQUEST");
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int main(void)
{
const HINSTANCE hInst = GetModuleHandle(NULL);
const WNDCLASS wc = {
.hInstance = hInst,
.hIcon = LoadIcon(NULL, IDI_APPLICATION),
.lpszClassName = TEXT("test-class"),
.lpfnWndProc = wnd_proc,
};
RegisterClass(&wc);
const HWND hWnd = CreateWindowEx(0, TEXT("test-class"), TEXT("Test"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 1920, 1080, NULL, NULL, hInst, NULL);
while (!close_requested) {
MSG msg;
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
DestroyWindow(hWnd);
return 0;
}
我不确定是什么导致我的应用程序阻止用户更改其键盘布局。我一直在使用 US International
和 Microsoft IME
键盘进行测试。如果键盘保持不变,我也无法更改语言首选项,例如 English (United States)
和 English (United Kingdom)
具有相同的键盘布局 (US International
)。
是否有任何我应该处理的 Windows 消息,或者在创建 window 时我是否需要设置任何额外的标志?
我认为您使用的消息循环导致了问题。修改消息循环为:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
它对我有用,我建议你参考Using Messages and Message Queues来弄清楚这两种消息循环的区别。
编辑:
您也可以使用:
while (!close_requested) {
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
错误原因由IInspectable给出:The dangers of filtering window messages