Skip to content

Commit 2335229

Browse files
authored
[USER32][IMM32][SDK] Support WM_IME_SYSTEM.0x1D (reactos#8088)
Splitted from reactos#8080. The message handling of WM_IME_SYSTEM.0x1D is needed for IME menu handling. JIRA issue: CORE-20142 - Define IMS_IMEMENUITEMSELECTED (0x1D) in <immdev.h>. - Add WM_IME_SYSTEM.0x1D handling in ImeWnd_OnImeSystem function. - Rename and extend User32GetImmFileName function as User32GetSystemFilePath, with adding a filename parameter.
1 parent 5b4d1db commit 2335229

File tree

5 files changed

+83
-45
lines changed

5 files changed

+83
-45
lines changed

sdk/include/ddk/immdev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ typedef struct tagGUIDELINE {
110110
#define IMS_IMEDEACTIVATE 0x18
111111
#define IMS_ACTIVATELAYOUT 0x19
112112
#define IMS_GETIMEMENU 0x1C
113+
#define IMS_IMEMENUITEMSELECTED 0x1D
113114
#define IMS_GETCONTEXT 0x1E
114115
#define IMS_SENDNOTIFICATION 0x1F
115116
#define IMS_COMPLETECOMPSTR 0x20

win32ss/user/imm32/imemenu.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -610,12 +610,15 @@ ImmGetImeMenuItemsAW(
610610

611611
/* Get IME menu items from the IME */
612612
ret = pImeDpi->ImeGetImeMenuItems(hIMC, dwFlags, dwType, pNewParent, pNewItems, dwSize);
613-
if (!ret || !lpImeMenuItems)
613+
if (!ret)
614614
{
615-
ERR("%d, %p\n", ret, lpImeMenuItems);
615+
ERR("ImeGetImeMenuItems failed\n");
616616
goto Quit;
617617
}
618618

619+
if (!lpImeMenuItems)
620+
goto Quit;
621+
619622
if (bImcIsAnsi != bTargetIsAnsi) /* Are text types different? */
620623
{
621624
if (bTargetIsAnsi)

win32ss/user/user32/include/user32p.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ VOID DeleteFrameBrushes(VOID);
128128
BOOL WINAPI GdiValidateHandle(HGDIOBJ);
129129
HANDLE FASTCALL UserGetProp(HWND hWnd, ATOM Atom, BOOLEAN SystemProp);
130130
BOOL WINAPI InitializeImmEntryTable(VOID);
131-
HRESULT User32GetImmFileName(_Out_ LPWSTR lpBuffer, _In_ size_t cchBuffer);
131+
HRESULT User32GetSystemFilePath(_Out_writes_(cchBuffer) PWSTR lpBuffer, _In_ SIZE_T cchBuffer, _In_ PCWSTR pszFileName);
132132
BOOL WINAPI UpdatePerUserImmEnabling(VOID);
133133
VOID APIENTRY CliImmInitializeHotKeys(DWORD dwAction, HKL hKL);
134134
VOID IntLoadPreloadKeyboardLayouts(VOID);

win32ss/user/user32/misc/dllmain.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ DllMain(
537537
{
538538
WCHAR szImmFile[MAX_PATH];
539539
InitializeImmEntryTable();
540-
User32GetImmFileName(szImmFile, _countof(szImmFile));
540+
User32GetSystemFilePath(szImmFile, _countof(szImmFile), L"imm32.dll");
541541
hImm32 = GetModuleHandleW(szImmFile);
542542
}
543543

win32ss/user/user32/misc/imm.c

Lines changed: 75 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/*
2-
* COPYRIGHT: See COPYING in the top level directory
3-
* PROJECT: ReactOS user32.dll
4-
* FILE: win32ss/user/user32/misc/imm.c
5-
* PURPOSE: User32.dll Imm functions
6-
* PROGRAMMERS: Dmitry Chapyshev ([email protected])
7-
* Katayama Hirofumi MZ ([email protected])
2+
* PROJECT: ReactOS user32.dll
3+
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4+
* PURPOSE: User32.dll Imm functions
5+
* COPYRIGHT: Copyright Dmitry Chapyshev ([email protected])
6+
* Copyright Katayama Hirofumi MZ ([email protected])
87
*/
98

109
#include <user32.h>
@@ -17,11 +16,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
1716
#define MAX_CANDIDATEFORM 4
1817

1918
/* Is != NULL when we have loaded the IMM ourselves */
20-
HINSTANCE ghImm32 = NULL; // Win: ghImm32
19+
HINSTANCE ghImm32 = NULL;
2120

22-
BOOL gbImmInitializing = FALSE; // Win: bImmInitializing
21+
BOOL gbImmInitializing = FALSE;
2322

24-
INT gfConIme = -1; // Win: gfConIme
23+
INT gfConIme = -1;
2524

2625
HWND FASTCALL IntGetTopLevelWindow(HWND hWnd)
2726
{
@@ -43,7 +42,6 @@ HWND FASTCALL IntGetTopLevelWindow(HWND hWnd)
4342
static type WINAPI IMMSTUB_##name params { IMM_RETURN_##retkind((type)retval); }
4443
#include "immtable.h"
4544

46-
// Win: gImmApiEntries
4745
Imm32ApiTable gImmApiEntries = {
4846
/* initialize by stubs */
4947
#undef DEFINE_IMM_ENTRY
@@ -52,21 +50,25 @@ Imm32ApiTable gImmApiEntries = {
5250
#include "immtable.h"
5351
};
5452

55-
// Win: GetImmFileName
5653
HRESULT
57-
User32GetImmFileName(_Out_ LPWSTR lpBuffer, _In_ size_t cchBuffer)
54+
User32GetSystemFilePath(
55+
_Out_writes_(cchBuffer) PWSTR lpBuffer,
56+
_In_ SIZE_T cchBuffer,
57+
_In_ PCWSTR pszFileName)
5858
{
5959
UINT length = GetSystemDirectoryW(lpBuffer, cchBuffer);
6060
if (length && length < cchBuffer)
6161
{
6262
StringCchCatW(lpBuffer, cchBuffer, L"\\");
63-
return StringCchCatW(lpBuffer, cchBuffer, L"imm32.dll");
63+
return StringCchCatW(lpBuffer, cchBuffer, pszFileName);
6464
}
65-
return StringCchCopyW(lpBuffer, cchBuffer, L"imm32.dll");
65+
DWORD dwError = GetLastError();
66+
ERR("GetSystemDirectoryW failed (error %lu)\n", dwError);
67+
StringCchCopyW(lpBuffer, cchBuffer, pszFileName);
68+
return HRESULT_FROM_WIN32(dwError);
6669
}
6770

6871
// @unimplemented
69-
// Win: _InitializeImmEntryTable
7072
static BOOL IntInitializeImmEntryTable(VOID)
7173
{
7274
WCHAR ImmFile[MAX_PATH];
@@ -76,8 +78,8 @@ static BOOL IntInitializeImmEntryTable(VOID)
7678
if (IMM_FN(ImmWINNLSEnableIME) != IMMSTUB_ImmWINNLSEnableIME)
7779
return TRUE;
7880

79-
User32GetImmFileName(ImmFile, _countof(ImmFile));
80-
TRACE("File %S\n", ImmFile);
81+
User32GetSystemFilePath(ImmFile, _countof(ImmFile), L"imm32.dll");
82+
TRACE("File %s\n", debugstr_w(ImmFile));
8183

8284
/* If IMM32 is already loaded, use it without increasing reference count. */
8385
if (imm32 == NULL)
@@ -115,14 +117,12 @@ static BOOL IntInitializeImmEntryTable(VOID)
115117
return TRUE;
116118
}
117119

118-
// Win: InitializeImmEntryTable
119120
BOOL WINAPI InitializeImmEntryTable(VOID)
120121
{
121122
gbImmInitializing = TRUE;
122123
return IntInitializeImmEntryTable();
123124
}
124125

125-
// Win: User32InitializeImmEntryTable
126126
BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
127127
{
128128
TRACE("Imm (%x)\n", magic);
@@ -139,7 +139,7 @@ BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
139139
if (ghImm32 == NULL && !gbImmInitializing)
140140
{
141141
WCHAR ImmFile[MAX_PATH];
142-
User32GetImmFileName(ImmFile, _countof(ImmFile));
142+
User32GetSystemFilePath(ImmFile, _countof(ImmFile), L"imm32.dll");
143143
ghImm32 = LoadLibraryW(ImmFile);
144144
if (ghImm32 == NULL)
145145
{
@@ -151,21 +151,18 @@ BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
151151
return IMM_FN(ImmRegisterClient)(&gSharedInfo, ghImm32);
152152
}
153153

154-
// Win: ImeIsUsableContext
155154
static BOOL User32CanSetImeWindowToImc(HIMC hIMC, HWND hImeWnd)
156155
{
157156
PIMC pIMC = ValidateHandle(hIMC, TYPE_INPUTCONTEXT);
158157
return pIMC && (!pIMC->hImeWnd || pIMC->hImeWnd == hImeWnd || !ValidateHwnd(pIMC->hImeWnd));
159158
}
160159

161-
// Win: GetIMEShowStatus
162160
static BOOL User32GetImeShowStatus(VOID)
163161
{
164162
return (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_GETIMESHOWSTATUS);
165163
}
166164

167165
/* Sends a message to the IME UI window. */
168-
/* Win: SendMessageToUI(pimeui, uMsg, wParam, lParam, !unicode) */
169166
static LRESULT
170167
User32SendImeUIMessage(PIMEUI pimeui, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL unicode)
171168
{
@@ -195,7 +192,6 @@ User32SendImeUIMessage(PIMEUI pimeui, UINT uMsg, WPARAM wParam, LPARAM lParam, B
195192
return ret;
196193
}
197194

198-
// Win: SendOpenStatusNotify
199195
static VOID User32NotifyOpenStatus(PIMEUI pimeui, HWND hwndIMC, BOOL bOpen)
200196
{
201197
WPARAM wParam = (bOpen ? IMN_OPENSTATUSWINDOW : IMN_CLOSESTATUSWINDOW);
@@ -210,7 +206,6 @@ static VOID User32NotifyOpenStatus(PIMEUI pimeui, HWND hwndIMC, BOOL bOpen)
210206
User32SendImeUIMessage(pimeui, WM_IME_NOTIFY, wParam, 0, TRUE);
211207
}
212208

213-
// Win: ImeMarkUsedContext
214209
static VOID User32SetImeWindowOfImc(HIMC hIMC, HWND hImeWnd)
215210
{
216211
PIMC pIMC = ValidateHandle(hIMC, TYPE_INPUTCONTEXT);
@@ -220,7 +215,6 @@ static VOID User32SetImeWindowOfImc(HIMC hIMC, HWND hImeWnd)
220215
NtUserUpdateInputContext(hIMC, UIC_IMEWINDOW, (ULONG_PTR)hImeWnd);
221216
}
222217

223-
// Win: ImeSetImc
224218
static VOID User32UpdateImcOfImeUI(PIMEUI pimeui, HIMC hNewIMC)
225219
{
226220
HWND hImeWnd;
@@ -242,7 +236,6 @@ static VOID User32UpdateImcOfImeUI(PIMEUI pimeui, HIMC hNewIMC)
242236
}
243237

244238
/* Handles WM_IME_NOTIFY message of the default IME window. */
245-
/* Win: ImeNotifyHandler */
246239
static LRESULT ImeWnd_OnImeNotify(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
247240
{
248241
LRESULT ret = 0;
@@ -293,7 +286,6 @@ static LRESULT ImeWnd_OnImeNotify(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
293286
}
294287

295288
/* Creates the IME UI window. */
296-
/* Win: CreateIMEUI */
297289
static HWND User32CreateImeUIWindow(PIMEUI pimeui, HKL hKL)
298290
{
299291
IMEINFOEX ImeInfoEx;
@@ -339,7 +331,6 @@ static HWND User32CreateImeUIWindow(PIMEUI pimeui, HKL hKL)
339331
}
340332

341333
/* Initializes the default IME window. */
342-
/* Win: ImeWndCreateHandler */
343334
static INT ImeWnd_OnCreate(PIMEUI pimeui, LPCREATESTRUCT lpCS)
344335
{
345336
PWND pParentWnd, pWnd = pimeui->spwnd;
@@ -371,7 +362,6 @@ static INT ImeWnd_OnCreate(PIMEUI pimeui, LPCREATESTRUCT lpCS)
371362
}
372363

373364
/* Destroys the IME UI window. */
374-
/* Win: DestroyIMEUI */
375365
static VOID User32DestroyImeUIWindow(PIMEUI pimeui)
376366
{
377367
HWND hwndUI = pimeui->hwndUI;
@@ -387,7 +377,6 @@ static VOID User32DestroyImeUIWindow(PIMEUI pimeui)
387377
}
388378

389379
/* Handles WM_IME_SELECT message of the default IME window. */
390-
/* Win: ImeSelectHandler */
391380
static VOID ImeWnd_OnImeSelect(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
392381
{
393382
HKL hKL;
@@ -422,7 +411,6 @@ static VOID ImeWnd_OnImeSelect(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
422411
}
423412

424413
/* Handles WM_IME_CONTROL message of the default IME window. */
425-
/* Win: ImeControlHandler(pimeui, wParam, lParam, !unicode) */
426414
static LRESULT
427415
ImeWnd_OnImeControl(PIMEUI pimeui, WPARAM wParam, LPARAM lParam, BOOL unicode)
428416
{
@@ -558,7 +546,6 @@ ImeWnd_OnImeControl(PIMEUI pimeui, WPARAM wParam, LPARAM lParam, BOOL unicode)
558546
}
559547

560548
/* Modify the IME activation status. */
561-
/* Win: FocusSetIMCContext */
562549
static VOID FASTCALL User32SetImeActivenessOfWindow(HWND hWnd, BOOL bActive)
563550
{
564551
HIMC hIMC;
@@ -574,7 +561,6 @@ static VOID FASTCALL User32SetImeActivenessOfWindow(HWND hWnd, BOOL bActive)
574561
IMM_FN(ImmReleaseContext)(hWnd, hIMC);
575562
}
576563

577-
/* Win: CtfLoadThreadLayout */
578564
VOID FASTCALL CtfLoadThreadLayout(PIMEUI pimeui)
579565
{
580566
IMM_FN(CtfImmTIMActivate)(pimeui->hKL);
@@ -636,6 +622,59 @@ ImeWnd_SwitchSoftKbdProc(_In_ HIMC hIMC, _In_ LPARAM lParam)
636622
return TRUE;
637623
}
638624

625+
// indicdll!12
626+
typedef VOID (CALLBACK *FN_GetPenMenuData)(PUINT pnID, PDWORD_PTR pdwMenuData);
627+
static FN_GetPenMenuData s_pGetPenMenuData = NULL;
628+
#define IFN_GetPenMenuData 12
629+
630+
static BOOL CALLBACK
631+
User32GetPenMenuData(_Out_ PUINT pnID, _Out_ PDWORD_PTR pdwMenuData)
632+
{
633+
if (!s_pGetPenMenuData)
634+
{
635+
WCHAR szPath[MAX_PATH];
636+
HMODULE hIndicDll = GetModuleHandleW(L"indicdll.dll");
637+
if (!hIndicDll)
638+
{
639+
User32GetSystemFilePath(szPath, _countof(szPath), L"indicdll.dll");
640+
hIndicDll = LoadLibraryW(szPath);
641+
}
642+
if (!hIndicDll)
643+
{
644+
ERR("indicdll.dll not loaded: %s\n", debugstr_w(szPath));
645+
return FALSE;
646+
}
647+
648+
s_pGetPenMenuData =
649+
(FN_GetPenMenuData)GetProcAddress(hIndicDll, MAKEINTRESOURCEA(IFN_GetPenMenuData));
650+
}
651+
652+
if (!s_pGetPenMenuData)
653+
return FALSE;
654+
655+
s_pGetPenMenuData(pnID, pdwMenuData);
656+
return TRUE;
657+
}
658+
659+
// IMS_IMEMENUITEMSELECTED
660+
static VOID
661+
User32ImeMenuItemSelected(HWND hwndTarget)
662+
{
663+
if (!IsWindow(hwndTarget))
664+
return;
665+
666+
HIMC hIMC = IMM_FN(ImmGetContext)(hwndTarget);
667+
if (!hIMC)
668+
return;
669+
670+
UINT nID = 0;
671+
DWORD_PTR dwMenuData = 0;
672+
if (User32GetPenMenuData(&nID, &dwMenuData))
673+
IMM_FN(ImmNotifyIME)(hIMC, NI_IMEMENUSELECTED, nID, dwMenuData);
674+
675+
IMM_FN(ImmReleaseContext)(hwndTarget, hIMC);
676+
}
677+
639678
/* Handles WM_IME_SYSTEM message of the default IME window. */
640679
static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
641680
{
@@ -765,8 +804,8 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
765804
ret = IMM_FN(ImmPutImeMenuItemsIntoMappedFile)((HIMC)lParam);
766805
break;
767806

768-
case 0x1D:
769-
FIXME("\n");
807+
case IMS_IMEMENUITEMSELECTED:
808+
User32ImeMenuItemSelected((HWND)lParam);
770809
break;
771810

772811
case IMS_GETCONTEXT:
@@ -792,7 +831,6 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
792831
}
793832

794833
/* Handles WM_IME_SETCONTEXT message of the default IME window. */
795-
/* Win: ImeSetContextHandler */
796834
LRESULT ImeWnd_OnImeSetContext(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
797835
{
798836
LRESULT ret;
@@ -947,7 +985,6 @@ LRESULT ImeWnd_OnImeSetContext(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
947985
}
948986

949987
/* The window procedure of the default IME window */
950-
/* Win: ImeWndProcWorker(pWnd, msg, wParam, lParam, !unicode) */
951988
LRESULT WINAPI
952989
ImeWndProc_common(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode) // ReactOS
953990
{
@@ -1103,19 +1140,16 @@ ImeWndProc_common(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicod
11031140
return DefWindowProcA(hwnd, msg, wParam, lParam);
11041141
}
11051142

1106-
// Win: ImeWndProcA
11071143
LRESULT WINAPI ImeWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
11081144
{
11091145
return ImeWndProc_common(hwnd, msg, wParam, lParam, FALSE);
11101146
}
11111147

1112-
// Win: ImeWndProcW
11131148
LRESULT WINAPI ImeWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
11141149
{
11151150
return ImeWndProc_common(hwnd, msg, wParam, lParam, TRUE);
11161151
}
11171152

1118-
// Win: UpdatePerUserImmEnabling
11191153
BOOL WINAPI UpdatePerUserImmEnabling(VOID)
11201154
{
11211155
HMODULE imm32;

0 commit comments

Comments
 (0)