imm32: Implement ImmRegisterWord using loaded IME.
[wine/multimedia.git] / dlls / imm32 / imm.c
blob4ffb4813e38ed228236f02a5ae9c0a844ac205c3
1 /*
2 * IMM32 library
4 * Copyright 1998 Patrik Stridvall
5 * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <stdio.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winerror.h"
30 #include "wine/debug.h"
31 #include "imm.h"
32 #include "ddk/imm.h"
33 #include "winnls.h"
34 #include "winreg.h"
35 #include "wine/list.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(imm);
39 typedef struct tagIMCCInternal
41 DWORD dwLock;
42 DWORD dwSize;
43 } IMCCInternal;
45 #define MAKE_FUNCPTR(f) typeof(f) * p##f
46 typedef struct _tagImmHkl{
47 struct list entry;
48 HKL hkl;
49 HMODULE hIME;
50 IMEINFO imeInfo;
51 WCHAR imeClassName[17]; /* 16 character max */
52 ULONG uSelected;
54 /* Function Pointers */
55 MAKE_FUNCPTR(ImeInquire);
56 MAKE_FUNCPTR(ImeConfigure);
57 MAKE_FUNCPTR(ImeDestroy);
58 MAKE_FUNCPTR(ImeEscape);
59 MAKE_FUNCPTR(ImeSelect);
60 MAKE_FUNCPTR(ImeSetActiveContext);
61 MAKE_FUNCPTR(ImeToAsciiEx);
62 MAKE_FUNCPTR(NotifyIME);
63 MAKE_FUNCPTR(ImeRegisterWord);
64 MAKE_FUNCPTR(ImeUnregisterWord);
65 MAKE_FUNCPTR(ImeEnumRegisterWord);
66 MAKE_FUNCPTR(ImeSetCompositionString);
67 MAKE_FUNCPTR(ImeConversionList);
68 MAKE_FUNCPTR(ImeProcessKey);
69 MAKE_FUNCPTR(ImeGetRegisterWordStyle);
70 MAKE_FUNCPTR(ImeGetImeMenuItems);
71 } ImmHkl;
72 #undef MAKE_FUNCPTR
74 typedef struct tagInputContextData
76 DWORD dwLock;
77 INPUTCONTEXT IMC;
79 ImmHkl *immKbd;
80 HWND imeWnd;
81 } InputContextData;
83 typedef struct _tagTRANSMSG {
84 UINT message;
85 WPARAM wParam;
86 LPARAM lParam;
87 } TRANSMSG, *LPTRANSMSG;
89 typedef struct _tagIMMThreadData {
90 HIMC defaultContext;
91 HWND hwndDefault;
92 } IMMThreadData;
94 static HANDLE hImeInst;
95 static DWORD tlsIndex = 0;
96 static struct list ImmHklList = LIST_INIT(ImmHklList);
98 /* MSIME messages */
99 static UINT WM_MSIME_SERVICE;
100 static UINT WM_MSIME_RECONVERTOPTIONS;
101 static UINT WM_MSIME_MOUSE;
102 static UINT WM_MSIME_RECONVERTREQUEST;
103 static UINT WM_MSIME_RECONVERT;
104 static UINT WM_MSIME_QUERYPOSITION;
105 static UINT WM_MSIME_DOCUMENTFEED;
107 static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0};
109 #define is_himc_ime_unicode(p) (p->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE)
110 #define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE)
112 static BOOL IMM_DestroyContext(HIMC hIMC);
114 static inline WCHAR *strdupAtoW( const char *str )
116 WCHAR *ret = NULL;
117 if (str)
119 DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
120 if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
121 MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
123 return ret;
126 static inline CHAR *strdupWtoA( const WCHAR *str )
128 CHAR *ret = NULL;
129 if (str)
131 DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
132 if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
133 WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
135 return ret;
138 static IMMThreadData* IMM_GetThreadData(void)
140 return (IMMThreadData*)TlsGetValue(tlsIndex);
143 static void IMM_InitThreadData(void)
145 IMMThreadData* data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
146 sizeof(IMMThreadData));
147 TlsSetValue(tlsIndex,data);
149 TRACE("Thread Data Created\n");
152 static void IMM_FreeThreadData(void)
154 IMMThreadData* data = TlsGetValue(tlsIndex);
155 IMM_DestroyContext(data->defaultContext);
156 DestroyWindow(data->hwndDefault);
157 HeapFree(GetProcessHeap(),0,data);
158 TRACE("Thread Data Destroyed\n");
161 static HMODULE LoadDefaultWineIME(void)
163 char buffer[MAX_PATH], libname[32], *name, *next;
164 HMODULE module = 0;
165 HKEY hkey;
167 TRACE("Attempting to fall back to wine default IME\n");
169 strcpy( buffer, "x11" ); /* default value */
170 /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
171 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
173 DWORD type, count = sizeof(buffer);
174 RegQueryValueExA( hkey, "Ime", 0, &type, (LPBYTE) buffer, &count );
175 RegCloseKey( hkey );
178 name = buffer;
179 while (name)
181 next = strchr( name, ',' );
182 if (next) *next++ = 0;
184 snprintf( libname, sizeof(libname), "wine%s.drv", name );
185 if ((module = LoadLibraryA( libname )) != 0) break;
186 name = next;
189 return module;
192 /* ImmHkl loading and freeing */
193 #define LOAD_FUNCPTR(f) if((ptr->p##f = (LPVOID)GetProcAddress(ptr->hIME, #f)) == NULL){WARN("Can't find function %s in ime\n", #f);}
194 static ImmHkl *IMM_GetImmHkl(HKL hkl)
196 ImmHkl *ptr;
197 WCHAR filename[MAX_PATH];
199 TRACE("Seeking ime for keyboard 0x%x\n",(unsigned)hkl);
201 LIST_FOR_EACH_ENTRY(ptr, &ImmHklList, ImmHkl, entry)
203 if (ptr->hkl == hkl)
204 return ptr;
206 /* not found... create it */
208 ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ImmHkl));
210 ptr->hkl = hkl;
211 if (ImmGetIMEFileNameW(hkl, filename, MAX_PATH)) ptr->hIME = LoadLibraryW(filename);
212 if (!ptr->hIME)
213 ptr->hIME = LoadDefaultWineIME();
214 if (ptr->hIME)
216 LOAD_FUNCPTR(ImeInquire);
217 if (!ptr->pImeInquire || !ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL))
219 FreeLibrary(ptr->hIME);
220 ptr->hIME = NULL;
222 else
224 LOAD_FUNCPTR(ImeDestroy);
225 LOAD_FUNCPTR(ImeSelect);
226 if (!ptr->pImeSelect || !ptr->pImeDestroy)
228 FreeLibrary(ptr->hIME);
229 ptr->hIME = NULL;
231 else
233 LOAD_FUNCPTR(ImeConfigure);
234 LOAD_FUNCPTR(ImeEscape);
235 LOAD_FUNCPTR(ImeSetActiveContext);
236 LOAD_FUNCPTR(ImeToAsciiEx);
237 LOAD_FUNCPTR(NotifyIME);
238 LOAD_FUNCPTR(ImeRegisterWord);
239 LOAD_FUNCPTR(ImeUnregisterWord);
240 LOAD_FUNCPTR(ImeEnumRegisterWord);
241 LOAD_FUNCPTR(ImeSetCompositionString);
242 LOAD_FUNCPTR(ImeConversionList);
243 LOAD_FUNCPTR(ImeProcessKey);
244 LOAD_FUNCPTR(ImeGetRegisterWordStyle);
245 LOAD_FUNCPTR(ImeGetImeMenuItems);
246 /* make sure our classname is WCHAR */
247 if (!is_kbd_ime_unicode(ptr))
249 WCHAR bufW[17];
250 MultiByteToWideChar(CP_ACP, 0, (LPSTR)ptr->imeClassName,
251 -1, bufW, 17);
252 lstrcpyW(ptr->imeClassName, bufW);
257 list_add_head(&ImmHklList,&ptr->entry);
259 return ptr;
261 #undef LOAD_FUNCPTR
263 static void IMM_FreeAllImmHkl(void)
265 ImmHkl *ptr,*cursor2;
267 LIST_FOR_EACH_ENTRY_SAFE(ptr, cursor2, &ImmHklList, ImmHkl, entry)
269 list_remove(&ptr->entry);
270 if (ptr->hIME)
272 ptr->pImeDestroy(1);
273 FreeLibrary(ptr->hIME);
275 HeapFree(GetProcessHeap(),0,ptr);
279 static void IMM_RegisterMessages(void)
281 WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
282 WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
283 WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
284 WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
285 WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
286 WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
287 WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
290 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
292 TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
293 switch (fdwReason)
295 case DLL_PROCESS_ATTACH:
296 hImeInst = hInstDLL;
297 IMM_RegisterMessages();
298 tlsIndex = TlsAlloc();
299 IMM_InitThreadData();
300 break;
301 case DLL_THREAD_ATTACH:
302 IMM_InitThreadData();
303 break;
304 case DLL_THREAD_DETACH:
305 IMM_FreeThreadData();
306 break;
307 case DLL_PROCESS_DETACH:
308 IMM_FreeThreadData();
309 IMM_FreeAllImmHkl();
310 TlsFree(tlsIndex);
311 break;
313 return TRUE;
316 /* for posting messages as the IME */
317 static void ImmInternalPostIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam)
319 HWND target = GetFocus();
320 if (!target)
321 PostMessageW(data->IMC.hWnd,msg,wParam,lParam);
322 else
323 PostMessageW(target, msg, wParam, lParam);
326 static LRESULT ImmInternalSendIMENotify(InputContextData *data, WPARAM notify, LPARAM lParam)
328 HWND target;
330 target = data->IMC.hWnd;
331 if (!target) target = GetFocus();
333 if (target)
334 return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
336 return 0;
339 static HIMCC ImmCreateBlankCompStr(void)
341 HIMCC rc;
342 LPCOMPOSITIONSTRING ptr;
343 rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
344 ptr = (LPCOMPOSITIONSTRING)ImmLockIMCC(rc);
345 memset(ptr,0,sizeof(COMPOSITIONSTRING));
346 ptr->dwSize = sizeof(COMPOSITIONSTRING);
347 ImmUnlockIMCC(rc);
348 return rc;
351 /***********************************************************************
352 * ImmAssociateContext (IMM32.@)
354 HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
356 HIMC old = NULL;
357 InputContextData *data = (InputContextData*)hIMC;
359 TRACE("(%p, %p):\n", hWnd, hIMC);
361 if (!IMM_GetThreadData()->defaultContext)
362 IMM_GetThreadData()->defaultContext = ImmCreateContext();
365 * If already associated just return
367 if (hIMC && data->IMC.hWnd == hWnd)
368 return hIMC;
370 if (hWnd)
372 old = (HIMC)RemovePropW(hWnd,szwWineIMCProperty);
374 if (old == NULL)
375 old = IMM_GetThreadData()->defaultContext;
376 else if (old == (HIMC)-1)
377 old = NULL;
379 if (hIMC != IMM_GetThreadData()->defaultContext)
381 if (hIMC == NULL) /* Meaning disable imm for that window*/
382 SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
383 else
384 SetPropW(hWnd,szwWineIMCProperty,(HANDLE)hIMC);
388 if (!hIMC)
389 return old;
391 if (IsWindow(data->IMC.hWnd))
394 * Post a message that your context is switching
396 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
399 data->IMC.hWnd = hWnd;
401 if (IsWindow(data->IMC.hWnd))
404 * Post a message that your context is switching
406 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
409 return old;
412 /***********************************************************************
413 * ImmAssociateContextEx (IMM32.@)
415 BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
417 FIXME("(%p, %p, %d): stub\n", hWnd, hIMC, dwFlags);
418 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
419 return FALSE;
422 /***********************************************************************
423 * ImmConfigureIMEA (IMM32.@)
425 BOOL WINAPI ImmConfigureIMEA(
426 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
428 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
430 TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
432 if (immHkl->hIME && immHkl->pImeConfigure)
434 if (dwMode != IME_CONFIG_REGISTERWORD || !is_kbd_ime_unicode(immHkl))
435 return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
436 else
438 REGISTERWORDW rww;
439 REGISTERWORDA *rwa = (REGISTERWORDA*)lpData;
440 BOOL rc;
442 rww.lpReading = strdupAtoW(rwa->lpReading);
443 rww.lpWord = strdupAtoW(rwa->lpWord);
444 rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rww);
445 HeapFree(GetProcessHeap(),0,rww.lpReading);
446 HeapFree(GetProcessHeap(),0,rww.lpWord);
447 return rc;
450 else
451 return FALSE;
454 /***********************************************************************
455 * ImmConfigureIMEW (IMM32.@)
457 BOOL WINAPI ImmConfigureIMEW(
458 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
460 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
462 TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
464 if (immHkl->hIME && immHkl->pImeConfigure)
466 if (dwMode != IME_CONFIG_REGISTERWORD || is_kbd_ime_unicode(immHkl))
467 return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
468 else
470 REGISTERWORDW *rww = (REGISTERWORDW*)lpData;
471 REGISTERWORDA rwa;
472 BOOL rc;
474 rwa.lpReading = strdupWtoA(rww->lpReading);
475 rwa.lpWord = strdupWtoA(rww->lpWord);
476 rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rwa);
477 HeapFree(GetProcessHeap(),0,rwa.lpReading);
478 HeapFree(GetProcessHeap(),0,rwa.lpWord);
479 return rc;
482 else
483 return FALSE;
486 /***********************************************************************
487 * ImmCreateContext (IMM32.@)
489 HIMC WINAPI ImmCreateContext(void)
491 InputContextData *new_context;
493 new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
495 /* Load the IME */
496 new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
498 if (!new_context->immKbd->hIME)
500 TRACE("IME dll could not be loaded\n");
501 HeapFree(GetProcessHeap(),0,new_context);
502 return 0;
505 /* hCompStr is never NULL */
506 new_context->IMC.hCompStr = ImmCreateBlankCompStr();
507 new_context->IMC.hMsgBuf = ImmCreateIMCC(1);
509 /* Initialize the IME Private */
510 new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
512 if (!new_context->immKbd->pImeSelect(new_context, TRUE))
514 TRACE("Selection of IME failed\n");
515 IMM_DestroyContext(new_context);
516 return 0;
519 new_context->immKbd->uSelected++;
520 TRACE("Created context 0x%x\n",(UINT)new_context);
522 return (HIMC)new_context;
525 static BOOL IMM_DestroyContext(HIMC hIMC)
527 InputContextData *data = (InputContextData*)hIMC;
529 TRACE("Destroying %p\n",hIMC);
531 if (hIMC)
533 data->immKbd->uSelected --;
534 data->immKbd->pImeSelect(hIMC, FALSE);
536 if (IMM_GetThreadData()->hwndDefault == data->imeWnd)
537 IMM_GetThreadData()->hwndDefault = NULL;
538 DestroyWindow(data->imeWnd);
540 ImmDestroyIMCC(data->IMC.hCompStr);
541 ImmDestroyIMCC(data->IMC.hCandInfo);
542 ImmDestroyIMCC(data->IMC.hGuideLine);
543 ImmDestroyIMCC(data->IMC.hPrivate);
544 ImmDestroyIMCC(data->IMC.hMsgBuf);
546 HeapFree(GetProcessHeap(),0,data);
548 return TRUE;
551 /***********************************************************************
552 * ImmDestroyContext (IMM32.@)
554 BOOL WINAPI ImmDestroyContext(HIMC hIMC)
556 if (hIMC != IMM_GetThreadData()->defaultContext)
557 return IMM_DestroyContext(hIMC);
558 else
559 return FALSE;
562 /***********************************************************************
563 * ImmDisableIME (IMM32.@)
565 BOOL WINAPI ImmDisableIME(DWORD idThread)
567 FIXME("(%d): stub\n", idThread);
568 return TRUE;
571 /***********************************************************************
572 * ImmEnumRegisterWordA (IMM32.@)
574 UINT WINAPI ImmEnumRegisterWordA(
575 HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
576 LPCSTR lpszReading, DWORD dwStyle,
577 LPCSTR lpszRegister, LPVOID lpData)
579 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
580 TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL, lpfnEnumProc,
581 debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister), lpData);
582 if (immHkl->hIME && immHkl->pImeEnumRegisterWord)
584 if (!is_kbd_ime_unicode(immHkl))
585 return immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
586 (LPCWSTR)lpszReading, dwStyle, (LPCWSTR)lpszRegister, lpData);
587 else
589 FIXME("A procedure called with W ime back end\n");
590 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
591 return 0;
594 else
595 return 0;
598 /***********************************************************************
599 * ImmEnumRegisterWordW (IMM32.@)
601 UINT WINAPI ImmEnumRegisterWordW(
602 HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
603 LPCWSTR lpszReading, DWORD dwStyle,
604 LPCWSTR lpszRegister, LPVOID lpData)
606 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
607 TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL, lpfnEnumProc,
608 debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister), lpData);
609 if (immHkl->hIME && immHkl->pImeEnumRegisterWord)
611 if (is_kbd_ime_unicode(immHkl))
612 return immHkl->pImeEnumRegisterWord(lpfnEnumProc, lpszReading, dwStyle,
613 lpszRegister, lpData);
614 else
616 FIXME("W procedure called with A ime back end\n");
617 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
618 return 0;
621 else
622 return 0;
625 /***********************************************************************
626 * ImmEscapeA (IMM32.@)
628 LRESULT WINAPI ImmEscapeA(
629 HKL hKL, HIMC hIMC,
630 UINT uEscape, LPVOID lpData)
632 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
633 TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
635 if (immHkl->hIME && immHkl->pImeEscape)
637 if (!is_kbd_ime_unicode(immHkl))
638 return immHkl->pImeEscape(hIMC,uEscape,lpData);
639 else
641 FIXME("A procedure called with W ime back end\n");
642 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
643 return 0;
646 else
647 return 0;
650 /***********************************************************************
651 * ImmEscapeW (IMM32.@)
653 LRESULT WINAPI ImmEscapeW(
654 HKL hKL, HIMC hIMC,
655 UINT uEscape, LPVOID lpData)
657 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
658 TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
660 if (immHkl->hIME && immHkl->pImeEscape)
662 if (is_kbd_ime_unicode(immHkl))
663 return immHkl->pImeEscape(hIMC,uEscape,lpData);
664 else
666 FIXME("W procedure called with A ime back end\n");
667 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
668 return 0;
671 else
672 return 0;
675 /***********************************************************************
676 * ImmGetCandidateListA (IMM32.@)
678 DWORD WINAPI ImmGetCandidateListA(
679 HIMC hIMC, DWORD deIndex,
680 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
682 FIXME("(%p, %d, %p, %d): stub\n",
683 hIMC, deIndex,
684 lpCandList, dwBufLen
686 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
687 return 0;
690 /***********************************************************************
691 * ImmGetCandidateListCountA (IMM32.@)
693 DWORD WINAPI ImmGetCandidateListCountA(
694 HIMC hIMC, LPDWORD lpdwListCount)
696 FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
697 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
698 return 0;
701 /***********************************************************************
702 * ImmGetCandidateListCountW (IMM32.@)
704 DWORD WINAPI ImmGetCandidateListCountW(
705 HIMC hIMC, LPDWORD lpdwListCount)
707 FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
708 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
709 return 0;
712 /***********************************************************************
713 * ImmGetCandidateListW (IMM32.@)
715 DWORD WINAPI ImmGetCandidateListW(
716 HIMC hIMC, DWORD deIndex,
717 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
719 FIXME("(%p, %d, %p, %d): stub\n",
720 hIMC, deIndex,
721 lpCandList, dwBufLen
723 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
724 return 0;
727 /***********************************************************************
728 * ImmGetCandidateWindow (IMM32.@)
730 BOOL WINAPI ImmGetCandidateWindow(
731 HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
733 FIXME("(%p, %d, %p): stub\n", hIMC, dwBufLen, lpCandidate);
734 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
735 return FALSE;
738 /***********************************************************************
739 * ImmGetCompositionFontA (IMM32.@)
741 BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
743 LOGFONTW lfW;
744 BOOL rc;
746 TRACE("(%p, %p):\n", hIMC, lplf);
748 rc = ImmGetCompositionFontW(hIMC,&lfW);
749 if (rc)
751 memcpy(lplf,&lfW,sizeof(LOGFONTA));
752 WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName,
753 LF_FACESIZE, NULL, NULL);
755 return rc;
758 /***********************************************************************
759 * ImmGetCompositionFontW (IMM32.@)
761 BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
763 InputContextData *data = (InputContextData*)hIMC;
765 TRACE("(%p, %p):\n", hIMC, lplf);
767 if (!data)
768 return FALSE;
770 *lplf = data->IMC.lfFont.W;
772 return TRUE;
775 /***********************************************************************
776 * ImmGetCompositionStringA (IMM32.@)
778 LONG WINAPI ImmGetCompositionStringA(
779 HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
781 CHAR *buf;
782 LONG rc = 0;
783 InputContextData *data = (InputContextData*)hIMC;
784 LPCOMPOSITIONSTRING compstr;
785 LPBYTE compdata;
787 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
789 if (!data)
790 return FALSE;
792 if (!data->IMC.hCompStr)
793 return FALSE;
795 compdata = ImmLockIMCC(data->IMC.hCompStr);
796 compstr = (LPCOMPOSITIONSTRING)compdata;
798 if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
799 compstr->dwResultStrOffset > 0)
801 LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
803 TRACE("GSC_RESULTSTR %p %i\n",ResultStr,
804 compstr->dwResultStrLen);
806 buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwResultStrLen * 3 );
807 rc = WideCharToMultiByte(CP_ACP, 0, ResultStr,
808 compstr->dwResultStrLen , buf,
809 compstr->dwResultStrLen * 3, NULL, NULL);
810 if (dwBufLen >= rc)
811 memcpy(lpBuf,buf,rc);
813 HeapFree( GetProcessHeap(), 0, buf );
815 else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
816 compstr->dwCompStrOffset > 0)
818 LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
820 TRACE("GSC_COMPSTR %p %i\n", CompString, compstr->dwCompStrLen);
822 buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwCompStrLen * 3 );
823 rc = WideCharToMultiByte(CP_ACP, 0, CompString,
824 compstr->dwCompStrLen, buf,
825 compstr->dwCompStrLen * 3, NULL, NULL);
826 if (dwBufLen >= rc)
827 memcpy(lpBuf,buf,rc);
828 HeapFree( GetProcessHeap(), 0, buf );
830 else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
831 compstr->dwCompAttrOffset > 0)
833 LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
834 TRACE("GSC_COMPATTR %p %i\n", Compattr , compstr->dwCompAttrLen);
836 rc = compstr->dwCompAttrLen;
837 if (dwBufLen >= rc)
838 memcpy(lpBuf,Compattr,rc);
840 else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
841 compstr->dwCompClauseOffset > 0)
843 LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
844 TRACE("GSC_COMPCLAUSE %p %i\n", Compclause, compstr->dwCompClauseLen);
846 rc = compstr->dwCompClauseLen;
847 if (dwBufLen >= compstr->dwCompClauseLen)
848 memcpy(lpBuf,Compclause,rc);
850 else if (dwIndex == GCS_RESULTCLAUSE && compstr->dwResultClauseLen > 0 &&
851 compstr->dwResultClauseOffset > 0)
853 LPWSTR Resultclause = (LPWSTR)(compdata + compstr->dwResultClauseOffset);
854 TRACE("GSC_RESULTCLAUSE %p %i\n", Resultclause, compstr->dwResultClauseLen);
856 rc = compstr->dwResultClauseLen;
857 if (dwBufLen >= compstr->dwResultClauseLen)
858 memcpy(lpBuf,Resultclause,rc);
860 else if (dwIndex == GCS_CURSORPOS)
862 TRACE("GSC_CURSORPOS\n");
863 rc = compstr->dwCursorPos;
865 else if (dwIndex == GCS_DELTASTART)
867 TRACE("GCS_DELTASTART\n");
868 rc = compstr->dwDeltaStart;
870 else
872 FIXME("Unhandled index 0x%x\n",dwIndex);
875 ImmUnlockIMCC(data->IMC.hCompStr);
877 return rc;
880 /***********************************************************************
881 * ImmGetCompositionStringW (IMM32.@)
883 LONG WINAPI ImmGetCompositionStringW(
884 HIMC hIMC, DWORD dwIndex,
885 LPVOID lpBuf, DWORD dwBufLen)
887 LONG rc = 0;
888 InputContextData *data = (InputContextData*)hIMC;
889 LPCOMPOSITIONSTRING compstr;
890 LPBYTE compdata;
892 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
894 if (!data)
895 return FALSE;
897 if (!data->IMC.hCompStr)
898 return FALSE;
900 compdata = ImmLockIMCC(data->IMC.hCompStr);
901 compstr = (LPCOMPOSITIONSTRING)compdata;
903 if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
904 compstr->dwResultStrOffset > 0)
906 LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
907 rc = compstr->dwResultStrLen * sizeof(WCHAR);
909 if (dwBufLen >= rc)
910 memcpy(lpBuf,ResultStr,rc);
912 else if (dwIndex == GCS_RESULTREADSTR && compstr->dwResultReadStrLen > 0 &&
913 compstr->dwResultReadStrOffset > 0)
915 LPWSTR ResultReadString = (LPWSTR)(compdata + compstr->dwResultReadStrOffset);
917 rc = compstr->dwResultReadStrLen * sizeof(WCHAR);
918 if (dwBufLen >= rc)
919 memcpy(lpBuf,ResultReadString,rc);
921 else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
922 compstr->dwCompStrOffset > 0)
924 LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
925 rc = compstr->dwCompStrLen * sizeof(WCHAR);
926 if (dwBufLen >= rc)
927 memcpy(lpBuf,CompString,rc);
929 else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
930 compstr->dwCompAttrOffset > 0)
933 LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
935 rc = compstr->dwCompAttrLen;
936 if (dwBufLen >= rc)
937 memcpy(lpBuf,Compattr,rc);
939 else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
940 compstr->dwCompClauseOffset > 0)
942 LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
944 rc = compstr->dwCompClauseLen;
945 if (dwBufLen >= compstr->dwCompClauseLen)
946 memcpy(lpBuf,Compclause,rc);
948 else if (dwIndex == GCS_COMPREADSTR && compstr->dwCompReadStrLen > 0 &&
949 compstr->dwCompReadStrOffset > 0)
951 LPWSTR CompReadString = (LPWSTR)(compdata + compstr->dwCompReadStrOffset);
953 rc = compstr->dwCompReadStrLen * sizeof(WCHAR);
955 if (dwBufLen >= rc)
956 memcpy(lpBuf,CompReadString,rc);
958 else if (dwIndex == GCS_CURSORPOS)
960 TRACE("GSC_CURSORPOS\n");
961 rc = compstr->dwCursorPos;
963 else if (dwIndex == GCS_DELTASTART)
965 TRACE("GCS_DELTASTART\n");
966 rc = compstr->dwDeltaStart;
968 else
970 FIXME("Unhandled index 0x%x\n",dwIndex);
973 ImmUnlockIMCC(data->IMC.hCompStr);
975 return rc;
978 /***********************************************************************
979 * ImmGetCompositionWindow (IMM32.@)
981 BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
983 InputContextData *data = (InputContextData*)hIMC;
985 TRACE("(%p, %p)\n", hIMC, lpCompForm);
987 if (!data)
988 return FALSE;
990 *lpCompForm = data->IMC.cfCompForm;
991 return 1;
994 /***********************************************************************
995 * ImmGetContext (IMM32.@)
998 HIMC WINAPI ImmGetContext(HWND hWnd)
1000 HIMC rc = NULL;
1002 TRACE("%p\n", hWnd);
1003 if (!IMM_GetThreadData()->defaultContext)
1004 IMM_GetThreadData()->defaultContext = ImmCreateContext();
1006 rc = (HIMC)GetPropW(hWnd,szwWineIMCProperty);
1007 if (rc == (HIMC)-1)
1008 rc = NULL;
1009 else if (rc == NULL)
1010 rc = IMM_GetThreadData()->defaultContext;
1012 if (rc)
1014 InputContextData *data = (InputContextData*)rc;
1015 data->IMC.hWnd = hWnd;
1017 TRACE("returning %p\n", rc);
1019 return rc;
1022 /***********************************************************************
1023 * ImmGetConversionListA (IMM32.@)
1025 DWORD WINAPI ImmGetConversionListA(
1026 HKL hKL, HIMC hIMC,
1027 LPCSTR pSrc, LPCANDIDATELIST lpDst,
1028 DWORD dwBufLen, UINT uFlag)
1030 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1031 TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_a(pSrc), lpDst,
1032 dwBufLen, uFlag);
1033 if (immHkl->hIME && immHkl->pImeConversionList)
1035 if (!is_kbd_ime_unicode(immHkl))
1036 return immHkl->pImeConversionList(hIMC,(LPCWSTR)pSrc,lpDst,dwBufLen,uFlag);
1037 else
1039 FIXME("A procedure called with W ime back end\n");
1040 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1041 return 0;
1044 else
1045 return 0;
1048 /***********************************************************************
1049 * ImmGetConversionListW (IMM32.@)
1051 DWORD WINAPI ImmGetConversionListW(
1052 HKL hKL, HIMC hIMC,
1053 LPCWSTR pSrc, LPCANDIDATELIST lpDst,
1054 DWORD dwBufLen, UINT uFlag)
1056 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1057 TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_w(pSrc), lpDst,
1058 dwBufLen, uFlag);
1059 if (immHkl->hIME && immHkl->pImeConversionList)
1061 if (is_kbd_ime_unicode(immHkl))
1062 return immHkl->pImeConversionList(hIMC,pSrc,lpDst,dwBufLen,uFlag);
1063 else
1065 FIXME("W procedure called with A ime back end\n");
1066 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1067 return 0;
1070 else
1071 return 0;
1074 /***********************************************************************
1075 * ImmGetConversionStatus (IMM32.@)
1077 BOOL WINAPI ImmGetConversionStatus(
1078 HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
1080 TRACE("(%p, %p, %p): best guess\n", hIMC, lpfdwConversion, lpfdwSentence);
1081 if (lpfdwConversion)
1082 *lpfdwConversion = IME_CMODE_NATIVE;
1083 if (lpfdwSentence)
1084 *lpfdwSentence = IME_SMODE_NONE;
1085 return TRUE;
1088 /***********************************************************************
1089 * ImmGetDefaultIMEWnd (IMM32.@)
1091 HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
1093 TRACE("Default is %x\n",(unsigned)IMM_GetThreadData()->hwndDefault);
1094 return IMM_GetThreadData()->hwndDefault;
1097 /***********************************************************************
1098 * ImmGetDescriptionA (IMM32.@)
1100 UINT WINAPI ImmGetDescriptionA(
1101 HKL hKL, LPSTR lpszDescription, UINT uBufLen)
1103 WCHAR *buf;
1104 DWORD len;
1106 TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
1108 /* find out how many characters in the unicode buffer */
1109 len = ImmGetDescriptionW( hKL, NULL, 0 );
1111 /* allocate a buffer of that size */
1112 buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
1113 if( !buf )
1114 return 0;
1116 /* fetch the unicode buffer */
1117 len = ImmGetDescriptionW( hKL, buf, len + 1 );
1119 /* convert it back to ASCII */
1120 len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
1121 lpszDescription, uBufLen, NULL, NULL );
1123 HeapFree( GetProcessHeap(), 0, buf );
1125 return len;
1128 /***********************************************************************
1129 * ImmGetDescriptionW (IMM32.@)
1131 UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
1133 static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
1135 FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
1137 if (!uBufLen) return lstrlenW( name );
1138 lstrcpynW( lpszDescription, name, uBufLen );
1139 return lstrlenW( lpszDescription );
1142 /***********************************************************************
1143 * ImmGetGuideLineA (IMM32.@)
1145 DWORD WINAPI ImmGetGuideLineA(
1146 HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
1148 FIXME("(%p, %d, %s, %d): stub\n",
1149 hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
1151 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1152 return 0;
1155 /***********************************************************************
1156 * ImmGetGuideLineW (IMM32.@)
1158 DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
1160 FIXME("(%p, %d, %s, %d): stub\n",
1161 hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
1163 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1164 return 0;
1167 /***********************************************************************
1168 * ImmGetIMEFileNameA (IMM32.@)
1170 UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen)
1172 LPWSTR bufW = NULL;
1173 UINT wBufLen = uBufLen;
1174 UINT rc;
1176 if (uBufLen && lpszFileName)
1177 bufW = HeapAlloc(GetProcessHeap(),0,uBufLen * sizeof(WCHAR));
1178 else /* We need this to get the number of byte required */
1180 bufW = HeapAlloc(GetProcessHeap(),0,MAX_PATH * sizeof(WCHAR));
1181 wBufLen = MAX_PATH;
1184 rc = ImmGetIMEFileNameW(hKL,bufW,wBufLen);
1186 if (rc > 0)
1188 if (uBufLen && lpszFileName)
1189 rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, lpszFileName,
1190 uBufLen, NULL, NULL);
1191 else /* get the length */
1192 rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL,
1193 NULL);
1196 HeapFree(GetProcessHeap(),0,bufW);
1197 return rc;
1200 /***********************************************************************
1201 * ImmGetIMEFileNameW (IMM32.@)
1203 UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
1205 static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
1206 static const WCHAR fmt[] = {'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','s','\\','%','0','8','x',0};
1208 HKEY hkey;
1209 DWORD length;
1210 DWORD rc;
1211 WCHAR regKey[sizeof(fmt)/sizeof(WCHAR)+8];
1213 wsprintfW( regKey, fmt, (unsigned)hKL );
1214 rc = RegOpenKeyW( HKEY_LOCAL_MACHINE, regKey, &hkey);
1215 if (rc != ERROR_SUCCESS)
1217 SetLastError(rc);
1218 return 0;
1221 length = 0;
1222 rc = RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, NULL, &length);
1224 if (rc != ERROR_SUCCESS)
1226 RegCloseKey(hkey);
1227 SetLastError(rc);
1228 return 0;
1230 if (length > uBufLen * sizeof(WCHAR) || !lpszFileName)
1232 RegCloseKey(hkey);
1233 if (lpszFileName)
1235 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1236 return 0;
1238 else
1239 return length / sizeof(WCHAR);
1242 RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, lpszFileName, &length);
1244 RegCloseKey(hkey);
1246 return length / sizeof(WCHAR);
1249 /***********************************************************************
1250 * ImmGetOpenStatus (IMM32.@)
1252 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
1254 InputContextData *data = (InputContextData*)hIMC;
1256 if (!data)
1257 return FALSE;
1258 FIXME("(%p): semi-stub\n", hIMC);
1260 return data->IMC.fOpen;
1263 /***********************************************************************
1264 * ImmGetProperty (IMM32.@)
1266 DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
1268 DWORD rc = 0;
1269 ImmHkl *kbd;
1271 TRACE("(%p, %d)\n", hKL, fdwIndex);
1272 kbd = IMM_GetImmHkl(hKL);
1274 if (kbd && kbd->hIME)
1276 switch (fdwIndex)
1278 case IGP_PROPERTY: rc = kbd->imeInfo.fdwProperty; break;
1279 case IGP_CONVERSION: rc = kbd->imeInfo.fdwConversionCaps; break;
1280 case IGP_SENTENCE: rc = kbd->imeInfo.fdwSentenceCaps; break;
1281 case IGP_SETCOMPSTR: rc = kbd->imeInfo.fdwSCSCaps; break;
1282 case IGP_SELECT: rc = kbd->imeInfo.fdwSelectCaps; break;
1283 case IGP_GETIMEVERSION: rc = IMEVER_0400; break;
1284 case IGP_UI: rc = 0; break;
1285 default: rc = 0;
1288 return rc;
1291 /***********************************************************************
1292 * ImmGetRegisterWordStyleA (IMM32.@)
1294 UINT WINAPI ImmGetRegisterWordStyleA(
1295 HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
1297 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1298 TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
1299 if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
1301 if (!is_kbd_ime_unicode(immHkl))
1302 return immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)lpStyleBuf);
1303 else
1305 STYLEBUFW sbw;
1306 UINT rc;
1308 rc = immHkl->pImeGetRegisterWordStyle(nItem,&sbw);
1309 WideCharToMultiByte(CP_ACP, 0, sbw.szDescription, -1,
1310 lpStyleBuf->szDescription, 32, NULL, NULL);
1311 lpStyleBuf->dwStyle = sbw.dwStyle;
1312 return rc;
1315 else
1316 return 0;
1319 /***********************************************************************
1320 * ImmGetRegisterWordStyleW (IMM32.@)
1322 UINT WINAPI ImmGetRegisterWordStyleW(
1323 HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
1325 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1326 TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
1327 if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
1329 if (is_kbd_ime_unicode(immHkl))
1330 return immHkl->pImeGetRegisterWordStyle(nItem,lpStyleBuf);
1331 else
1333 STYLEBUFA sba;
1334 UINT rc;
1336 rc = immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)&sba);
1337 MultiByteToWideChar(CP_ACP, 0, sba.szDescription, -1,
1338 lpStyleBuf->szDescription, 32);
1339 lpStyleBuf->dwStyle = sba.dwStyle;
1340 return rc;
1343 else
1344 return 0;
1347 /***********************************************************************
1348 * ImmGetStatusWindowPos (IMM32.@)
1350 BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1352 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1353 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1354 return FALSE;
1357 /***********************************************************************
1358 * ImmGetVirtualKey (IMM32.@)
1360 UINT WINAPI ImmGetVirtualKey(HWND hWnd)
1362 OSVERSIONINFOA version;
1363 FIXME("(%p): stub\n", hWnd);
1364 GetVersionExA( &version );
1365 switch(version.dwPlatformId)
1367 case VER_PLATFORM_WIN32_WINDOWS:
1368 return VK_PROCESSKEY;
1369 case VER_PLATFORM_WIN32_NT:
1370 return 0;
1371 default:
1372 FIXME("%d not supported\n",version.dwPlatformId);
1373 return VK_PROCESSKEY;
1377 /***********************************************************************
1378 * ImmInstallIMEA (IMM32.@)
1380 HKL WINAPI ImmInstallIMEA(
1381 LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
1383 FIXME("(%s, %s): stub\n",
1384 debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
1386 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1387 return NULL;
1390 /***********************************************************************
1391 * ImmInstallIMEW (IMM32.@)
1393 HKL WINAPI ImmInstallIMEW(
1394 LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
1396 FIXME("(%s, %s): stub\n",
1397 debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
1399 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1400 return NULL;
1403 /***********************************************************************
1404 * ImmIsIME (IMM32.@)
1406 BOOL WINAPI ImmIsIME(HKL hKL)
1408 ImmHkl *ptr;
1409 TRACE("(%p):\n", hKL);
1410 ptr = IMM_GetImmHkl(hKL);
1411 return (ptr && ptr->hIME);
1414 /***********************************************************************
1415 * ImmIsUIMessageA (IMM32.@)
1417 BOOL WINAPI ImmIsUIMessageA(
1418 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1420 BOOL rc = FALSE;
1422 TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
1423 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1424 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1425 (msg == WM_MSIME_SERVICE) ||
1426 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1427 (msg == WM_MSIME_MOUSE) ||
1428 (msg == WM_MSIME_RECONVERTREQUEST) ||
1429 (msg == WM_MSIME_RECONVERT) ||
1430 (msg == WM_MSIME_QUERYPOSITION) ||
1431 (msg == WM_MSIME_DOCUMENTFEED))
1434 if (!IMM_GetThreadData()->hwndDefault)
1435 ImmGetDefaultIMEWnd(NULL);
1437 if (hWndIME == NULL)
1438 PostMessageA(IMM_GetThreadData()->hwndDefault, msg, wParam, lParam);
1440 rc = TRUE;
1442 return rc;
1445 /***********************************************************************
1446 * ImmIsUIMessageW (IMM32.@)
1448 BOOL WINAPI ImmIsUIMessageW(
1449 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1451 BOOL rc = FALSE;
1452 TRACE("(%p, %d, %ld, %ld):\n", hWndIME, msg, wParam, lParam);
1453 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1454 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1455 (msg == WM_MSIME_SERVICE) ||
1456 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1457 (msg == WM_MSIME_MOUSE) ||
1458 (msg == WM_MSIME_RECONVERTREQUEST) ||
1459 (msg == WM_MSIME_RECONVERT) ||
1460 (msg == WM_MSIME_QUERYPOSITION) ||
1461 (msg == WM_MSIME_DOCUMENTFEED))
1462 rc = TRUE;
1463 return rc;
1466 /***********************************************************************
1467 * ImmNotifyIME (IMM32.@)
1469 BOOL WINAPI ImmNotifyIME(
1470 HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
1472 InputContextData *data = (InputContextData*)hIMC;
1474 TRACE("(%p, %d, %d, %d)\n",
1475 hIMC, dwAction, dwIndex, dwValue);
1477 if (!data || ! data->immKbd->pNotifyIME)
1478 return FALSE;
1480 return data->immKbd->pNotifyIME(hIMC,dwAction,dwIndex,dwValue);
1483 /***********************************************************************
1484 * ImmRegisterWordA (IMM32.@)
1486 BOOL WINAPI ImmRegisterWordA(
1487 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
1489 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1490 TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
1491 debugstr_a(lpszRegister));
1492 if (immHkl->hIME && immHkl->pImeRegisterWord)
1494 if (!is_kbd_ime_unicode(immHkl))
1495 return immHkl->pImeRegisterWord((LPCWSTR)lpszReading,dwStyle,
1496 (LPCWSTR)lpszRegister);
1497 else
1499 LPWSTR lpszwReading = strdupAtoW(lpszReading);
1500 LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
1501 BOOL rc;
1503 rc = immHkl->pImeRegisterWord(lpszwReading,dwStyle,lpszwRegister);
1504 HeapFree(GetProcessHeap(),0,lpszwReading);
1505 HeapFree(GetProcessHeap(),0,lpszwRegister);
1506 return rc;
1509 else
1510 return FALSE;
1513 /***********************************************************************
1514 * ImmRegisterWordW (IMM32.@)
1516 BOOL WINAPI ImmRegisterWordW(
1517 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
1519 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1520 TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
1521 debugstr_w(lpszRegister));
1522 if (immHkl->hIME && immHkl->pImeRegisterWord)
1524 if (is_kbd_ime_unicode(immHkl))
1525 return immHkl->pImeRegisterWord(lpszReading,dwStyle,lpszRegister);
1526 else
1528 LPSTR lpszaReading = strdupWtoA(lpszReading);
1529 LPSTR lpszaRegister = strdupWtoA(lpszRegister);
1530 BOOL rc;
1532 rc = immHkl->pImeRegisterWord((LPCWSTR)lpszaReading,dwStyle,
1533 (LPCWSTR)lpszaRegister);
1534 HeapFree(GetProcessHeap(),0,lpszaReading);
1535 HeapFree(GetProcessHeap(),0,lpszaRegister);
1536 return rc;
1539 else
1540 return FALSE;
1543 /***********************************************************************
1544 * ImmReleaseContext (IMM32.@)
1546 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1548 static int shown = 0;
1550 if (!shown) {
1551 FIXME("(%p, %p): stub\n", hWnd, hIMC);
1552 shown = 1;
1554 return TRUE;
1557 /***********************************************************************
1558 * ImmSetCandidateWindow (IMM32.@)
1560 BOOL WINAPI ImmSetCandidateWindow(
1561 HIMC hIMC, LPCANDIDATEFORM lpCandidate)
1563 FIXME("(%p, %p): stub\n", hIMC, lpCandidate);
1564 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1565 return FALSE;
1568 /***********************************************************************
1569 * ImmSetCompositionFontA (IMM32.@)
1571 BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
1573 InputContextData *data = (InputContextData*)hIMC;
1574 TRACE("(%p, %p)\n", hIMC, lplf);
1576 if (!data)
1577 return FALSE;
1579 memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
1580 MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
1581 LF_FACESIZE);
1582 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
1584 return TRUE;
1587 /***********************************************************************
1588 * ImmSetCompositionFontW (IMM32.@)
1590 BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
1592 InputContextData *data = (InputContextData*)hIMC;
1593 TRACE("(%p, %p)\n", hIMC, lplf);
1595 if (!data)
1596 return FALSE;
1598 data->IMC.lfFont.W = *lplf;
1599 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
1601 return TRUE;
1604 /***********************************************************************
1605 * ImmSetCompositionStringA (IMM32.@)
1607 BOOL WINAPI ImmSetCompositionStringA(
1608 HIMC hIMC, DWORD dwIndex,
1609 LPCVOID lpComp, DWORD dwCompLen,
1610 LPCVOID lpRead, DWORD dwReadLen)
1612 DWORD comp_len;
1613 DWORD read_len;
1614 WCHAR *CompBuffer = NULL;
1615 WCHAR *ReadBuffer = NULL;
1616 BOOL rc;
1617 InputContextData *data = (InputContextData*)hIMC;
1619 TRACE("(%p, %d, %p, %d, %p, %d):\n",
1620 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1622 if (!data)
1623 return FALSE;
1625 if (!is_himc_ime_unicode(data))
1626 return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
1627 dwCompLen, lpRead, dwReadLen);
1629 comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
1630 if (comp_len)
1632 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
1633 MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
1636 read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
1637 if (read_len)
1639 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
1640 MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
1643 rc = ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
1644 ReadBuffer, read_len);
1646 HeapFree(GetProcessHeap(), 0, CompBuffer);
1647 HeapFree(GetProcessHeap(), 0, ReadBuffer);
1649 return rc;
1652 /***********************************************************************
1653 * ImmSetCompositionStringW (IMM32.@)
1655 BOOL WINAPI ImmSetCompositionStringW(
1656 HIMC hIMC, DWORD dwIndex,
1657 LPCVOID lpComp, DWORD dwCompLen,
1658 LPCVOID lpRead, DWORD dwReadLen)
1660 DWORD comp_len;
1661 DWORD read_len;
1662 CHAR *CompBuffer = NULL;
1663 CHAR *ReadBuffer = NULL;
1664 BOOL rc;
1665 InputContextData *data = (InputContextData*)hIMC;
1667 TRACE("(%p, %d, %p, %d, %p, %d):\n",
1668 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1670 if (!data)
1671 return FALSE;
1673 if (is_himc_ime_unicode(data))
1674 return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
1675 dwCompLen, lpRead, dwReadLen);
1677 comp_len = WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, NULL, 0, NULL,
1678 NULL);
1679 if (comp_len)
1681 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len);
1682 WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len,
1683 NULL, NULL);
1686 read_len = WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, NULL, 0, NULL,
1687 NULL);
1688 if (read_len)
1690 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len);
1691 WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len,
1692 NULL, NULL);
1695 rc = ImmSetCompositionStringA(hIMC, dwIndex, CompBuffer, comp_len,
1696 ReadBuffer, read_len);
1698 HeapFree(GetProcessHeap(), 0, CompBuffer);
1699 HeapFree(GetProcessHeap(), 0, ReadBuffer);
1701 return rc;
1704 /***********************************************************************
1705 * ImmSetCompositionWindow (IMM32.@)
1707 BOOL WINAPI ImmSetCompositionWindow(
1708 HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1710 BOOL reshow = FALSE;
1711 InputContextData *data = (InputContextData*)hIMC;
1713 TRACE("(%p, %p)\n", hIMC, lpCompForm);
1714 TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm->dwStyle,
1715 lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
1716 lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
1718 if (!data)
1719 return FALSE;
1721 data->IMC.cfCompForm = *lpCompForm;
1723 if (IsWindowVisible(IMM_GetThreadData()->hwndDefault))
1725 reshow = TRUE;
1726 ShowWindow(IMM_GetThreadData()->hwndDefault,SW_HIDE);
1729 /* FIXME: this is a partial stub */
1731 if (reshow)
1732 ShowWindow(IMM_GetThreadData()->hwndDefault,SW_SHOWNOACTIVATE);
1734 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
1735 return TRUE;
1738 /***********************************************************************
1739 * ImmSetConversionStatus (IMM32.@)
1741 BOOL WINAPI ImmSetConversionStatus(
1742 HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
1744 static int shown = 0;
1746 if (!shown) {
1747 FIXME("(%p, %d, %d): stub\n",
1748 hIMC, fdwConversion, fdwSentence
1750 shown = 1;
1752 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1753 return FALSE;
1756 /***********************************************************************
1757 * ImmSetOpenStatus (IMM32.@)
1759 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
1761 InputContextData *data = (InputContextData*)hIMC;
1763 TRACE("%p %d\n", hIMC, fOpen);
1765 if (!data)
1766 return FALSE;
1768 if (data->imeWnd == NULL)
1770 /* create the ime window */
1771 data->imeWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
1772 data->immKbd->imeClassName,
1773 NULL, WS_POPUP, 0, 0, 1, 1, 0, 0, hImeInst, 0);
1774 SetWindowLongW(data->imeWnd, IMMGWL_IMC, (LONG)data);
1775 IMM_GetThreadData()->hwndDefault = data->imeWnd;
1778 data->IMC.fOpen = fOpen;
1779 return ImmNotifyIME(hIMC,NI_CONTEXTUPDATED,0,IMC_SETOPENSTATUS);
1782 /***********************************************************************
1783 * ImmSetStatusWindowPos (IMM32.@)
1785 BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1787 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1788 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1789 return FALSE;
1792 /***********************************************************************
1793 * ImmSimulateHotKey (IMM32.@)
1795 BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
1797 FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
1798 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1799 return FALSE;
1802 /***********************************************************************
1803 * ImmUnregisterWordA (IMM32.@)
1805 BOOL WINAPI ImmUnregisterWordA(
1806 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
1808 FIXME("(%p, %s, %d, %s): stub\n",
1809 hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
1811 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1812 return FALSE;
1815 /***********************************************************************
1816 * ImmUnregisterWordW (IMM32.@)
1818 BOOL WINAPI ImmUnregisterWordW(
1819 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
1821 FIXME("(%p, %s, %d, %s): stub\n",
1822 hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
1824 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1825 return FALSE;
1828 /***********************************************************************
1829 * ImmGetImeMenuItemsA (IMM32.@)
1831 DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
1832 LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
1833 DWORD dwSize)
1835 InputContextData *data = (InputContextData*)hIMC;
1836 TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
1837 lpImeParentMenu, lpImeMenu, dwSize);
1838 if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
1840 if (!is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
1841 return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
1842 (IMEMENUITEMINFOW*)lpImeParentMenu,
1843 (IMEMENUITEMINFOW*)lpImeMenu, dwSize);
1844 else
1846 IMEMENUITEMINFOW lpImeParentMenuW;
1847 IMEMENUITEMINFOW *lpImeMenuW, *parent = NULL;
1848 DWORD rc;
1850 if (lpImeParentMenu)
1851 parent = &lpImeParentMenuW;
1852 if (lpImeMenu)
1854 int count = dwSize / sizeof(LPIMEMENUITEMINFOA);
1855 dwSize = count * sizeof(IMEMENUITEMINFOW);
1856 lpImeMenuW = HeapAlloc(GetProcessHeap(), 0, dwSize);
1858 else
1859 lpImeMenuW = NULL;
1861 rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
1862 parent, lpImeMenuW, dwSize);
1864 if (lpImeParentMenu)
1866 memcpy(lpImeParentMenu,&lpImeParentMenuW,sizeof(IMEMENUITEMINFOA));
1867 lpImeParentMenu->hbmpItem = lpImeParentMenuW.hbmpItem;
1868 WideCharToMultiByte(CP_ACP, 0, lpImeParentMenuW.szString,
1869 -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE,
1870 NULL, NULL);
1872 if (lpImeMenu && rc)
1874 int i;
1875 for (i = 0; i < rc; i++)
1877 memcpy(&lpImeMenu[i],&lpImeMenuW[1],sizeof(IMEMENUITEMINFOA));
1878 lpImeMenu[i].hbmpItem = lpImeMenuW[i].hbmpItem;
1879 WideCharToMultiByte(CP_ACP, 0, lpImeMenuW[i].szString,
1880 -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE,
1881 NULL, NULL);
1884 HeapFree(GetProcessHeap(),0,lpImeMenuW);
1885 return rc;
1888 else
1889 return 0;
1892 /***********************************************************************
1893 * ImmGetImeMenuItemsW (IMM32.@)
1895 DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
1896 LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
1897 DWORD dwSize)
1899 InputContextData *data = (InputContextData*)hIMC;
1900 TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
1901 lpImeParentMenu, lpImeMenu, dwSize);
1902 if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
1904 if (is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
1905 return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
1906 lpImeParentMenu, lpImeMenu, dwSize);
1907 else
1909 IMEMENUITEMINFOA lpImeParentMenuA;
1910 IMEMENUITEMINFOA *lpImeMenuA, *parent = NULL;
1911 DWORD rc;
1913 if (lpImeParentMenu)
1914 parent = &lpImeParentMenuA;
1915 if (lpImeMenu)
1917 int count = dwSize / sizeof(LPIMEMENUITEMINFOW);
1918 dwSize = count * sizeof(IMEMENUITEMINFOA);
1919 lpImeMenuA = HeapAlloc(GetProcessHeap(), 0, dwSize);
1921 else
1922 lpImeMenuA = NULL;
1924 rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
1925 (IMEMENUITEMINFOW*)parent,
1926 (IMEMENUITEMINFOW*)lpImeMenuA, dwSize);
1928 if (lpImeParentMenu)
1930 memcpy(lpImeParentMenu,&lpImeParentMenuA,sizeof(IMEMENUITEMINFOA));
1931 lpImeParentMenu->hbmpItem = lpImeParentMenuA.hbmpItem;
1932 MultiByteToWideChar(CP_ACP, 0, lpImeParentMenuA.szString,
1933 -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE);
1935 if (lpImeMenu && rc)
1937 int i;
1938 for (i = 0; i < rc; i++)
1940 memcpy(&lpImeMenu[i],&lpImeMenuA[1],sizeof(IMEMENUITEMINFOA));
1941 lpImeMenu[i].hbmpItem = lpImeMenuA[i].hbmpItem;
1942 MultiByteToWideChar(CP_ACP, 0, lpImeMenuA[i].szString,
1943 -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE);
1946 HeapFree(GetProcessHeap(),0,lpImeMenuA);
1947 return rc;
1950 else
1951 return 0;
1954 /***********************************************************************
1955 * ImmLockIMC(IMM32.@)
1957 LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
1959 InputContextData *data = (InputContextData*)hIMC;
1961 if (!data)
1962 return NULL;
1963 data->dwLock++;
1964 return &data->IMC;
1967 /***********************************************************************
1968 * ImmUnlockIMC(IMM32.@)
1970 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
1972 InputContextData *data = (InputContextData*)hIMC;
1973 data->dwLock--;
1974 return (data->dwLock!=0);
1977 /***********************************************************************
1978 * ImmGetIMCLockCount(IMM32.@)
1980 DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
1982 InputContextData *data = (InputContextData*)hIMC;
1983 return data->dwLock;
1986 /***********************************************************************
1987 * ImmCreateIMCC(IMM32.@)
1989 HIMCC WINAPI ImmCreateIMCC(DWORD size)
1991 IMCCInternal *internal;
1992 int real_size = size + sizeof(IMCCInternal);
1994 internal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, real_size);
1995 if (internal == NULL)
1996 return NULL;
1998 internal->dwSize = size;
1999 return (HIMCC)internal;
2002 /***********************************************************************
2003 * ImmDestroyIMCC(IMM32.@)
2005 HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
2007 HeapFree(GetProcessHeap(),0,block);
2008 return NULL;
2011 /***********************************************************************
2012 * ImmLockIMCC(IMM32.@)
2014 LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
2016 IMCCInternal *internal;
2017 internal = (IMCCInternal*) imcc;
2019 internal->dwLock ++;
2020 return internal + 1;
2023 /***********************************************************************
2024 * ImmUnlockIMCC(IMM32.@)
2026 BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
2028 IMCCInternal *internal;
2029 internal = (IMCCInternal*) imcc;
2031 internal->dwLock --;
2032 return (internal->dwLock!=0);
2035 /***********************************************************************
2036 * ImmGetIMCCLockCount(IMM32.@)
2038 DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
2040 IMCCInternal *internal;
2041 internal = (IMCCInternal*) imcc;
2043 return internal->dwLock;
2046 /***********************************************************************
2047 * ImmReSizeIMCC(IMM32.@)
2049 HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
2051 IMCCInternal *internal,*newone;
2052 int real_size = size + sizeof(IMCCInternal);
2054 internal = (IMCCInternal*) imcc;
2056 newone = HeapReAlloc(GetProcessHeap(), 0, internal, real_size);
2057 newone->dwSize = size;
2059 return newone;
2062 /***********************************************************************
2063 * ImmGetIMCCSize(IMM32.@)
2065 DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
2067 IMCCInternal *internal;
2068 internal = (IMCCInternal*) imcc;
2070 return internal->dwSize;
2073 /***********************************************************************
2074 * ImmGenerateMessage(IMM32.@)
2076 BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
2078 InputContextData *data = (InputContextData*)hIMC;
2080 TRACE("%i messages queued\n",data->IMC.dwNumMsgBuf);
2081 if (data->IMC.dwNumMsgBuf > 0)
2083 LPTRANSMSG lpTransMsg;
2084 INT i;
2086 lpTransMsg = (LPTRANSMSG)ImmLockIMCC(data->IMC.hMsgBuf);
2087 for (i = 0; i < data->IMC.dwNumMsgBuf; i++)
2088 ImmInternalPostIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam);
2090 ImmUnlockIMCC(data->IMC.hMsgBuf);
2092 data->IMC.dwNumMsgBuf = 0;
2095 return TRUE;