https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d7f13aa696cf606dc1629a...
commit d7f13aa696cf606dc1629a54b3bf6325e8afad25 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sat Jul 31 15:56:11 2021 +0900 Commit: GitHub noreply@github.com CommitDate: Sat Jul 31 15:56:11 2021 +0900
[IMM32] Improve ImmSimulateHotKey (#3858)
- Improve ImmSimulateHotKey function. - Modify IMEDPI structure. CORE-11700 --- dll/win32/imm32/imm.c | 248 ++++++++++++++++++++++++++++++++++++++++++++++- win32ss/include/ntuser.h | 5 +- 2 files changed, 249 insertions(+), 4 deletions(-)
diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c index 5e655e6c4e6..9c7aa19ec4a 100644 --- a/dll/win32/imm32/imm.c +++ b/dll/win32/imm32/imm.c @@ -48,6 +48,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm); #define IMM_INIT_MAGIC 0x19650412 #define IMM_INVALID_CANDFORM ULONG_MAX
+#define LANGID_CHINESE_SIMPLIFIED MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) +#define LANGID_CHINESE_TRADITIONAL MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) +#define LANGID_JAPANESE MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT) + #define REGKEY_KEYBOARD_LAYOUTS \ L"System\CurrentControlSet\Control\Keyboard Layouts" #define REGKEY_IMM \ @@ -1205,6 +1209,234 @@ static DWORD APIENTRY Imm32AllocAndBuildHimcList(DWORD dwThreadId, HIMC **pphLis #undef MAX_RETRY }
+static BOOL APIENTRY Imm32ImeNonImeToggle(HIMC hIMC, HKL hKL, HWND hWnd, LANGID LangID) +{ + LPINPUTCONTEXT pIC; + BOOL fOpen; + + if (hWnd != NULL) + return FALSE; + + if (!IS_IME_HKL(hKL) || LOWORD(hKL) != LangID) + { + FIXME("We have to do something here\n"); + return TRUE; + } + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return TRUE; + + fOpen = pIC->fOpen; + ImmUnlockIMC(hIMC); + + if (!fOpen) + { + ImmSetOpenStatus(hIMC, TRUE); + return TRUE; + } + + FIXME("We have to do something here\n"); + return TRUE; +} + +static BOOL APIENTRY Imm32CShapeToggle(HIMC hIMC, HKL hKL, HWND hWnd) +{ + LPINPUTCONTEXT pIC; + BOOL fOpen; + DWORD dwConversion, dwSentence; + + if (hWnd == NULL || !IS_IME_HKL(hKL)) + return FALSE; + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return TRUE; + + fOpen = pIC->fOpen; + if (fOpen) + { + dwConversion = (pIC->fdwConversion ^ IME_CMODE_FULLSHAPE); + dwSentence = pIC->fdwSentence; + } + + ImmUnlockIMC(hIMC); + + if (fOpen) + ImmSetConversionStatus(hIMC, dwConversion, dwSentence); + else + ImmSetOpenStatus(hIMC, TRUE); + + return TRUE; +} + +static BOOL APIENTRY Imm32CSymbolToggle(HIMC hIMC, HKL hKL, HWND hWnd) +{ + LPINPUTCONTEXT pIC; + BOOL fOpen; + DWORD dwConversion, dwSentence; + + if (hWnd == NULL || !IS_IME_HKL(hKL)) + return FALSE; + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return TRUE; + + fOpen = pIC->fOpen; + if (fOpen) + { + dwConversion = (pIC->fdwConversion ^ IME_CMODE_SYMBOL); + dwSentence = pIC->fdwSentence; + } + + ImmUnlockIMC(hIMC); + + if (fOpen) + ImmSetConversionStatus(hIMC, dwConversion, dwSentence); + else + ImmSetOpenStatus(hIMC, TRUE); + + return TRUE; +} + +static BOOL APIENTRY Imm32JCloseOpen(HIMC hIMC, HKL hKL, HWND hWnd) +{ + BOOL fOpen; + + if (ImmIsIME(hKL) && LOWORD(hKL) == LANGID_JAPANESE) + { + fOpen = ImmGetOpenStatus(hIMC); + ImmSetOpenStatus(hIMC, !fOpen); + return TRUE; + } + + FIXME("We have to do something here\n"); + return TRUE; +} + +static BOOL APIENTRY Imm32KShapeToggle(HIMC hIMC) +{ + LPINPUTCONTEXT pIC; + DWORD dwConversion, dwSentence; + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + dwConversion = (pIC->fdwConversion ^ IME_CMODE_FULLSHAPE); + dwSentence = pIC->fdwSentence; + ImmSetConversionStatus(hIMC, dwConversion, dwSentence); + + if (pIC->fdwConversion & (IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE)) + ImmSetOpenStatus(hIMC, TRUE); + else + ImmSetOpenStatus(hIMC, FALSE); + + ImmUnlockIMC(hIMC); + return TRUE; +} + +static BOOL APIENTRY Imm32KHanjaConvert(HIMC hIMC) +{ + LPINPUTCONTEXT pIC; + DWORD dwConversion, dwSentence; + + pIC = ImmLockIMC(hIMC); + if (!pIC) + return FALSE; + + dwConversion = (pIC->fdwConversion ^ IME_CMODE_HANJACONVERT); + dwSentence = pIC->fdwSentence; + ImmUnlockIMC(hIMC); + + ImmSetConversionStatus(hIMC, dwConversion, dwSentence); + return TRUE; +} + +static BOOL APIENTRY Imm32KEnglish(HIMC hIMC) +{ + LPINPUTCONTEXT pIC; + DWORD dwConversion, dwSentence; + BOOL fOpen; + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + dwConversion = (pIC->fdwConversion ^ IME_CMODE_NATIVE); + dwSentence = pIC->fdwSentence; + ImmSetConversionStatus(hIMC, dwConversion, dwSentence); + + fOpen = ((pIC->fdwConversion & (IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE)) != 0); + ImmSetOpenStatus(hIMC, fOpen); + + ImmUnlockIMC(hIMC); + return TRUE; +} + +static BOOL APIENTRY Imm32ProcessHotKey(HWND hWnd, HIMC hIMC, HKL hKL, DWORD dwHotKeyID) +{ + DWORD dwImeThreadId, dwThreadId; + PIMEDPI pImeDpi; + BOOL ret; + + if (hIMC) + { + dwImeThreadId = Imm32QueryInputContext(hIMC, 1); + dwThreadId = GetCurrentThreadId(); + if (dwImeThreadId != dwThreadId) + return FALSE; + } + + switch (dwHotKeyID) + { + case IME_CHOTKEY_IME_NONIME_TOGGLE: + return Imm32ImeNonImeToggle(hIMC, hKL, hWnd, LANGID_CHINESE_SIMPLIFIED); + + case IME_CHOTKEY_SHAPE_TOGGLE: + return Imm32CShapeToggle(hIMC, hKL, hWnd); + + case IME_CHOTKEY_SYMBOL_TOGGLE: + return Imm32CSymbolToggle(hIMC, hKL, hWnd); + + case IME_JHOTKEY_CLOSE_OPEN: + return Imm32JCloseOpen(hIMC, hKL, hWnd); + + case IME_KHOTKEY_SHAPE_TOGGLE: + return Imm32KShapeToggle(hIMC); + + case IME_KHOTKEY_HANJACONVERT: + return Imm32KHanjaConvert(hIMC); + + case IME_KHOTKEY_ENGLISH: + return Imm32KEnglish(hIMC); + + case IME_THOTKEY_IME_NONIME_TOGGLE: + return Imm32ImeNonImeToggle(hIMC, hKL, hWnd, LANGID_CHINESE_TRADITIONAL); + + case IME_THOTKEY_SHAPE_TOGGLE: + return Imm32CShapeToggle(hIMC, hKL, hWnd); + + case IME_THOTKEY_SYMBOL_TOGGLE: + return Imm32CSymbolToggle(hIMC, hKL, hWnd); + + default: + break; + } + + if (dwHotKeyID < IME_HOTKEY_PRIVATE_FIRST || IME_HOTKEY_PRIVATE_LAST < dwHotKeyID) + return FALSE; + + pImeDpi = ImmLockImeDpi(hKL); + if (pImeDpi == NULL) + return FALSE; + + ret = (BOOL)pImeDpi->ImeEscape(hIMC, IME_ESC_PRIVATE_HOTKEY, &dwHotKeyID); + ImmUnlockImeDpi(pImeDpi); + return ret; +} + PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc) { PCLIENTIMC pClientImc; @@ -3288,9 +3520,19 @@ BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow) */ BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID) { - FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + HIMC hIMC; + DWORD dwThreadId; + HKL hKL; + BOOL ret; + + TRACE("ImmSimulateHotKey(%p, 0x%lX)\n", hWnd, dwHotKeyID); + + hIMC = ImmGetContext(hWnd); + dwThreadId = GetWindowThreadProcessId(hWnd, NULL); + hKL = GetKeyboardLayout(dwThreadId); + ret = Imm32ProcessHotKey(hWnd, hIMC, hKL, dwHotKeyID); + ImmReleaseContext(hWnd, hIMC); + return ret; }
/*********************************************************************** diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h index 8182efe16f3..024e9413a0a 100644 --- a/win32ss/include/ntuser.h +++ b/win32ss/include/ntuser.h @@ -1213,6 +1213,7 @@ typedef struct _IMEWND } IMEWND, *PIMEWND;
typedef BOOL (WINAPI *FN_ImeDestroy)(UINT uReserved); +typedef LRESULT (WINAPI *FN_ImeEscape)(HIMC hIMC, UINT uEscape, LPVOID lpData); typedef BOOL (WINAPI *FN_NotifyIME)(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue);
typedef struct IMEDPI /* unconfirmed */ @@ -1227,7 +1228,8 @@ typedef struct IMEDPI /* unconfirmed */ DWORD dwFlags; DWORD dwUnknown3[7]; FN_ImeDestroy ImeDestroy; - DWORD dwUnknown4[5]; + FN_ImeEscape ImeEscape; + DWORD dwUnknown4[4]; FN_NotifyIME NotifyIME; /* ... */ } IMEDPI, *PIMEDPI; @@ -1239,6 +1241,7 @@ C_ASSERT(offsetof(IMEDPI, hKL) == 0x8); C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c); C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50); C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70); +C_ASSERT(offsetof(IMEDPI, ImeEscape) == 0x74); C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88); #endif