Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Issues with receiving WM_INPUTLANGCHANGE etc. messages when language is chosen using hotkeys
I'm currently writing an input and output handling library for the D language, and I'm not getting any kind of input language change messages when the language is being toggled with hotkeys, and only during moving the window from toggling it on the taskbar.
The beginning of the function that can be called for an event loop looks like this under Windows
package int poll_win_LegacyIO(ref InputEvent output) nothrow @nogc {
tryAgain:
MSG msg;
BOOL bret = PeekMessageW(&msg, OSWindow.refCount[winCount].getHandle, 0, 0, PM_REMOVE);
if (bret) {
output.timestamp = msg.time * 1000L;
output.handle = OSWindow.refCount[winCount].getHandle;
auto message = msg.message & 0xFF_FF;
DispatchMessageW(&msg);
[...]
}
}
Then there's a separate OSWindow class with its own windows callback functions:
static extern (Windows) LRESULT wndprocCallback(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) nothrow @system {
switch (msg) {
case WM_CREATE, WM_NCCREATE:
return DefWindowProcW(hWnd, msg, wParam, lParam);
default:
foreach (OSWindow key; refCount) {
if (key.getHandle() == hWnd)
return key.wndCallback(msg, wParam, lParam);
}
return LRESULT.init;
}
}
}
[...]
version (Windows)
protected LRESULT wndCallback(UINT msg, WPARAM wParam, LPARAM lParam) nothrow @system {
switch (msg) {
case WM_INPUTLANGCHANGEREQUEST:
statusFlags = Status.InputLangChReq;
inputLang = cast(uint)lParam;
goto default;
case WM_INPUTLANGCHANGE:
statusFlags = Status.InputLangCh;
inputLang = cast(uint)lParam;
goto default;
[...]
default:
return DefWindowProcW(windowHandle, msg, wParam, lParam);
}
}
Using a debugger, I noticed that the WM_INPUTLANGCHANGE and WM_INPUTLANGCHANGEREQUEST commands are not generated when the input language is being changed by the user, and instead the input language change hotkeys don't work as intended (the selection comes up, but hangs for a while, and no language will be changed, sometimes even hangs the application), and changing the input from the taskbar only get dispatched to my application once the window is being resized or moved. I did various modifications to the code (including removing a part that optionally trapped the Win and Menu key presses, and temporarily moving the DispatchMessageW function before the if statement).
Is there potentially some fundamental problem with handling focus in my window class (there's currently nothing besides the DevWindowProcW function), or something else?
EDIT: Version is Windows 10, but the input language change commands go as far back as Windows 2000, if they're not older. Also tried putting a TranslateMessage function before the DispatchMessage (I often need absolute key codes, that are not input language dependent), but didn't change the behavior (will also try with using null as window handle in the PeekMessage function).
1 answer
It seems like changing the window handle to null in PeekMessageW solved the issue:
BOOL bret = PeekMessageW(&msg, null, 0, 0, PM_REMOVE);
Then I can still get the window handle source like this:
output.handle = msg.hwnd;
Win32 API is just really not intuitive, and many behaviors are not well documented.
1 comment thread