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
2625HWND 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
4745Imm32ApiTable 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
5653HRESULT
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
7072static 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
119120BOOL WINAPI InitializeImmEntryTable (VOID )
120121{
121122 gbImmInitializing = TRUE;
122123 return IntInitializeImmEntryTable ();
123124}
124125
125- // Win: User32InitializeImmEntryTable
126126BOOL 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
155154static 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
162160static 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) */
169166static LRESULT
170167User32SendImeUIMessage (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
199195static 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
214209static 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
224218static 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 */
246239static 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 */
297289static 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 */
343334static 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 */
375365static 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 */
391380static 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) */
426414static LRESULT
427415ImeWnd_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 */
562549static 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 */
578564VOID 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. */
640679static 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 */
796834LRESULT 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) */
951988LRESULT WINAPI
952989ImeWndProc_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
11071143LRESULT 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
11131148LRESULT 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
11191153BOOL WINAPI UpdatePerUserImmEnabling (VOID )
11201154{
11211155 HMODULE imm32 ;
0 commit comments