1 /* 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 (dmitry@reactos.org) 7 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 8 * UPDATE HISTORY: 9 * 01/27/2009 Created 10 */ 11 12 #include <user32.h> 13 #include <strsafe.h> 14 15 WINE_DEFAULT_DEBUG_CHANNEL(user32); 16 17 #define IMM_INIT_MAGIC 0x19650412 18 19 HINSTANCE ghImm32 = NULL; 20 BOOL bImmInitializing = FALSE; 21 22 /* define stub functions */ 23 #undef DEFINE_IMM_ENTRY 24 #define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \ 25 static type WINAPI IMMSTUB_##name params { IMM_RETURN_##retkind((type)retval); } 26 #include "immtable.h" 27 28 Imm32ApiTable gImmApiEntries = { 29 /* initialize by stubs */ 30 #undef DEFINE_IMM_ENTRY 31 #define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \ 32 IMMSTUB_##name, 33 #include "immtable.h" 34 }; 35 36 HRESULT WINAPI GetImmFileName(PWSTR lpBuffer, UINT uSize) 37 { 38 UINT length; 39 STRSAFE_LPWSTR Safe = lpBuffer; 40 41 length = GetSystemDirectoryW(lpBuffer, uSize); 42 if ( length && length < uSize ) 43 { 44 StringCchCatW(Safe, uSize, L"\\"); 45 return StringCchCatW(Safe, uSize, L"imm32.dll"); 46 } 47 return StringCchCopyW(Safe, uSize, L"imm32.dll"); 48 } 49 50 /* 51 * @unimplemented 52 */ 53 BOOL WINAPI IntInitializeImmEntryTable(VOID) 54 { 55 WCHAR ImmFile[MAX_PATH]; 56 HMODULE imm32 = ghImm32; 57 58 GetImmFileName(ImmFile, sizeof(ImmFile)); 59 TRACE("File %ws\n",ImmFile); 60 61 if (imm32 == NULL) 62 { 63 imm32 = GetModuleHandleW(ImmFile); 64 } 65 66 if (imm32 == NULL) 67 { 68 imm32 = ghImm32 = LoadLibraryW(ImmFile); 69 if (imm32 == NULL) 70 { 71 ERR("Did not load!\n"); 72 return FALSE; 73 } 74 return TRUE; 75 } 76 77 /* load imm procedures */ 78 #undef DEFINE_IMM_ENTRY 79 #define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \ 80 do { \ 81 FN_##name proc = (FN_##name)GetProcAddress(imm32, #name); \ 82 if (proc) { \ 83 IMM_FN(name) = proc; \ 84 } \ 85 } while (0); 86 #include "immtable.h" 87 88 return TRUE; 89 } 90 91 BOOL WINAPI InitializeImmEntryTable(VOID) 92 { 93 bImmInitializing = TRUE; 94 return IntInitializeImmEntryTable(); 95 } 96 97 BOOL WINAPI User32InitializeImmEntryTable(DWORD magic) 98 { 99 TRACE("Imm (%x)\n", magic); 100 101 if (magic != IMM_INIT_MAGIC) 102 return FALSE; 103 104 if (IMM_FN(ImmIsIME) != IMMSTUB_ImmIsIME) 105 return TRUE; 106 107 IntInitializeImmEntryTable(); 108 109 if (ghImm32 == NULL && !bImmInitializing) 110 { 111 WCHAR ImmFile[MAX_PATH]; 112 GetImmFileName(ImmFile, sizeof(ImmFile)); 113 ghImm32 = LoadLibraryW(ImmFile); 114 if (ghImm32 == NULL) 115 { 116 ERR("Did not load! 2\n"); 117 return FALSE; 118 } 119 } 120 121 return TRUE; 122 } 123 124 LRESULT WINAPI ImeWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode ) // ReactOS 125 { 126 PWND pWnd; 127 PIMEUI pimeui; 128 129 pWnd = ValidateHwnd(hwnd); 130 if (pWnd) 131 { 132 if (!pWnd->fnid) 133 { 134 if (msg != WM_NCCREATE) 135 { 136 if (unicode) 137 return DefWindowProcW(hwnd, msg, wParam, lParam); 138 return DefWindowProcA(hwnd, msg, wParam, lParam); 139 } 140 NtUserSetWindowFNID(hwnd, FNID_IME); 141 pimeui = HeapAlloc( GetProcessHeap(), 0, sizeof(IMEUI) ); 142 SetWindowLongPtrW(hwnd, 0, (LONG_PTR)pimeui); 143 } 144 else 145 { 146 if (pWnd->fnid != FNID_IME) 147 { 148 ERR("Wrong window class for Ime! fnId 0x%x\n",pWnd->fnid); 149 return 0; 150 } 151 pimeui = ((PIMEWND)pWnd)->pimeui; 152 if (pimeui == NULL) 153 { 154 ERR("Window is not set to IME!\n"); 155 return 0; 156 } 157 } 158 } 159 160 if (msg==WM_CREATE || msg==WM_NCCREATE) 161 return TRUE; 162 163 if (msg==WM_NCDESTROY) 164 { 165 HeapFree( GetProcessHeap(), 0, pimeui ); 166 SetWindowLongPtrW(hwnd, 0, 0); 167 NtUserSetWindowFNID(hwnd, FNID_DESTROY); 168 } 169 170 if (unicode) 171 return DefWindowProcW(hwnd, msg, wParam, lParam); 172 return DefWindowProcA(hwnd, msg, wParam, lParam); 173 } 174 175 LRESULT WINAPI ImeWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) 176 { 177 return ImeWndProc_common(hwnd, msg, wParam, lParam, FALSE); 178 } 179 180 LRESULT WINAPI ImeWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) 181 { 182 return ImeWndProc_common(hwnd, msg, wParam, lParam, TRUE); 183 } 184 185 BOOL 186 WINAPI 187 UpdatePerUserImmEnabling(VOID) 188 { 189 BOOL Ret = NtUserCallNoParam(NOPARAM_ROUTINE_UPDATEPERUSERIMMENABLING); 190 if ( Ret ) 191 { 192 if ( gpsi->dwSRVIFlags & SRVINFO_IMM32 ) 193 { 194 HMODULE imm32 = GetModuleHandleW(L"imm32.dll"); 195 if ( !imm32 ) 196 { 197 imm32 = LoadLibraryW(L"imm32.dll"); 198 if (!imm32) 199 { 200 ERR("UPUIE: Imm32 not installed!\n"); 201 Ret = FALSE; 202 } 203 } 204 } 205 } 206 return Ret; 207 } 208 209 static const WCHAR imeW[] = {'I','M','E',0}; 210 211 BOOL 212 WINAPI 213 RegisterIMEClass(VOID) 214 { 215 WNDCLASSEXW WndClass; 216 ATOM atom; 217 218 ZeroMemory(&WndClass, sizeof(WndClass)); 219 220 WndClass.cbSize = sizeof(WndClass); 221 WndClass.lpszClassName = imeW; 222 WndClass.style = CS_GLOBALCLASS; 223 WndClass.lpfnWndProc = ImeWndProcW; 224 WndClass.cbWndExtra = sizeof(LONG_PTR); 225 WndClass.hCursor = LoadCursorW(NULL, IDC_ARROW); 226 227 atom = RegisterClassExWOWW( &WndClass, 228 0, 229 FNID_IME, 230 0, 231 FALSE); 232 if (atom) 233 { 234 RegisterDefaultClasses |= ICLASS_TO_MASK(ICLS_IME); 235 TRACE("Register IME Class!\n"); 236 return TRUE; 237 } 238 ERR("Failed to register IME Class!\n"); 239 return FALSE; 240 } 241 242 /* 243 * @unimplemented 244 */ 245 BOOL WINAPI CliImmSetHotKey(DWORD dwID, UINT uModifiers, UINT uVirtualKey, HKL hKl) 246 { 247 UNIMPLEMENTED; 248 return FALSE; 249 } 250 251 /* 252 * @implemented 253 */ 254 BOOL 255 WINAPI 256 IMPSetIMEW(HWND hwnd, LPIMEPROW ime) 257 { 258 return IMM_FN(ImmIMPSetIMEW)(hwnd, ime); 259 } 260 261 /* 262 * @implemented 263 */ 264 BOOL 265 WINAPI 266 IMPQueryIMEW(LPIMEPROW ime) 267 { 268 return IMM_FN(ImmIMPQueryIMEW)(ime); 269 } 270 271 /* 272 * @implemented 273 */ 274 BOOL 275 WINAPI 276 IMPGetIMEW(HWND hwnd, LPIMEPROW ime) 277 { 278 return IMM_FN(ImmIMPGetIMEW)(hwnd, ime); 279 } 280 281 /* 282 * @implemented 283 */ 284 BOOL 285 WINAPI 286 IMPSetIMEA(HWND hwnd, LPIMEPROA ime) 287 { 288 return IMM_FN(ImmIMPSetIMEA)(hwnd, ime); 289 } 290 291 /* 292 * @implemented 293 */ 294 BOOL 295 WINAPI 296 IMPQueryIMEA(LPIMEPROA ime) 297 { 298 return IMM_FN(ImmIMPQueryIMEA)(ime); 299 } 300 301 /* 302 * @implemented 303 */ 304 BOOL 305 WINAPI 306 IMPGetIMEA(HWND hwnd, LPIMEPROA ime) 307 { 308 return IMM_FN(ImmIMPGetIMEA)(hwnd, ime); 309 } 310 311 /* 312 * @implemented 313 */ 314 LRESULT 315 WINAPI 316 SendIMEMessageExW(HWND hwnd, LPARAM lParam) 317 { 318 return IMM_FN(ImmSendIMEMessageExW)(hwnd, lParam); 319 } 320 321 /* 322 * @implemented 323 */ 324 LRESULT 325 WINAPI 326 SendIMEMessageExA(HWND hwnd, LPARAM lParam) 327 { 328 return IMM_FN(ImmSendIMEMessageExA)(hwnd, lParam); 329 } 330 331 /* 332 * @implemented 333 */ 334 BOOL 335 WINAPI 336 WINNLSEnableIME(HWND hwnd, BOOL enable) 337 { 338 return IMM_FN(ImmWINNLSEnableIME)(hwnd, enable); 339 } 340 341 /* 342 * @implemented 343 */ 344 BOOL 345 WINAPI 346 WINNLSGetEnableStatus(HWND hwnd) 347 { 348 return IMM_FN(ImmWINNLSGetEnableStatus)(hwnd); 349 } 350 351 /* 352 * @implemented 353 */ 354 UINT 355 WINAPI 356 WINNLSGetIMEHotkey(HWND hwnd) 357 { 358 return FALSE; 359 } 360