From c9d3c29aa33aee77c99b46a8135469cde544b2ca Mon Sep 17 00:00:00 2001 From: sneakyevil Date: Tue, 5 Sep 2023 13:20:48 +0200 Subject: [PATCH] Backend: Win32: support keyboard codepage conversion for when compiling in MBCS mode and creating a non-Unicode window. (#6785, #6782, #5725) --- backends/imgui_impl_win32.cpp | 18 +++++++++++++++++- docs/CHANGELOG.txt | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 0993ecf8c..f3c339149 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -36,6 +36,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window. // 2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218) // 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702) // 2023-02-15: Inputs: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse position over non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162) @@ -94,6 +95,7 @@ struct ImGui_ImplWin32_Data INT64 Time; INT64 TicksPerSecond; ImGuiMouseCursor LastMouseCursor; + UINT32 KeyboardCodePage; #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD bool HasGamepad; @@ -116,6 +118,16 @@ static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData() } // Functions +static void ImGui_ImplWin32_UpdateKeyboardCodePage() +{ + // Retrieve keyboard code page, required for handling of non-Unicode Windows. + ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); + HKL keyboard_layout = ::GetKeyboardLayout(0); + LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT); + if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0) + bd->KeyboardCodePage = CP_ACP; // Fallback to default ANSI code page when fails. +} + static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc) { ImGuiIO& io = ImGui::GetIO(); @@ -138,6 +150,7 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc) bd->TicksPerSecond = perf_frequency; bd->Time = perf_counter; bd->LastMouseCursor = ImGuiMouseCursor_COUNT; + ImGui_ImplWin32_UpdateKeyboardCodePage(); // Set platform dependent data in viewport ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd; @@ -671,6 +684,9 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA case WM_KILLFOCUS: io.AddFocusEvent(msg == WM_SETFOCUS); return 0; + case WM_INPUTLANGCHANGE: + ImGui_ImplWin32_UpdateKeyboardCodePage(); + return 0; case WM_CHAR: if (::IsWindowUnicode(hwnd)) { @@ -681,7 +697,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA else { wchar_t wch = 0; - ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1); + ::MultiByteToWideChar(bd->KeyboardCodePage, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1); io.AddInputCharacter(wch); } return 0; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 183c1151d..2d85903cf 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -52,6 +52,8 @@ Other changes: Was most often noticable when using an horizontal scrollbar. (#6789) - ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl] - Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] +- Backends: Win32: Added support for keyboard codepage conversion for when application + is compiled in MBCS mode and using a non-Unicode window. (#6785, #6782, #5725, #5961) [@sneakyevil] -----------------------------------------------------------------------