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 * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org)
15 #include <wine/debug.h>
18 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
20 #define IMM_INIT_MAGIC 0x19650412
23 Imm32ApiTable gImmApiEntries
= {0};
24 HINSTANCE ghImm32
= NULL
;
25 BOOL bImmInitializing
= FALSE
;
26 BOOL ImmApiTableZero
= TRUE
;
28 HRESULT WINAPI
GetImmFileName(PWSTR lpBuffer
, UINT uSize
)
31 STRSAFE_LPWSTR Safe
= lpBuffer
;
33 length
= GetSystemDirectoryW(lpBuffer
, uSize
);
34 if ( length
&& length
< uSize
)
36 StringCchCatW(Safe
, uSize
, L
"\\");
37 return StringCchCatW(Safe
, uSize
, L
"IMM32.DLL");
39 return StringCchCopyW(Safe
, uSize
, L
"IMM32.DLL");
43 * This function should not be implemented, it is used,
44 * if you can not load function from imm32.dll
46 BOOL WINAPI
IMM_ImmIsIME(HKL hKL
) { return 0; }
47 HIMC WINAPI
IMM_ImmAssociateContext(HWND hwnd
, HIMC himc
) { return 0; }
48 BOOL WINAPI
IMM_ImmReleaseContext(HWND hwnd
, HIMC himc
) { return 0; }
49 LRESULT WINAPI
IMM_ImmEscapeAW(HKL hkl
, HIMC himc
, UINT uint
, LPVOID lpvoid
) { return 0; }
50 LONG WINAPI
IMM_ImmGetCompositionStringAW(HIMC himc
, DWORD dword1
, LPVOID lpvoid
, DWORD dword2
) { return 0; }
51 BOOL WINAPI
IMM_ImmGetCompositionFontA(HIMC himc
, LPLOGFONTA lplf
) { return 0; }
52 BOOL WINAPI
IMM_ImmGetCompositionFontW(HIMC himc
, LPLOGFONTW lplf
) { return 0; }
53 BOOL WINAPI
IMM_ImmSetCompositionFontA(HIMC himc
, LPLOGFONTA lplf
) { return 0; }
54 BOOL WINAPI
IMM_ImmSetCompositionFontW(HIMC himc
, LPLOGFONTW lplf
) { return 0; }
55 BOOL WINAPI
IMM_ImmSetGetCompositionWindow(HIMC himc
, LPCOMPOSITIONFORM lpcf
) { return 0; }
56 HIMC WINAPI
IMM_ImmGetContext(HWND hwnd
) { return 0; }
57 HWND WINAPI
IMM_ImmGetDefaultIMEWnd(HWND hwnd
) { return 0; }
58 BOOL WINAPI
IMM_ImmNotifyIME(HIMC himc
, DWORD dword1
, DWORD dword2
, DWORD dword3
) { return 0; }
59 BOOL WINAPI
IMM_ImmRegisterClient(PVOID ptr
, HINSTANCE hMod
) { return 0; }
60 UINT WINAPI
IMM_ImmProcessKey(HWND hwnd
, HKL hkl
, UINT Vk
, LPARAM lParam
, DWORD HotKey
) { return 0; }
65 BOOL WINAPI
IntInitializeImmEntryTable(VOID
)
67 WCHAR ImmFile
[MAX_PATH
];
68 HMODULE imm32
= ghImm32
;
70 if (gImmApiEntries
.pImmIsIME
!= 0)
72 ERR("Imm Api Table Init 1\n");
76 GetImmFileName(ImmFile
, sizeof(ImmFile
));
77 TRACE("File %ws\n",ImmFile
);
81 imm32
= GetModuleHandleW(ImmFile
);
86 imm32
= ghImm32
= LoadLibraryW(ImmFile
);
89 ERR("Did not load!\n");
97 ImmApiTableZero
= FALSE
;
98 ZeroMemory(&gImmApiEntries
, sizeof(Imm32ApiTable
));
101 gImmApiEntries
.pImmIsIME
= (BOOL (WINAPI
*)(HKL
)) GetProcAddress(imm32
, "ImmIsIME");
102 if (!gImmApiEntries
.pImmIsIME
)
103 gImmApiEntries
.pImmIsIME
= IMM_ImmIsIME
;
105 gImmApiEntries
.pImmEscapeA
= (LRESULT (WINAPI
*)(HKL
, HIMC
, UINT
, LPVOID
)) GetProcAddress(imm32
, "ImmEscapeA");
106 if (!gImmApiEntries
.pImmEscapeA
)
107 gImmApiEntries
.pImmEscapeA
= IMM_ImmEscapeAW
;
109 gImmApiEntries
.pImmEscapeW
= (LRESULT (WINAPI
*)(HKL
, HIMC
, UINT
, LPVOID
)) GetProcAddress(imm32
, "ImmEscapeW");
110 if (!gImmApiEntries
.pImmEscapeW
)
111 gImmApiEntries
.pImmEscapeW
= IMM_ImmEscapeAW
;
113 gImmApiEntries
.pImmGetCompositionStringA
= (LONG (WINAPI
*)(HIMC
, DWORD
, LPVOID
, DWORD
)) GetProcAddress(imm32
, "ImmGetCompositionStringA");
114 if (!gImmApiEntries
.pImmGetCompositionStringA
)
115 gImmApiEntries
.pImmGetCompositionStringA
= IMM_ImmGetCompositionStringAW
;
117 gImmApiEntries
.pImmGetCompositionStringW
= (LONG (WINAPI
*)(HIMC
, DWORD
, LPVOID
, DWORD
)) GetProcAddress(imm32
, "ImmGetCompositionStringW");
118 if (!gImmApiEntries
.pImmGetCompositionStringW
)
119 gImmApiEntries
.pImmGetCompositionStringW
= IMM_ImmGetCompositionStringAW
;
121 gImmApiEntries
.pImmGetCompositionFontA
= (BOOL (WINAPI
*)(HIMC
, LPLOGFONTA
)) GetProcAddress(imm32
, "ImmGetCompositionFontA");
122 if (!gImmApiEntries
.pImmGetCompositionFontA
)
123 gImmApiEntries
.pImmGetCompositionFontA
= IMM_ImmGetCompositionFontA
;
125 gImmApiEntries
.pImmGetCompositionFontW
= (BOOL (WINAPI
*)(HIMC
, LPLOGFONTW
)) GetProcAddress(imm32
, "ImmGetCompositionFontW");
126 if (!gImmApiEntries
.pImmGetCompositionFontW
)
127 gImmApiEntries
.pImmGetCompositionFontW
= IMM_ImmGetCompositionFontW
;
129 gImmApiEntries
.pImmSetCompositionFontA
= (BOOL (WINAPI
*)(HIMC
, LPLOGFONTA
)) GetProcAddress(imm32
, "ImmSetCompositionFontA");
130 if (!gImmApiEntries
.pImmSetCompositionFontA
)
131 gImmApiEntries
.pImmSetCompositionFontA
= IMM_ImmSetCompositionFontA
;
133 gImmApiEntries
.pImmSetCompositionFontW
= (BOOL (WINAPI
*)(HIMC
, LPLOGFONTW
)) GetProcAddress(imm32
, "ImmSetCompositionFontW");
134 if (!gImmApiEntries
.pImmSetCompositionFontW
)
135 gImmApiEntries
.pImmSetCompositionFontW
= IMM_ImmSetCompositionFontW
;
137 gImmApiEntries
.pImmGetCompositionWindow
= (BOOL (WINAPI
*)(HIMC
, LPCOMPOSITIONFORM
)) GetProcAddress(imm32
, "ImmGetCompositionWindow");
138 if (!gImmApiEntries
.pImmGetCompositionWindow
)
139 gImmApiEntries
.pImmGetCompositionWindow
= IMM_ImmSetGetCompositionWindow
;
141 gImmApiEntries
.pImmSetCompositionWindow
= (BOOL (WINAPI
*)(HIMC
, LPCOMPOSITIONFORM
)) GetProcAddress(imm32
, "ImmSetCompositionWindow");
142 if (!gImmApiEntries
.pImmSetCompositionWindow
)
143 gImmApiEntries
.pImmSetCompositionWindow
= IMM_ImmSetGetCompositionWindow
;
145 gImmApiEntries
.pImmAssociateContext
= (HIMC (WINAPI
*)(HWND
, HIMC
)) GetProcAddress(imm32
, "ImmAssociateContext");
146 if (!gImmApiEntries
.pImmAssociateContext
)
147 gImmApiEntries
.pImmAssociateContext
= IMM_ImmAssociateContext
;
149 gImmApiEntries
.pImmReleaseContext
= (BOOL (WINAPI
*)(HWND
, HIMC
)) GetProcAddress(imm32
, "ImmReleaseContext");
150 if (!gImmApiEntries
.pImmReleaseContext
)
151 gImmApiEntries
.pImmReleaseContext
= IMM_ImmReleaseContext
;
153 gImmApiEntries
.pImmGetContext
= (HIMC (WINAPI
*)(HWND
)) GetProcAddress(imm32
, "ImmGetContext");
154 if (!gImmApiEntries
.pImmGetContext
)
155 gImmApiEntries
.pImmGetContext
= IMM_ImmGetContext
;
157 gImmApiEntries
.pImmGetDefaultIMEWnd
= (HWND (WINAPI
*)(HWND
)) GetProcAddress(imm32
, "ImmGetDefaultIMEWnd");
158 if (!gImmApiEntries
.pImmGetDefaultIMEWnd
)
159 gImmApiEntries
.pImmGetDefaultIMEWnd
= IMM_ImmGetDefaultIMEWnd
;
161 gImmApiEntries
.pImmNotifyIME
= (BOOL (WINAPI
*)(HIMC
, DWORD
, DWORD
, DWORD
)) GetProcAddress(imm32
, "ImmNotifyIME");
162 if (!gImmApiEntries
.pImmNotifyIME
)
163 gImmApiEntries
.pImmNotifyIME
= IMM_ImmNotifyIME
;
166 * TODO: Load more functions from imm32.dll
167 * Function like IMPSetIMEW, IMPQueryIMEW etc. call functions
168 * from imm32.dll through pointers in the structure gImmApiEntries.
169 * I do not know whether it is necessary to initialize a table
170 * of functions to load user32 (DLL_PROCESS_ATTACH)
173 gImmApiEntries
.pImmRegisterClient
= (BOOL (WINAPI
*)(PVOID
, HINSTANCE
)) GetProcAddress(imm32
, "ImmRegisterClient");
174 if (!gImmApiEntries
.pImmRegisterClient
)
175 gImmApiEntries
.pImmRegisterClient
= IMM_ImmRegisterClient
;
177 gImmApiEntries
.pImmProcessKey
= (UINT (WINAPI
*)(HWND
, HKL
, UINT
, LPARAM
, DWORD
)) GetProcAddress(imm32
, "ImmProcessKey");
178 if (!gImmApiEntries
.pImmProcessKey
)
179 gImmApiEntries
.pImmProcessKey
= IMM_ImmProcessKey
;
184 BOOL WINAPI
InitializeImmEntryTable(VOID
)
186 bImmInitializing
= TRUE
;
187 return IntInitializeImmEntryTable();
190 BOOL WINAPI
User32InitializeImmEntryTable(DWORD magic
)
192 TRACE("(%x)\n", magic
);
194 if (magic
!= IMM_INIT_MAGIC
)
197 if (gImmApiEntries
.pImmIsIME
!= 0)
199 ERR("Imm Api Table Init 2\n");
203 IntInitializeImmEntryTable();
205 if (ghImm32
== NULL
&& !bImmInitializing
)
207 WCHAR ImmFile
[MAX_PATH
];
208 ERR("IMM32 not installed!\n");
209 GetImmFileName(ImmFile
, sizeof(ImmFile
));
210 ERR("File %ws\n",ImmFile
);
211 ghImm32
= LoadLibraryW(ImmFile
);
214 ERR("Did not load! 2\n");
218 #if 0 // For real Imm32.dll testing!!!!
219 if (ghImm32
&& !gImmApiEntries
.pImmRegisterClient(&gSharedInfo
, ghImm32
))
221 ERR("Wine is stubed!\n");
227 LRESULT WINAPI
ImeWndProc_common( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
) // ReactOS
232 pWnd
= ValidateHwnd(hwnd
);
237 if (msg
!= WM_NCCREATE
)
240 return DefWindowProcW(hwnd
, msg
, wParam
, lParam
);
241 return DefWindowProcA(hwnd
, msg
, wParam
, lParam
);
243 NtUserSetWindowFNID(hwnd
, FNID_IME
);
244 pimeui
= HeapAlloc( GetProcessHeap(), 0, sizeof(IMEUI
) );
245 SetWindowLongPtrW(hwnd
, 0, (LONG_PTR
)pimeui
);
249 if (pWnd
->fnid
!= FNID_IME
)
251 ERR("Wrong window class for Ime! fnId 0x%x\n",pWnd
->fnid
);
254 pimeui
= ((PIMEWND
)pWnd
)->pimeui
;
257 ERR("Window is not set to IME!\n");
263 if (msg
==WM_CREATE
|| msg
==WM_NCCREATE
)
266 if (msg
==WM_NCDESTROY
)
268 HeapFree( GetProcessHeap(), 0, pimeui
);
269 SetWindowLongPtrW(hwnd
, 0, 0);
270 NtUserSetWindowFNID(hwnd
, FNID_DESTROY
);
274 return DefWindowProcW(hwnd
, msg
, wParam
, lParam
);
275 return DefWindowProcA(hwnd
, msg
, wParam
, lParam
);
278 LRESULT WINAPI
ImeWndProcA( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
280 return ImeWndProc_common(hwnd
, msg
, wParam
, lParam
, FALSE
);
283 LRESULT WINAPI
ImeWndProcW( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
285 return ImeWndProc_common(hwnd
, msg
, wParam
, lParam
, TRUE
);
288 static const WCHAR imeW
[] = {'I','M','E',0};
292 RegisterIMEClass(VOID
)
294 WNDCLASSEXW WndClass
;
297 ZeroMemory(&WndClass
, sizeof(WndClass
));
299 WndClass
.cbSize
= sizeof(WndClass
);
300 WndClass
.lpszClassName
= imeW
;
301 WndClass
.style
= CS_GLOBALCLASS
;
302 WndClass
.lpfnWndProc
= ImeWndProcW
;
303 WndClass
.cbWndExtra
= sizeof(LONG_PTR
);
304 WndClass
.hCursor
= LoadCursorW(NULL
, IDC_ARROW
);
306 atom
= RegisterClassExWOWW( &WndClass
,
313 RegisterDefaultClasses
|= ICLASS_TO_MASK(ICLS_IME
);
316 ERR("Failed to register IME Class!\n");
323 BOOL WINAPI
CliImmSetHotKey(DWORD dwID
, UINT uModifiers
, UINT uVirtualKey
, HKL hKl
)
334 IMPSetIMEW(HWND hwnd
, LPIMEPROW ime
)
345 IMPQueryIMEW(LPIMEPROW ime
)
356 IMPGetIMEW(HWND hwnd
, LPIMEPROW ime
)
367 IMPSetIMEA(HWND hwnd
, LPIMEPROA ime
)
378 IMPQueryIMEA(LPIMEPROA ime
)
389 IMPGetIMEA(HWND hwnd
, LPIMEPROA ime
)
400 SendIMEMessageExW(HWND hwnd
, LPARAM lparam
)
411 SendIMEMessageExA(HWND hwnd
, LPARAM lparam
)
422 WINNLSEnableIME(HWND hwnd
, BOOL enable
)
433 WINNLSGetEnableStatus(HWND hwnd
)
444 WINNLSGetIMEHotkey(HWND hwnd
)