https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d7f13aa696cf606dc1629…
commit d7f13aa696cf606dc1629a54b3bf6325e8afad25
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Jul 31 15:56:11 2021 +0900
Commit: GitHub <noreply(a)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