Reactos

[KBSWITCH] Fix ID_IMEONOFF action (#8562)

Toggling IME open/close from pen icon menu didn't work
because the kbswitch app thread is different from the IME thread.
JIRA issue: CORE-19268
- Use WM_IME_CONTROL:IMC_GETOPENSTATUS instead of
imm32!ImmGetOpenStatus.
- Use WM_IME_CONTROL:IMC_GETCONVERSIONMODE instead
of imm32!ImmGetConversionStatus.
- Use WM_IME_SYSTEM:IMS_SETOPENSTATUS instead of
imm32!ImmSetOpenStatus.
- Adjustment for timing of SetForegroundWindow call.

authored by

Katayama Hirofumi MZ and committed by
GitHub
3885311c c77e0e51

+28 -16
+28 -16
base/applications/kbswitch/kbswitch.c
··· 77 77 #define LAYOUTF_REMOVE_LEFT_DEF_MENU 0x8 78 78 #define LAYOUTF_REMOVE_RIGHT_DEF_MENU 0x10 79 79 80 + // ImmGetOpenStatus cannot be used from different thread 81 + static inline BOOL IsImeOpen(HWND hwndIme) 82 + { 83 + return (BOOL)SendMessage(hwndIme, WM_IME_CONTROL, IMC_GETOPENSTATUS, 0); 84 + } 85 + 86 + // ImmGetConversionStatus cannot be used from different thread 87 + static inline DWORD GetImeConversionMode(HWND hwndIme) 88 + { 89 + return (DWORD)SendMessage(hwndIme, WM_IME_CONTROL, IMC_GETCONVERSIONMODE, 0); 90 + } 91 + 80 92 static VOID 81 93 UpdateTrayInfo(VOID) 82 94 { ··· 471 483 if (!hIMC) 472 484 return IME_STATUS_NO_IME; 473 485 474 - DWORD dwImeStatus = (ImmGetOpenStatus(hIMC) ? IME_STATUS_IME_OPEN : IME_STATUS_IME_CLOSED); 486 + DWORD dwImeStatus = (IsImeOpen(hwndIme) ? IME_STATUS_IME_OPEN : IME_STATUS_IME_CLOSED); 475 487 if (GetACP() == 949) // Korean 476 488 { 477 - DWORD dwConversion = 0, dwSentence = 0; 478 - if (ImmGetConversionStatus(hIMC, &dwConversion, &dwSentence)) 479 - { 480 - if (dwConversion & IME_CMODE_NATIVE) 481 - dwImeStatus |= IME_STATUS_IME_NATIVE; 489 + DWORD dwConversion = GetImeConversionMode(hwndIme); 490 + if (dwConversion & IME_CMODE_NATIVE) 491 + dwImeStatus |= IME_STATUS_IME_NATIVE; 482 492 483 - if (dwConversion & IME_CMODE_FULLSHAPE) 484 - dwImeStatus |= IME_STATUS_IME_FULLSHAPE; 485 - } 493 + if (dwConversion & IME_CMODE_FULLSHAPE) 494 + dwImeStatus |= IME_STATUS_IME_FULLSHAPE; 486 495 } 487 496 488 497 return dwImeStatus; ··· 1111 1120 return; 1112 1121 } 1113 1122 1114 - // Workaround of TrackPopupMenu's bug 1123 + // Is IME open? 1124 + BOOL bImeOn = IsImeOpen(hwndIme); 1125 + 1126 + // Workaround of TrackPopupMenu's bug. 1127 + // NOTE: This might change IME status. 1115 1128 SetForegroundWindow(hwnd); 1116 1129 1117 1130 // Create IME menu ··· 1120 1133 HMENU hMenu = MenuFromImeMenu(pImeMenu); 1121 1134 1122 1135 HKL hKL = g_ahKLs[g_iKL]; 1123 - DWORD dwImeStatus = GetImeStatus(hwndTarget); 1124 - BOOL bImeOn = FALSE, bSoftOn = FALSE, bShowToolbar = FALSE; 1136 + BOOL bSoftOn = FALSE, bShowToolbar = FALSE; 1125 1137 TCHAR szText[128]; 1126 1138 if (bRightButton) 1127 1139 { ··· 1145 1157 if (!IS_KOREAN_IME_HKL(hKL)) // Not Korean IME? 1146 1158 { 1147 1159 // "IME ON / OFF" 1148 - bImeOn = (dwImeStatus == IME_STATUS_IME_OPEN); 1149 1160 UINT nId = (bImeOn ? IDS_IME_ON : IDS_IME_OFF); 1150 1161 LoadString(g_hInst, nId, szText, _countof(szText)); 1151 1162 AppendMenu(hMenu, MF_STRING, ID_IMEONOFF, szText); ··· 1197 1208 // Workaround of TrackPopupMenu's bug 1198 1209 PostMessage(hwnd, WM_NULL, 0, 0); 1199 1210 1211 + // Back to target window 1212 + SetForegroundWindow(hwndTarget); 1213 + 1200 1214 if (nID) // Action! 1201 1215 { 1202 1216 if (nID >= ID_STARTIMEMENU) // IME internal menu ID? ··· 1221 1235 PostMessage(hwndIme, WM_IME_SYSTEM, IMS_CONFIGURE, (LPARAM)hKL); 1222 1236 break; 1223 1237 case ID_IMEONOFF: 1224 - ImmSetOpenStatus(hIMC, !bImeOn); 1238 + PostMessage(hwndIme, WM_IME_SYSTEM, IMS_SETOPENSTATUS, !bImeOn); 1225 1239 break; 1226 1240 case ID_SOFTKBDONOFF: 1227 1241 PostMessage(hwndIme, WM_IME_SYSTEM, IMS_SOFTKBDONOFF, !bSoftOn); ··· 1241 1255 // Clean up 1242 1256 DestroyMenu(hMenu); 1243 1257 CleanupImeMenus(); 1244 - 1245 - SetForegroundWindow(hwndTarget); 1246 1258 } 1247 1259 1248 1260 // WM_COMMAND