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
30 #include "wine/debug.h"
35 #include "wine/list.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(imm
);
39 typedef struct tagIMCCInternal
45 #define MAKE_FUNCPTR(f) typeof(f) * p##f
46 typedef struct _tagImmHkl
{
51 WCHAR imeClassName
[17]; /* 16 character max */
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
);
74 typedef struct tagInputContextData
84 typedef struct _tagTRANSMSG
{
88 } TRANSMSG
, *LPTRANSMSG
;
90 typedef struct _tagIMMThreadData
{
95 static DWORD tlsIndex
= 0;
96 static struct list ImmHklList
= LIST_INIT(ImmHklList
);
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
)
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
);
126 static inline CHAR
*strdupWtoA( const WCHAR
*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
);
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
;
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
);
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;
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
)
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
)
206 /* not found... create it */
208 ptr
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ImmHkl
));
211 if (ImmGetIMEFileNameW(hkl
, filename
, MAX_PATH
)) ptr
->hIME
= LoadLibraryW(filename
);
213 ptr
->hIME
= LoadDefaultWineIME();
216 LOAD_FUNCPTR(ImeInquire
);
217 if (!ptr
->pImeInquire
|| !ptr
->pImeInquire(&ptr
->imeInfo
, ptr
->imeClassName
, NULL
))
219 FreeLibrary(ptr
->hIME
);
224 LOAD_FUNCPTR(ImeDestroy
);
225 LOAD_FUNCPTR(ImeSelect
);
226 if (!ptr
->pImeSelect
|| !ptr
->pImeDestroy
)
228 FreeLibrary(ptr
->hIME
);
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
))
250 MultiByteToWideChar(CP_ACP
, 0, (LPSTR
)ptr
->imeClassName
,
252 lstrcpyW(ptr
->imeClassName
, bufW
);
257 list_add_head(&ImmHklList
,&ptr
->entry
);
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
);
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
);
295 case DLL_PROCESS_ATTACH
:
296 IMM_RegisterMessages();
297 tlsIndex
= TlsAlloc();
298 IMM_InitThreadData();
300 case DLL_THREAD_ATTACH
:
301 IMM_InitThreadData();
303 case DLL_THREAD_DETACH
:
304 IMM_FreeThreadData();
306 case DLL_PROCESS_DETACH
:
307 IMM_FreeThreadData();
315 /* for posting messages as the IME */
316 static void ImmInternalPostIMEMessage(InputContextData
*data
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
318 HWND target
= GetFocus();
320 PostMessageW(data
->IMC
.hWnd
,msg
,wParam
,lParam
);
322 PostMessageW(target
, msg
, wParam
, lParam
);
325 static LRESULT
ImmInternalSendIMENotify(InputContextData
*data
, WPARAM notify
, LPARAM lParam
)
329 target
= data
->IMC
.hWnd
;
330 if (!target
) target
= GetFocus();
333 return SendMessageW(target
, WM_IME_NOTIFY
, notify
, lParam
);
338 static HIMCC
ImmCreateBlankCompStr(void)
341 LPCOMPOSITIONSTRING ptr
;
342 rc
= ImmCreateIMCC(sizeof(COMPOSITIONSTRING
));
343 ptr
= (LPCOMPOSITIONSTRING
)ImmLockIMCC(rc
);
344 memset(ptr
,0,sizeof(COMPOSITIONSTRING
));
345 ptr
->dwSize
= sizeof(COMPOSITIONSTRING
);
350 /***********************************************************************
351 * ImmAssociateContext (IMM32.@)
353 HIMC WINAPI
ImmAssociateContext(HWND hWnd
, HIMC hIMC
)
356 InputContextData
*data
= (InputContextData
*)hIMC
;
358 TRACE("(%p, %p):\n", hWnd
, hIMC
);
360 if (!IMM_GetThreadData()->defaultContext
)
361 IMM_GetThreadData()->defaultContext
= ImmCreateContext();
364 * If already associated just return
366 if (hIMC
&& data
->IMC
.hWnd
== hWnd
)
371 old
= (HIMC
)RemovePropW(hWnd
,szwWineIMCProperty
);
374 old
= IMM_GetThreadData()->defaultContext
;
375 else if (old
== (HIMC
)-1)
378 if (hIMC
!= IMM_GetThreadData()->defaultContext
)
380 if (hIMC
== NULL
) /* Meaning disable imm for that window*/
381 SetPropW(hWnd
,szwWineIMCProperty
,(HANDLE
)-1);
383 SetPropW(hWnd
,szwWineIMCProperty
,(HANDLE
)hIMC
);
388 InputContextData
*old_data
= (InputContextData
*)old
;
389 if (old_data
->IMC
.hWnd
== hWnd
)
390 old_data
->IMC
.hWnd
= NULL
;
397 if (IsWindow(data
->IMC
.hWnd
))
400 * Post a message that your context is switching
402 SendMessageW(data
->IMC
.hWnd
, WM_IME_SETCONTEXT
, FALSE
, ISC_SHOWUIALL
);
405 data
->IMC
.hWnd
= hWnd
;
407 if (IsWindow(data
->IMC
.hWnd
))
410 * Post a message that your context is switching
412 SendMessageW(data
->IMC
.hWnd
, WM_IME_SETCONTEXT
, TRUE
, ISC_SHOWUIALL
);
418 /***********************************************************************
419 * ImmAssociateContextEx (IMM32.@)
421 BOOL WINAPI
ImmAssociateContextEx(HWND hWnd
, HIMC hIMC
, DWORD dwFlags
)
423 FIXME("(%p, %p, %d): stub\n", hWnd
, hIMC
, dwFlags
);
424 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
428 /***********************************************************************
429 * ImmConfigureIMEA (IMM32.@)
431 BOOL WINAPI
ImmConfigureIMEA(
432 HKL hKL
, HWND hWnd
, DWORD dwMode
, LPVOID lpData
)
434 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
436 TRACE("(%p, %p, %d, %p):\n", hKL
, hWnd
, dwMode
, lpData
);
438 if (immHkl
->hIME
&& immHkl
->pImeConfigure
)
440 if (dwMode
!= IME_CONFIG_REGISTERWORD
|| !is_kbd_ime_unicode(immHkl
))
441 return immHkl
->pImeConfigure(hKL
,hWnd
,dwMode
,lpData
);
445 REGISTERWORDA
*rwa
= (REGISTERWORDA
*)lpData
;
448 rww
.lpReading
= strdupAtoW(rwa
->lpReading
);
449 rww
.lpWord
= strdupAtoW(rwa
->lpWord
);
450 rc
= immHkl
->pImeConfigure(hKL
,hWnd
,dwMode
,&rww
);
451 HeapFree(GetProcessHeap(),0,rww
.lpReading
);
452 HeapFree(GetProcessHeap(),0,rww
.lpWord
);
460 /***********************************************************************
461 * ImmConfigureIMEW (IMM32.@)
463 BOOL WINAPI
ImmConfigureIMEW(
464 HKL hKL
, HWND hWnd
, DWORD dwMode
, LPVOID lpData
)
466 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
468 TRACE("(%p, %p, %d, %p):\n", hKL
, hWnd
, dwMode
, lpData
);
470 if (immHkl
->hIME
&& immHkl
->pImeConfigure
)
472 if (dwMode
!= IME_CONFIG_REGISTERWORD
|| is_kbd_ime_unicode(immHkl
))
473 return immHkl
->pImeConfigure(hKL
,hWnd
,dwMode
,lpData
);
476 REGISTERWORDW
*rww
= (REGISTERWORDW
*)lpData
;
480 rwa
.lpReading
= strdupWtoA(rww
->lpReading
);
481 rwa
.lpWord
= strdupWtoA(rww
->lpWord
);
482 rc
= immHkl
->pImeConfigure(hKL
,hWnd
,dwMode
,&rwa
);
483 HeapFree(GetProcessHeap(),0,rwa
.lpReading
);
484 HeapFree(GetProcessHeap(),0,rwa
.lpWord
);
492 /***********************************************************************
493 * ImmCreateContext (IMM32.@)
495 HIMC WINAPI
ImmCreateContext(void)
497 InputContextData
*new_context
;
501 new_context
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(InputContextData
));
504 new_context
->immKbd
= IMM_GetImmHkl(GetKeyboardLayout(0));
506 if (!new_context
->immKbd
->hIME
)
508 TRACE("IME dll could not be loaded\n");
509 HeapFree(GetProcessHeap(),0,new_context
);
513 /* the HIMCCs are never NULL */
514 new_context
->IMC
.hCompStr
= ImmCreateBlankCompStr();
515 new_context
->IMC
.hMsgBuf
= ImmCreateIMCC(0);
516 new_context
->IMC
.hCandInfo
= ImmCreateIMCC(sizeof(CANDIDATEINFO
));
517 ci
= ImmLockIMCC(new_context
->IMC
.hCandInfo
);
518 memset(ci
,0,sizeof(CANDIDATEINFO
));
519 ci
->dwSize
= sizeof(CANDIDATEINFO
);
520 ImmUnlockIMCC(new_context
->IMC
.hCandInfo
);
521 new_context
->IMC
.hGuideLine
= ImmCreateIMCC(sizeof(GUIDELINE
));
522 gl
= ImmLockIMCC(new_context
->IMC
.hGuideLine
);
523 memset(gl
,0,sizeof(GUIDELINE
));
524 gl
->dwSize
= sizeof(GUIDELINE
);
525 ImmUnlockIMCC(new_context
->IMC
.hGuideLine
);
527 /* Initialize the IME Private */
528 new_context
->IMC
.hPrivate
= ImmCreateIMCC(new_context
->immKbd
->imeInfo
.dwPrivateDataSize
);
530 if (!new_context
->immKbd
->pImeSelect(new_context
, TRUE
))
532 TRACE("Selection of IME failed\n");
533 IMM_DestroyContext(new_context
);
537 new_context
->immKbd
->uSelected
++;
538 TRACE("Created context 0x%x\n",(UINT
)new_context
);
540 return (HIMC
)new_context
;
543 static BOOL
IMM_DestroyContext(HIMC hIMC
)
545 InputContextData
*data
= (InputContextData
*)hIMC
;
547 TRACE("Destroying %p\n",hIMC
);
551 data
->immKbd
->uSelected
--;
552 data
->immKbd
->pImeSelect(hIMC
, FALSE
);
554 if (IMM_GetThreadData()->hwndDefault
== data
->imeWnd
)
555 IMM_GetThreadData()->hwndDefault
= NULL
;
556 DestroyWindow(data
->imeWnd
);
558 ImmDestroyIMCC(data
->IMC
.hCompStr
);
559 ImmDestroyIMCC(data
->IMC
.hCandInfo
);
560 ImmDestroyIMCC(data
->IMC
.hGuideLine
);
561 ImmDestroyIMCC(data
->IMC
.hPrivate
);
562 ImmDestroyIMCC(data
->IMC
.hMsgBuf
);
564 HeapFree(GetProcessHeap(),0,data
);
569 /***********************************************************************
570 * ImmDestroyContext (IMM32.@)
572 BOOL WINAPI
ImmDestroyContext(HIMC hIMC
)
574 if (hIMC
!= IMM_GetThreadData()->defaultContext
)
575 return IMM_DestroyContext(hIMC
);
580 /***********************************************************************
581 * ImmDisableIME (IMM32.@)
583 BOOL WINAPI
ImmDisableIME(DWORD idThread
)
585 FIXME("(%d): stub\n", idThread
);
589 /***********************************************************************
590 * ImmEnumRegisterWordA (IMM32.@)
592 UINT WINAPI
ImmEnumRegisterWordA(
593 HKL hKL
, REGISTERWORDENUMPROCA lpfnEnumProc
,
594 LPCSTR lpszReading
, DWORD dwStyle
,
595 LPCSTR lpszRegister
, LPVOID lpData
)
597 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
598 TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL
, lpfnEnumProc
,
599 debugstr_a(lpszReading
), dwStyle
, debugstr_a(lpszRegister
), lpData
);
600 if (immHkl
->hIME
&& immHkl
->pImeEnumRegisterWord
)
602 if (!is_kbd_ime_unicode(immHkl
))
603 return immHkl
->pImeEnumRegisterWord((REGISTERWORDENUMPROCW
)lpfnEnumProc
,
604 (LPCWSTR
)lpszReading
, dwStyle
, (LPCWSTR
)lpszRegister
, lpData
);
607 FIXME("A procedure called with W ime back end\n");
608 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
616 /***********************************************************************
617 * ImmEnumRegisterWordW (IMM32.@)
619 UINT WINAPI
ImmEnumRegisterWordW(
620 HKL hKL
, REGISTERWORDENUMPROCW lpfnEnumProc
,
621 LPCWSTR lpszReading
, DWORD dwStyle
,
622 LPCWSTR lpszRegister
, LPVOID lpData
)
624 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
625 TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL
, lpfnEnumProc
,
626 debugstr_w(lpszReading
), dwStyle
, debugstr_w(lpszRegister
), lpData
);
627 if (immHkl
->hIME
&& immHkl
->pImeEnumRegisterWord
)
629 if (is_kbd_ime_unicode(immHkl
))
630 return immHkl
->pImeEnumRegisterWord(lpfnEnumProc
, lpszReading
, dwStyle
,
631 lpszRegister
, lpData
);
634 FIXME("W procedure called with A ime back end\n");
635 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
643 /***********************************************************************
644 * ImmEscapeA (IMM32.@)
646 LRESULT WINAPI
ImmEscapeA(
648 UINT uEscape
, LPVOID lpData
)
650 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
651 TRACE("(%p, %p, %d, %p):\n", hKL
, hIMC
, uEscape
, lpData
);
653 if (immHkl
->hIME
&& immHkl
->pImeEscape
)
655 if (!is_kbd_ime_unicode(immHkl
))
656 return immHkl
->pImeEscape(hIMC
,uEscape
,lpData
);
659 FIXME("A procedure called with W ime back end\n");
660 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
668 /***********************************************************************
669 * ImmEscapeW (IMM32.@)
671 LRESULT WINAPI
ImmEscapeW(
673 UINT uEscape
, LPVOID lpData
)
675 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
676 TRACE("(%p, %p, %d, %p):\n", hKL
, hIMC
, uEscape
, lpData
);
678 if (immHkl
->hIME
&& immHkl
->pImeEscape
)
680 if (is_kbd_ime_unicode(immHkl
))
681 return immHkl
->pImeEscape(hIMC
,uEscape
,lpData
);
684 FIXME("W procedure called with A ime back end\n");
685 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
693 /***********************************************************************
694 * ImmGetCandidateListA (IMM32.@)
696 DWORD WINAPI
ImmGetCandidateListA(
697 HIMC hIMC
, DWORD deIndex
,
698 LPCANDIDATELIST lpCandList
, DWORD dwBufLen
)
700 FIXME("(%p, %d, %p, %d): stub\n",
704 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
708 /***********************************************************************
709 * ImmGetCandidateListCountA (IMM32.@)
711 DWORD WINAPI
ImmGetCandidateListCountA(
712 HIMC hIMC
, LPDWORD lpdwListCount
)
714 FIXME("(%p, %p): stub\n", hIMC
, lpdwListCount
);
715 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
719 /***********************************************************************
720 * ImmGetCandidateListCountW (IMM32.@)
722 DWORD WINAPI
ImmGetCandidateListCountW(
723 HIMC hIMC
, LPDWORD lpdwListCount
)
725 FIXME("(%p, %p): stub\n", hIMC
, lpdwListCount
);
726 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
730 /***********************************************************************
731 * ImmGetCandidateListW (IMM32.@)
733 DWORD WINAPI
ImmGetCandidateListW(
734 HIMC hIMC
, DWORD deIndex
,
735 LPCANDIDATELIST lpCandList
, DWORD dwBufLen
)
737 FIXME("(%p, %d, %p, %d): stub\n",
741 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
745 /***********************************************************************
746 * ImmGetCandidateWindow (IMM32.@)
748 BOOL WINAPI
ImmGetCandidateWindow(
749 HIMC hIMC
, DWORD dwIndex
, LPCANDIDATEFORM lpCandidate
)
751 InputContextData
*data
= (InputContextData
*)hIMC
;
753 TRACE("%p, %d, %p\n", hIMC
, dwIndex
, lpCandidate
);
755 if (!data
|| !lpCandidate
)
758 if ( dwIndex
>= (sizeof(data
->IMC
.cfCandForm
) / sizeof(CANDIDATEFORM
)) )
761 *lpCandidate
= data
->IMC
.cfCandForm
[dwIndex
];
766 /***********************************************************************
767 * ImmGetCompositionFontA (IMM32.@)
769 BOOL WINAPI
ImmGetCompositionFontA(HIMC hIMC
, LPLOGFONTA lplf
)
774 TRACE("(%p, %p):\n", hIMC
, lplf
);
776 rc
= ImmGetCompositionFontW(hIMC
,&lfW
);
779 memcpy(lplf
,&lfW
,sizeof(LOGFONTA
));
780 WideCharToMultiByte(CP_ACP
, 0, lfW
.lfFaceName
, -1, lplf
->lfFaceName
,
781 LF_FACESIZE
, NULL
, NULL
);
786 /***********************************************************************
787 * ImmGetCompositionFontW (IMM32.@)
789 BOOL WINAPI
ImmGetCompositionFontW(HIMC hIMC
, LPLOGFONTW lplf
)
791 InputContextData
*data
= (InputContextData
*)hIMC
;
793 TRACE("(%p, %p):\n", hIMC
, lplf
);
798 *lplf
= data
->IMC
.lfFont
.W
;
803 /***********************************************************************
804 * ImmGetCompositionStringA (IMM32.@)
806 LONG WINAPI
ImmGetCompositionStringA(
807 HIMC hIMC
, DWORD dwIndex
, LPVOID lpBuf
, DWORD dwBufLen
)
811 InputContextData
*data
= (InputContextData
*)hIMC
;
812 LPCOMPOSITIONSTRING compstr
;
815 TRACE("(%p, 0x%x, %p, %d)\n", hIMC
, dwIndex
, lpBuf
, dwBufLen
);
820 if (!data
->IMC
.hCompStr
)
823 compdata
= ImmLockIMCC(data
->IMC
.hCompStr
);
824 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
826 if (dwIndex
== GCS_RESULTSTR
&& compstr
->dwResultStrLen
> 0 &&
827 compstr
->dwResultStrOffset
> 0)
829 LPWSTR ResultStr
= (LPWSTR
)(compdata
+ compstr
->dwResultStrOffset
);
831 TRACE("GCS_RESULTSTR %p %i\n",ResultStr
,
832 compstr
->dwResultStrLen
);
834 buf
= HeapAlloc( GetProcessHeap(), 0, compstr
->dwResultStrLen
* 3 );
835 rc
= WideCharToMultiByte(CP_ACP
, 0, ResultStr
,
836 compstr
->dwResultStrLen
, buf
,
837 compstr
->dwResultStrLen
* 3, NULL
, NULL
);
839 memcpy(lpBuf
,buf
,rc
);
841 HeapFree( GetProcessHeap(), 0, buf
);
843 else if (dwIndex
== GCS_COMPSTR
&& compstr
->dwCompStrLen
> 0 &&
844 compstr
->dwCompStrOffset
> 0)
846 LPWSTR CompString
= (LPWSTR
)(compdata
+ compstr
->dwCompStrOffset
);
848 TRACE("GCS_COMPSTR %p %i\n", CompString
, compstr
->dwCompStrLen
);
850 buf
= HeapAlloc( GetProcessHeap(), 0, compstr
->dwCompStrLen
* 3 );
851 rc
= WideCharToMultiByte(CP_ACP
, 0, CompString
,
852 compstr
->dwCompStrLen
, buf
,
853 compstr
->dwCompStrLen
* 3, NULL
, NULL
);
855 memcpy(lpBuf
,buf
,rc
);
856 HeapFree( GetProcessHeap(), 0, buf
);
858 else if (dwIndex
== GCS_COMPATTR
&& compstr
->dwCompAttrLen
> 0 &&
859 compstr
->dwCompAttrOffset
> 0)
861 LPWSTR Compattr
= (LPWSTR
)(compdata
+ compstr
->dwCompAttrOffset
);
862 TRACE("GCS_COMPATTR %p %i\n", Compattr
, compstr
->dwCompAttrLen
);
864 rc
= compstr
->dwCompAttrLen
;
866 memcpy(lpBuf
,Compattr
,rc
);
868 else if (dwIndex
== GCS_COMPCLAUSE
&& compstr
->dwCompClauseLen
> 0 &&
869 compstr
->dwCompClauseOffset
> 0)
871 LPWSTR Compclause
= (LPWSTR
)(compdata
+ compstr
->dwCompClauseOffset
);
872 TRACE("GCS_COMPCLAUSE %p %i\n", Compclause
, compstr
->dwCompClauseLen
);
874 rc
= compstr
->dwCompClauseLen
;
875 if (dwBufLen
>= compstr
->dwCompClauseLen
)
876 memcpy(lpBuf
,Compclause
,rc
);
878 else if (dwIndex
== GCS_RESULTCLAUSE
&& compstr
->dwResultClauseLen
> 0 &&
879 compstr
->dwResultClauseOffset
> 0)
881 LPWSTR Resultclause
= (LPWSTR
)(compdata
+ compstr
->dwResultClauseOffset
);
882 TRACE("GCS_RESULTCLAUSE %p %i\n", Resultclause
, compstr
->dwResultClauseLen
);
884 rc
= compstr
->dwResultClauseLen
;
885 if (dwBufLen
>= compstr
->dwResultClauseLen
)
886 memcpy(lpBuf
,Resultclause
,rc
);
888 else if (dwIndex
== GCS_CURSORPOS
)
890 TRACE("GCS_CURSORPOS\n");
891 rc
= compstr
->dwCursorPos
;
893 else if (dwIndex
== GCS_DELTASTART
)
895 TRACE("GCS_DELTASTART\n");
896 rc
= compstr
->dwDeltaStart
;
900 FIXME("Unhandled index 0x%x\n",dwIndex
);
903 ImmUnlockIMCC(data
->IMC
.hCompStr
);
908 /***********************************************************************
909 * ImmGetCompositionStringW (IMM32.@)
911 LONG WINAPI
ImmGetCompositionStringW(
912 HIMC hIMC
, DWORD dwIndex
,
913 LPVOID lpBuf
, DWORD dwBufLen
)
916 InputContextData
*data
= (InputContextData
*)hIMC
;
917 LPCOMPOSITIONSTRING compstr
;
920 TRACE("(%p, 0x%x, %p, %d)\n", hIMC
, dwIndex
, lpBuf
, dwBufLen
);
925 if (!data
->IMC
.hCompStr
)
928 compdata
= ImmLockIMCC(data
->IMC
.hCompStr
);
929 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
931 if (dwIndex
== GCS_RESULTSTR
&& compstr
->dwResultStrLen
> 0 &&
932 compstr
->dwResultStrOffset
> 0)
934 LPWSTR ResultStr
= (LPWSTR
)(compdata
+ compstr
->dwResultStrOffset
);
935 rc
= compstr
->dwResultStrLen
* sizeof(WCHAR
);
938 memcpy(lpBuf
,ResultStr
,rc
);
940 else if (dwIndex
== GCS_RESULTREADSTR
&& compstr
->dwResultReadStrLen
> 0 &&
941 compstr
->dwResultReadStrOffset
> 0)
943 LPWSTR ResultReadString
= (LPWSTR
)(compdata
+ compstr
->dwResultReadStrOffset
);
945 rc
= compstr
->dwResultReadStrLen
* sizeof(WCHAR
);
947 memcpy(lpBuf
,ResultReadString
,rc
);
949 else if (dwIndex
== GCS_COMPSTR
&& compstr
->dwCompStrLen
> 0 &&
950 compstr
->dwCompStrOffset
> 0)
952 LPWSTR CompString
= (LPWSTR
)(compdata
+ compstr
->dwCompStrOffset
);
953 rc
= compstr
->dwCompStrLen
* sizeof(WCHAR
);
955 memcpy(lpBuf
,CompString
,rc
);
957 else if (dwIndex
== GCS_COMPATTR
&& compstr
->dwCompAttrLen
> 0 &&
958 compstr
->dwCompAttrOffset
> 0)
961 LPWSTR Compattr
= (LPWSTR
)(compdata
+ compstr
->dwCompAttrOffset
);
963 rc
= compstr
->dwCompAttrLen
;
965 memcpy(lpBuf
,Compattr
,rc
);
967 else if (dwIndex
== GCS_COMPCLAUSE
&& compstr
->dwCompClauseLen
> 0 &&
968 compstr
->dwCompClauseOffset
> 0)
970 LPWSTR Compclause
= (LPWSTR
)(compdata
+ compstr
->dwCompClauseOffset
);
972 rc
= compstr
->dwCompClauseLen
;
973 if (dwBufLen
>= compstr
->dwCompClauseLen
)
974 memcpy(lpBuf
,Compclause
,rc
);
976 else if (dwIndex
== GCS_COMPREADSTR
&& compstr
->dwCompReadStrLen
> 0 &&
977 compstr
->dwCompReadStrOffset
> 0)
979 LPWSTR CompReadString
= (LPWSTR
)(compdata
+ compstr
->dwCompReadStrOffset
);
981 rc
= compstr
->dwCompReadStrLen
* sizeof(WCHAR
);
984 memcpy(lpBuf
,CompReadString
,rc
);
986 else if (dwIndex
== GCS_CURSORPOS
)
988 TRACE("GCS_CURSORPOS\n");
989 rc
= compstr
->dwCursorPos
;
991 else if (dwIndex
== GCS_DELTASTART
)
993 TRACE("GCS_DELTASTART\n");
994 rc
= compstr
->dwDeltaStart
;
998 FIXME("Unhandled index 0x%x\n",dwIndex
);
1001 ImmUnlockIMCC(data
->IMC
.hCompStr
);
1006 /***********************************************************************
1007 * ImmGetCompositionWindow (IMM32.@)
1009 BOOL WINAPI
ImmGetCompositionWindow(HIMC hIMC
, LPCOMPOSITIONFORM lpCompForm
)
1011 InputContextData
*data
= (InputContextData
*)hIMC
;
1013 TRACE("(%p, %p)\n", hIMC
, lpCompForm
);
1018 *lpCompForm
= data
->IMC
.cfCompForm
;
1022 /***********************************************************************
1023 * ImmGetContext (IMM32.@)
1026 HIMC WINAPI
ImmGetContext(HWND hWnd
)
1030 TRACE("%p\n", hWnd
);
1031 if (!IMM_GetThreadData()->defaultContext
)
1032 IMM_GetThreadData()->defaultContext
= ImmCreateContext();
1034 rc
= (HIMC
)GetPropW(hWnd
,szwWineIMCProperty
);
1037 else if (rc
== NULL
)
1038 rc
= IMM_GetThreadData()->defaultContext
;
1042 InputContextData
*data
= (InputContextData
*)rc
;
1043 data
->IMC
.hWnd
= hWnd
;
1045 TRACE("returning %p\n", rc
);
1050 /***********************************************************************
1051 * ImmGetConversionListA (IMM32.@)
1053 DWORD WINAPI
ImmGetConversionListA(
1055 LPCSTR pSrc
, LPCANDIDATELIST lpDst
,
1056 DWORD dwBufLen
, UINT uFlag
)
1058 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1059 TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL
, hIMC
, debugstr_a(pSrc
), lpDst
,
1061 if (immHkl
->hIME
&& immHkl
->pImeConversionList
)
1063 if (!is_kbd_ime_unicode(immHkl
))
1064 return immHkl
->pImeConversionList(hIMC
,(LPCWSTR
)pSrc
,lpDst
,dwBufLen
,uFlag
);
1067 FIXME("A procedure called with W ime back end\n");
1068 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1076 /***********************************************************************
1077 * ImmGetConversionListW (IMM32.@)
1079 DWORD WINAPI
ImmGetConversionListW(
1081 LPCWSTR pSrc
, LPCANDIDATELIST lpDst
,
1082 DWORD dwBufLen
, UINT uFlag
)
1084 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1085 TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL
, hIMC
, debugstr_w(pSrc
), lpDst
,
1087 if (immHkl
->hIME
&& immHkl
->pImeConversionList
)
1089 if (is_kbd_ime_unicode(immHkl
))
1090 return immHkl
->pImeConversionList(hIMC
,pSrc
,lpDst
,dwBufLen
,uFlag
);
1093 FIXME("W procedure called with A ime back end\n");
1094 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1102 /***********************************************************************
1103 * ImmGetConversionStatus (IMM32.@)
1105 BOOL WINAPI
ImmGetConversionStatus(
1106 HIMC hIMC
, LPDWORD lpfdwConversion
, LPDWORD lpfdwSentence
)
1108 InputContextData
*data
= (InputContextData
*)hIMC
;
1110 TRACE("%p %p %p\n", hIMC
, lpfdwConversion
, lpfdwSentence
);
1115 if (lpfdwConversion
)
1116 *lpfdwConversion
= data
->IMC
.fdwConversion
;
1118 *lpfdwSentence
= data
->IMC
.fdwSentence
;
1123 /***********************************************************************
1124 * ImmGetDefaultIMEWnd (IMM32.@)
1126 HWND WINAPI
ImmGetDefaultIMEWnd(HWND hWnd
)
1128 TRACE("Default is %x\n",(unsigned)IMM_GetThreadData()->hwndDefault
);
1129 return IMM_GetThreadData()->hwndDefault
;
1132 /***********************************************************************
1133 * ImmGetDescriptionA (IMM32.@)
1135 UINT WINAPI
ImmGetDescriptionA(
1136 HKL hKL
, LPSTR lpszDescription
, UINT uBufLen
)
1141 TRACE("%p %p %d\n", hKL
, lpszDescription
, uBufLen
);
1143 /* find out how many characters in the unicode buffer */
1144 len
= ImmGetDescriptionW( hKL
, NULL
, 0 );
1146 /* allocate a buffer of that size */
1147 buf
= HeapAlloc( GetProcessHeap(), 0, (len
+ 1) * sizeof (WCHAR
) );
1151 /* fetch the unicode buffer */
1152 len
= ImmGetDescriptionW( hKL
, buf
, len
+ 1 );
1154 /* convert it back to ASCII */
1155 len
= WideCharToMultiByte( CP_ACP
, 0, buf
, len
+ 1,
1156 lpszDescription
, uBufLen
, NULL
, NULL
);
1158 HeapFree( GetProcessHeap(), 0, buf
);
1163 /***********************************************************************
1164 * ImmGetDescriptionW (IMM32.@)
1166 UINT WINAPI
ImmGetDescriptionW(HKL hKL
, LPWSTR lpszDescription
, UINT uBufLen
)
1168 static const WCHAR name
[] = { 'W','i','n','e',' ','X','I','M',0 };
1170 FIXME("(%p, %p, %d): semi stub\n", hKL
, lpszDescription
, uBufLen
);
1172 if (!uBufLen
) return lstrlenW( name
);
1173 lstrcpynW( lpszDescription
, name
, uBufLen
);
1174 return lstrlenW( lpszDescription
);
1177 /***********************************************************************
1178 * ImmGetGuideLineA (IMM32.@)
1180 DWORD WINAPI
ImmGetGuideLineA(
1181 HIMC hIMC
, DWORD dwIndex
, LPSTR lpBuf
, DWORD dwBufLen
)
1183 FIXME("(%p, %d, %s, %d): stub\n",
1184 hIMC
, dwIndex
, debugstr_a(lpBuf
), dwBufLen
1186 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1190 /***********************************************************************
1191 * ImmGetGuideLineW (IMM32.@)
1193 DWORD WINAPI
ImmGetGuideLineW(HIMC hIMC
, DWORD dwIndex
, LPWSTR lpBuf
, DWORD dwBufLen
)
1195 FIXME("(%p, %d, %s, %d): stub\n",
1196 hIMC
, dwIndex
, debugstr_w(lpBuf
), dwBufLen
1198 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1202 /***********************************************************************
1203 * ImmGetIMEFileNameA (IMM32.@)
1205 UINT WINAPI
ImmGetIMEFileNameA( HKL hKL
, LPSTR lpszFileName
, UINT uBufLen
)
1208 UINT wBufLen
= uBufLen
;
1211 if (uBufLen
&& lpszFileName
)
1212 bufW
= HeapAlloc(GetProcessHeap(),0,uBufLen
* sizeof(WCHAR
));
1213 else /* We need this to get the number of byte required */
1215 bufW
= HeapAlloc(GetProcessHeap(),0,MAX_PATH
* sizeof(WCHAR
));
1219 rc
= ImmGetIMEFileNameW(hKL
,bufW
,wBufLen
);
1223 if (uBufLen
&& lpszFileName
)
1224 rc
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, lpszFileName
,
1225 uBufLen
, NULL
, NULL
);
1226 else /* get the length */
1227 rc
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
,
1231 HeapFree(GetProcessHeap(),0,bufW
);
1235 /***********************************************************************
1236 * ImmGetIMEFileNameW (IMM32.@)
1238 UINT WINAPI
ImmGetIMEFileNameW(HKL hKL
, LPWSTR lpszFileName
, UINT uBufLen
)
1240 static const WCHAR szImeFileW
[] = {'I','m','e',' ','F','i','l','e',0};
1241 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};
1246 WCHAR regKey
[sizeof(fmt
)/sizeof(WCHAR
)+8];
1248 wsprintfW( regKey
, fmt
, (unsigned)hKL
);
1249 rc
= RegOpenKeyW( HKEY_LOCAL_MACHINE
, regKey
, &hkey
);
1250 if (rc
!= ERROR_SUCCESS
)
1257 rc
= RegGetValueW(hkey
, NULL
, szImeFileW
, RRF_RT_REG_SZ
, NULL
, NULL
, &length
);
1259 if (rc
!= ERROR_SUCCESS
)
1265 if (length
> uBufLen
* sizeof(WCHAR
) || !lpszFileName
)
1270 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1274 return length
/ sizeof(WCHAR
);
1277 RegGetValueW(hkey
, NULL
, szImeFileW
, RRF_RT_REG_SZ
, NULL
, lpszFileName
, &length
);
1281 return length
/ sizeof(WCHAR
);
1284 /***********************************************************************
1285 * ImmGetOpenStatus (IMM32.@)
1287 BOOL WINAPI
ImmGetOpenStatus(HIMC hIMC
)
1289 InputContextData
*data
= (InputContextData
*)hIMC
;
1293 FIXME("(%p): semi-stub\n", hIMC
);
1295 return data
->IMC
.fOpen
;
1298 /***********************************************************************
1299 * ImmGetProperty (IMM32.@)
1301 DWORD WINAPI
ImmGetProperty(HKL hKL
, DWORD fdwIndex
)
1306 TRACE("(%p, %d)\n", hKL
, fdwIndex
);
1307 kbd
= IMM_GetImmHkl(hKL
);
1309 if (kbd
&& kbd
->hIME
)
1313 case IGP_PROPERTY
: rc
= kbd
->imeInfo
.fdwProperty
; break;
1314 case IGP_CONVERSION
: rc
= kbd
->imeInfo
.fdwConversionCaps
; break;
1315 case IGP_SENTENCE
: rc
= kbd
->imeInfo
.fdwSentenceCaps
; break;
1316 case IGP_SETCOMPSTR
: rc
= kbd
->imeInfo
.fdwSCSCaps
; break;
1317 case IGP_SELECT
: rc
= kbd
->imeInfo
.fdwSelectCaps
; break;
1318 case IGP_GETIMEVERSION
: rc
= IMEVER_0400
; break;
1319 case IGP_UI
: rc
= 0; break;
1326 /***********************************************************************
1327 * ImmGetRegisterWordStyleA (IMM32.@)
1329 UINT WINAPI
ImmGetRegisterWordStyleA(
1330 HKL hKL
, UINT nItem
, LPSTYLEBUFA lpStyleBuf
)
1332 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1333 TRACE("(%p, %d, %p):\n", hKL
, nItem
, lpStyleBuf
);
1334 if (immHkl
->hIME
&& immHkl
->pImeGetRegisterWordStyle
)
1336 if (!is_kbd_ime_unicode(immHkl
))
1337 return immHkl
->pImeGetRegisterWordStyle(nItem
,(LPSTYLEBUFW
)lpStyleBuf
);
1343 rc
= immHkl
->pImeGetRegisterWordStyle(nItem
,&sbw
);
1344 WideCharToMultiByte(CP_ACP
, 0, sbw
.szDescription
, -1,
1345 lpStyleBuf
->szDescription
, 32, NULL
, NULL
);
1346 lpStyleBuf
->dwStyle
= sbw
.dwStyle
;
1354 /***********************************************************************
1355 * ImmGetRegisterWordStyleW (IMM32.@)
1357 UINT WINAPI
ImmGetRegisterWordStyleW(
1358 HKL hKL
, UINT nItem
, LPSTYLEBUFW lpStyleBuf
)
1360 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1361 TRACE("(%p, %d, %p):\n", hKL
, nItem
, lpStyleBuf
);
1362 if (immHkl
->hIME
&& immHkl
->pImeGetRegisterWordStyle
)
1364 if (is_kbd_ime_unicode(immHkl
))
1365 return immHkl
->pImeGetRegisterWordStyle(nItem
,lpStyleBuf
);
1371 rc
= immHkl
->pImeGetRegisterWordStyle(nItem
,(LPSTYLEBUFW
)&sba
);
1372 MultiByteToWideChar(CP_ACP
, 0, sba
.szDescription
, -1,
1373 lpStyleBuf
->szDescription
, 32);
1374 lpStyleBuf
->dwStyle
= sba
.dwStyle
;
1382 /***********************************************************************
1383 * ImmGetStatusWindowPos (IMM32.@)
1385 BOOL WINAPI
ImmGetStatusWindowPos(HIMC hIMC
, LPPOINT lpptPos
)
1387 FIXME("(%p, %p): stub\n", hIMC
, lpptPos
);
1388 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1392 /***********************************************************************
1393 * ImmGetVirtualKey (IMM32.@)
1395 UINT WINAPI
ImmGetVirtualKey(HWND hWnd
)
1397 OSVERSIONINFOA version
;
1398 InputContextData
*data
= (InputContextData
*)ImmGetContext( hWnd
);
1399 TRACE("%p\n", hWnd
);
1402 return data
->lastVK
;
1404 GetVersionExA( &version
);
1405 switch(version
.dwPlatformId
)
1407 case VER_PLATFORM_WIN32_WINDOWS
:
1408 return VK_PROCESSKEY
;
1409 case VER_PLATFORM_WIN32_NT
:
1412 FIXME("%d not supported\n",version
.dwPlatformId
);
1413 return VK_PROCESSKEY
;
1417 /***********************************************************************
1418 * ImmInstallIMEA (IMM32.@)
1420 HKL WINAPI
ImmInstallIMEA(
1421 LPCSTR lpszIMEFileName
, LPCSTR lpszLayoutText
)
1423 FIXME("(%s, %s): stub\n",
1424 debugstr_a(lpszIMEFileName
), debugstr_a(lpszLayoutText
)
1426 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1430 /***********************************************************************
1431 * ImmInstallIMEW (IMM32.@)
1433 HKL WINAPI
ImmInstallIMEW(
1434 LPCWSTR lpszIMEFileName
, LPCWSTR lpszLayoutText
)
1436 FIXME("(%s, %s): stub\n",
1437 debugstr_w(lpszIMEFileName
), debugstr_w(lpszLayoutText
)
1439 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1443 /***********************************************************************
1444 * ImmIsIME (IMM32.@)
1446 BOOL WINAPI
ImmIsIME(HKL hKL
)
1449 TRACE("(%p):\n", hKL
);
1450 ptr
= IMM_GetImmHkl(hKL
);
1451 return (ptr
&& ptr
->hIME
);
1454 /***********************************************************************
1455 * ImmIsUIMessageA (IMM32.@)
1457 BOOL WINAPI
ImmIsUIMessageA(
1458 HWND hWndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1462 TRACE("(%p, %x, %ld, %ld)\n", hWndIME
, msg
, wParam
, lParam
);
1463 if ((msg
>= WM_IME_STARTCOMPOSITION
&& msg
<= WM_IME_KEYLAST
) ||
1464 (msg
>= WM_IME_SETCONTEXT
&& msg
<= WM_IME_KEYUP
) ||
1465 (msg
== WM_MSIME_SERVICE
) ||
1466 (msg
== WM_MSIME_RECONVERTOPTIONS
) ||
1467 (msg
== WM_MSIME_MOUSE
) ||
1468 (msg
== WM_MSIME_RECONVERTREQUEST
) ||
1469 (msg
== WM_MSIME_RECONVERT
) ||
1470 (msg
== WM_MSIME_QUERYPOSITION
) ||
1471 (msg
== WM_MSIME_DOCUMENTFEED
))
1474 if (!IMM_GetThreadData()->hwndDefault
)
1475 ImmGetDefaultIMEWnd(NULL
);
1477 if (hWndIME
== NULL
)
1478 PostMessageA(IMM_GetThreadData()->hwndDefault
, msg
, wParam
, lParam
);
1485 /***********************************************************************
1486 * ImmIsUIMessageW (IMM32.@)
1488 BOOL WINAPI
ImmIsUIMessageW(
1489 HWND hWndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1492 TRACE("(%p, %d, %ld, %ld):\n", hWndIME
, msg
, wParam
, lParam
);
1493 if ((msg
>= WM_IME_STARTCOMPOSITION
&& msg
<= WM_IME_KEYLAST
) ||
1494 (msg
>= WM_IME_SETCONTEXT
&& msg
<= WM_IME_KEYUP
) ||
1495 (msg
== WM_MSIME_SERVICE
) ||
1496 (msg
== WM_MSIME_RECONVERTOPTIONS
) ||
1497 (msg
== WM_MSIME_MOUSE
) ||
1498 (msg
== WM_MSIME_RECONVERTREQUEST
) ||
1499 (msg
== WM_MSIME_RECONVERT
) ||
1500 (msg
== WM_MSIME_QUERYPOSITION
) ||
1501 (msg
== WM_MSIME_DOCUMENTFEED
))
1506 /***********************************************************************
1507 * ImmNotifyIME (IMM32.@)
1509 BOOL WINAPI
ImmNotifyIME(
1510 HIMC hIMC
, DWORD dwAction
, DWORD dwIndex
, DWORD dwValue
)
1512 InputContextData
*data
= (InputContextData
*)hIMC
;
1514 TRACE("(%p, %d, %d, %d)\n",
1515 hIMC
, dwAction
, dwIndex
, dwValue
);
1517 if (!data
|| ! data
->immKbd
->pNotifyIME
)
1520 return data
->immKbd
->pNotifyIME(hIMC
,dwAction
,dwIndex
,dwValue
);
1523 /***********************************************************************
1524 * ImmRegisterWordA (IMM32.@)
1526 BOOL WINAPI
ImmRegisterWordA(
1527 HKL hKL
, LPCSTR lpszReading
, DWORD dwStyle
, LPCSTR lpszRegister
)
1529 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1530 TRACE("(%p, %s, %d, %s):\n", hKL
, debugstr_a(lpszReading
), dwStyle
,
1531 debugstr_a(lpszRegister
));
1532 if (immHkl
->hIME
&& immHkl
->pImeRegisterWord
)
1534 if (!is_kbd_ime_unicode(immHkl
))
1535 return immHkl
->pImeRegisterWord((LPCWSTR
)lpszReading
,dwStyle
,
1536 (LPCWSTR
)lpszRegister
);
1539 LPWSTR lpszwReading
= strdupAtoW(lpszReading
);
1540 LPWSTR lpszwRegister
= strdupAtoW(lpszRegister
);
1543 rc
= immHkl
->pImeRegisterWord(lpszwReading
,dwStyle
,lpszwRegister
);
1544 HeapFree(GetProcessHeap(),0,lpszwReading
);
1545 HeapFree(GetProcessHeap(),0,lpszwRegister
);
1553 /***********************************************************************
1554 * ImmRegisterWordW (IMM32.@)
1556 BOOL WINAPI
ImmRegisterWordW(
1557 HKL hKL
, LPCWSTR lpszReading
, DWORD dwStyle
, LPCWSTR lpszRegister
)
1559 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1560 TRACE("(%p, %s, %d, %s):\n", hKL
, debugstr_w(lpszReading
), dwStyle
,
1561 debugstr_w(lpszRegister
));
1562 if (immHkl
->hIME
&& immHkl
->pImeRegisterWord
)
1564 if (is_kbd_ime_unicode(immHkl
))
1565 return immHkl
->pImeRegisterWord(lpszReading
,dwStyle
,lpszRegister
);
1568 LPSTR lpszaReading
= strdupWtoA(lpszReading
);
1569 LPSTR lpszaRegister
= strdupWtoA(lpszRegister
);
1572 rc
= immHkl
->pImeRegisterWord((LPCWSTR
)lpszaReading
,dwStyle
,
1573 (LPCWSTR
)lpszaRegister
);
1574 HeapFree(GetProcessHeap(),0,lpszaReading
);
1575 HeapFree(GetProcessHeap(),0,lpszaRegister
);
1583 /***********************************************************************
1584 * ImmReleaseContext (IMM32.@)
1586 BOOL WINAPI
ImmReleaseContext(HWND hWnd
, HIMC hIMC
)
1588 static int shown
= 0;
1591 FIXME("(%p, %p): stub\n", hWnd
, hIMC
);
1597 /***********************************************************************
1598 * ImmRequestMessageA(IMM32.@)
1600 LRESULT WINAPI
ImmRequestMessageA(HIMC hIMC
, WPARAM wParam
, LPARAM lParam
)
1602 FIXME("(%p %ld %ld): stub\n", hIMC
, wParam
, wParam
);
1603 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1607 /***********************************************************************
1608 * ImmRequestMessageW(IMM32.@)
1610 LRESULT WINAPI
ImmRequestMessageW(HIMC hIMC
, WPARAM wParam
, LPARAM lParam
)
1612 FIXME("(%p %ld %ld): stub\n", hIMC
, wParam
, wParam
);
1613 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1617 /***********************************************************************
1618 * ImmSetCandidateWindow (IMM32.@)
1620 BOOL WINAPI
ImmSetCandidateWindow(
1621 HIMC hIMC
, LPCANDIDATEFORM lpCandidate
)
1623 InputContextData
*data
= (InputContextData
*)hIMC
;
1625 TRACE("(%p, %p)\n", hIMC
, lpCandidate
);
1627 if (!data
|| !lpCandidate
)
1630 TRACE("\t%x, %x, (%i,%i), (%i,%i - %i,%i)\n",
1631 lpCandidate
->dwIndex
, lpCandidate
->dwStyle
,
1632 lpCandidate
->ptCurrentPos
.x
, lpCandidate
->ptCurrentPos
.y
,
1633 lpCandidate
->rcArea
.top
, lpCandidate
->rcArea
.left
,
1634 lpCandidate
->rcArea
.bottom
, lpCandidate
->rcArea
.right
);
1636 if ( lpCandidate
->dwIndex
>= (sizeof(data
->IMC
.cfCandForm
) / sizeof(CANDIDATEFORM
)) )
1639 data
->IMC
.cfCandForm
[lpCandidate
->dwIndex
] = *lpCandidate
;
1640 ImmNotifyIME(hIMC
, NI_CONTEXTUPDATED
, 0, IMC_SETCANDIDATEPOS
);
1641 ImmInternalSendIMENotify(data
, IMN_SETCANDIDATEPOS
, 1 << lpCandidate
->dwIndex
);
1646 /***********************************************************************
1647 * ImmSetCompositionFontA (IMM32.@)
1649 BOOL WINAPI
ImmSetCompositionFontA(HIMC hIMC
, LPLOGFONTA lplf
)
1651 InputContextData
*data
= (InputContextData
*)hIMC
;
1652 TRACE("(%p, %p)\n", hIMC
, lplf
);
1657 memcpy(&data
->IMC
.lfFont
.W
,lplf
,sizeof(LOGFONTA
));
1658 MultiByteToWideChar(CP_ACP
, 0, lplf
->lfFaceName
, -1, data
->IMC
.lfFont
.W
.lfFaceName
,
1660 ImmInternalSendIMENotify(data
, IMN_SETCOMPOSITIONFONT
, 0);
1665 /***********************************************************************
1666 * ImmSetCompositionFontW (IMM32.@)
1668 BOOL WINAPI
ImmSetCompositionFontW(HIMC hIMC
, LPLOGFONTW lplf
)
1670 InputContextData
*data
= (InputContextData
*)hIMC
;
1671 TRACE("(%p, %p)\n", hIMC
, lplf
);
1676 data
->IMC
.lfFont
.W
= *lplf
;
1677 ImmInternalSendIMENotify(data
, IMN_SETCOMPOSITIONFONT
, 0);
1682 /***********************************************************************
1683 * ImmSetCompositionStringA (IMM32.@)
1685 BOOL WINAPI
ImmSetCompositionStringA(
1686 HIMC hIMC
, DWORD dwIndex
,
1687 LPCVOID lpComp
, DWORD dwCompLen
,
1688 LPCVOID lpRead
, DWORD dwReadLen
)
1692 WCHAR
*CompBuffer
= NULL
;
1693 WCHAR
*ReadBuffer
= NULL
;
1695 InputContextData
*data
= (InputContextData
*)hIMC
;
1697 TRACE("(%p, %d, %p, %d, %p, %d):\n",
1698 hIMC
, dwIndex
, lpComp
, dwCompLen
, lpRead
, dwReadLen
);
1703 if (!is_himc_ime_unicode(data
))
1704 return data
->immKbd
->pImeSetCompositionString(hIMC
, dwIndex
, lpComp
,
1705 dwCompLen
, lpRead
, dwReadLen
);
1707 comp_len
= MultiByteToWideChar(CP_ACP
, 0, lpComp
, dwCompLen
, NULL
, 0);
1710 CompBuffer
= HeapAlloc(GetProcessHeap(),0,comp_len
* sizeof(WCHAR
));
1711 MultiByteToWideChar(CP_ACP
, 0, lpComp
, dwCompLen
, CompBuffer
, comp_len
);
1714 read_len
= MultiByteToWideChar(CP_ACP
, 0, lpRead
, dwReadLen
, NULL
, 0);
1717 ReadBuffer
= HeapAlloc(GetProcessHeap(),0,read_len
* sizeof(WCHAR
));
1718 MultiByteToWideChar(CP_ACP
, 0, lpRead
, dwReadLen
, ReadBuffer
, read_len
);
1721 rc
= ImmSetCompositionStringW(hIMC
, dwIndex
, CompBuffer
, comp_len
,
1722 ReadBuffer
, read_len
);
1724 HeapFree(GetProcessHeap(), 0, CompBuffer
);
1725 HeapFree(GetProcessHeap(), 0, ReadBuffer
);
1730 /***********************************************************************
1731 * ImmSetCompositionStringW (IMM32.@)
1733 BOOL WINAPI
ImmSetCompositionStringW(
1734 HIMC hIMC
, DWORD dwIndex
,
1735 LPCVOID lpComp
, DWORD dwCompLen
,
1736 LPCVOID lpRead
, DWORD dwReadLen
)
1740 CHAR
*CompBuffer
= NULL
;
1741 CHAR
*ReadBuffer
= NULL
;
1743 InputContextData
*data
= (InputContextData
*)hIMC
;
1745 TRACE("(%p, %d, %p, %d, %p, %d):\n",
1746 hIMC
, dwIndex
, lpComp
, dwCompLen
, lpRead
, dwReadLen
);
1751 if (is_himc_ime_unicode(data
))
1752 return data
->immKbd
->pImeSetCompositionString(hIMC
, dwIndex
, lpComp
,
1753 dwCompLen
, lpRead
, dwReadLen
);
1755 comp_len
= WideCharToMultiByte(CP_ACP
, 0, lpComp
, dwCompLen
, NULL
, 0, NULL
,
1759 CompBuffer
= HeapAlloc(GetProcessHeap(),0,comp_len
);
1760 WideCharToMultiByte(CP_ACP
, 0, lpComp
, dwCompLen
, CompBuffer
, comp_len
,
1764 read_len
= WideCharToMultiByte(CP_ACP
, 0, lpRead
, dwReadLen
, NULL
, 0, NULL
,
1768 ReadBuffer
= HeapAlloc(GetProcessHeap(),0,read_len
);
1769 WideCharToMultiByte(CP_ACP
, 0, lpRead
, dwReadLen
, ReadBuffer
, read_len
,
1773 rc
= ImmSetCompositionStringA(hIMC
, dwIndex
, CompBuffer
, comp_len
,
1774 ReadBuffer
, read_len
);
1776 HeapFree(GetProcessHeap(), 0, CompBuffer
);
1777 HeapFree(GetProcessHeap(), 0, ReadBuffer
);
1782 /***********************************************************************
1783 * ImmSetCompositionWindow (IMM32.@)
1785 BOOL WINAPI
ImmSetCompositionWindow(
1786 HIMC hIMC
, LPCOMPOSITIONFORM lpCompForm
)
1788 BOOL reshow
= FALSE
;
1789 InputContextData
*data
= (InputContextData
*)hIMC
;
1791 TRACE("(%p, %p)\n", hIMC
, lpCompForm
);
1792 TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm
->dwStyle
,
1793 lpCompForm
->ptCurrentPos
.x
, lpCompForm
->ptCurrentPos
.y
, lpCompForm
->rcArea
.top
,
1794 lpCompForm
->rcArea
.left
, lpCompForm
->rcArea
.bottom
, lpCompForm
->rcArea
.right
);
1799 data
->IMC
.cfCompForm
= *lpCompForm
;
1801 if (IsWindowVisible(IMM_GetThreadData()->hwndDefault
))
1804 ShowWindow(IMM_GetThreadData()->hwndDefault
,SW_HIDE
);
1807 /* FIXME: this is a partial stub */
1810 ShowWindow(IMM_GetThreadData()->hwndDefault
,SW_SHOWNOACTIVATE
);
1812 ImmInternalSendIMENotify(data
, IMN_SETCOMPOSITIONWINDOW
, 0);
1816 /***********************************************************************
1817 * ImmSetConversionStatus (IMM32.@)
1819 BOOL WINAPI
ImmSetConversionStatus(
1820 HIMC hIMC
, DWORD fdwConversion
, DWORD fdwSentence
)
1822 DWORD oldConversion
, oldSentence
;
1823 InputContextData
*data
= (InputContextData
*)hIMC
;
1825 TRACE("%p %d %d\n", hIMC
, fdwConversion
, fdwSentence
);
1830 if ( fdwConversion
!= data
->IMC
.fdwConversion
)
1832 oldConversion
= data
->IMC
.fdwConversion
;
1833 data
->IMC
.fdwConversion
= fdwConversion
;
1834 ImmNotifyIME(hIMC
, NI_CONTEXTUPDATED
, oldConversion
, IMC_SETCONVERSIONMODE
);
1835 ImmInternalSendIMENotify(data
, IMN_SETCONVERSIONMODE
, 0);
1837 if ( fdwSentence
!= data
->IMC
.fdwSentence
)
1839 oldSentence
= data
->IMC
.fdwSentence
;
1840 data
->IMC
.fdwSentence
= fdwSentence
;
1841 ImmNotifyIME(hIMC
, NI_CONTEXTUPDATED
, oldSentence
, IMC_SETSENTENCEMODE
);
1842 ImmInternalSendIMENotify(data
, IMN_SETSENTENCEMODE
, 0);
1848 /***********************************************************************
1849 * ImmSetOpenStatus (IMM32.@)
1851 BOOL WINAPI
ImmSetOpenStatus(HIMC hIMC
, BOOL fOpen
)
1853 InputContextData
*data
= (InputContextData
*)hIMC
;
1855 TRACE("%p %d\n", hIMC
, fOpen
);
1860 if (data
->imeWnd
== NULL
)
1862 /* create the ime window */
1863 data
->imeWnd
= CreateWindowExW( WS_EX_TOOLWINDOW
,
1864 data
->immKbd
->imeClassName
, NULL
, WS_POPUP
, 0, 0, 1, 1, 0,
1865 0, data
->immKbd
->hIME
, 0);
1866 SetWindowLongW(data
->imeWnd
, IMMGWL_IMC
, (LONG
)data
);
1867 IMM_GetThreadData()->hwndDefault
= data
->imeWnd
;
1870 if (!fOpen
!= !data
->IMC
.fOpen
)
1872 data
->IMC
.fOpen
= fOpen
;
1873 ImmNotifyIME( hIMC
, NI_CONTEXTUPDATED
, 0, IMC_SETOPENSTATUS
);
1874 ImmInternalSendIMENotify(data
, IMN_SETOPENSTATUS
, 0);
1880 /***********************************************************************
1881 * ImmSetStatusWindowPos (IMM32.@)
1883 BOOL WINAPI
ImmSetStatusWindowPos(HIMC hIMC
, LPPOINT lpptPos
)
1885 FIXME("(%p, %p): stub\n", hIMC
, lpptPos
);
1886 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1890 /***********************************************************************
1891 * ImmCreateSoftKeyboard(IMM32.@)
1893 HWND WINAPI
ImmCreateSoftKeyboard(UINT uType
, UINT hOwner
, int x
, int y
)
1895 FIXME("(%d, %d, %d, %d): stub\n", uType
, hOwner
, x
, y
);
1896 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1900 /***********************************************************************
1901 * ImmDestroySoftKeyboard(IMM32.@)
1903 BOOL WINAPI
ImmDestroySoftKeyboard(HWND hSoftWnd
)
1905 FIXME("(%p): stub\n", hSoftWnd
);
1906 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1910 /***********************************************************************
1911 * ImmShowSoftKeyboard(IMM32.@)
1913 BOOL WINAPI
ImmShowSoftKeyboard(HWND hSoftWnd
, int nCmdShow
)
1915 FIXME("(%p, %d): stub\n", hSoftWnd
, nCmdShow
);
1916 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1920 /***********************************************************************
1921 * ImmSimulateHotKey (IMM32.@)
1923 BOOL WINAPI
ImmSimulateHotKey(HWND hWnd
, DWORD dwHotKeyID
)
1925 FIXME("(%p, %d): stub\n", hWnd
, dwHotKeyID
);
1926 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1930 /***********************************************************************
1931 * ImmUnregisterWordA (IMM32.@)
1933 BOOL WINAPI
ImmUnregisterWordA(
1934 HKL hKL
, LPCSTR lpszReading
, DWORD dwStyle
, LPCSTR lpszUnregister
)
1936 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1937 TRACE("(%p, %s, %d, %s):\n", hKL
, debugstr_a(lpszReading
), dwStyle
,
1938 debugstr_a(lpszUnregister
));
1939 if (immHkl
->hIME
&& immHkl
->pImeUnregisterWord
)
1941 if (!is_kbd_ime_unicode(immHkl
))
1942 return immHkl
->pImeUnregisterWord((LPCWSTR
)lpszReading
,dwStyle
,
1943 (LPCWSTR
)lpszUnregister
);
1946 LPWSTR lpszwReading
= strdupAtoW(lpszReading
);
1947 LPWSTR lpszwUnregister
= strdupAtoW(lpszUnregister
);
1950 rc
= immHkl
->pImeUnregisterWord(lpszwReading
,dwStyle
,lpszwUnregister
);
1951 HeapFree(GetProcessHeap(),0,lpszwReading
);
1952 HeapFree(GetProcessHeap(),0,lpszwUnregister
);
1960 /***********************************************************************
1961 * ImmUnregisterWordW (IMM32.@)
1963 BOOL WINAPI
ImmUnregisterWordW(
1964 HKL hKL
, LPCWSTR lpszReading
, DWORD dwStyle
, LPCWSTR lpszUnregister
)
1966 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1967 TRACE("(%p, %s, %d, %s):\n", hKL
, debugstr_w(lpszReading
), dwStyle
,
1968 debugstr_w(lpszUnregister
));
1969 if (immHkl
->hIME
&& immHkl
->pImeUnregisterWord
)
1971 if (is_kbd_ime_unicode(immHkl
))
1972 return immHkl
->pImeUnregisterWord(lpszReading
,dwStyle
,lpszUnregister
);
1975 LPSTR lpszaReading
= strdupWtoA(lpszReading
);
1976 LPSTR lpszaUnregister
= strdupWtoA(lpszUnregister
);
1979 rc
= immHkl
->pImeUnregisterWord((LPCWSTR
)lpszaReading
,dwStyle
,
1980 (LPCWSTR
)lpszaUnregister
);
1981 HeapFree(GetProcessHeap(),0,lpszaReading
);
1982 HeapFree(GetProcessHeap(),0,lpszaUnregister
);
1990 /***********************************************************************
1991 * ImmGetImeMenuItemsA (IMM32.@)
1993 DWORD WINAPI
ImmGetImeMenuItemsA( HIMC hIMC
, DWORD dwFlags
, DWORD dwType
,
1994 LPIMEMENUITEMINFOA lpImeParentMenu
, LPIMEMENUITEMINFOA lpImeMenu
,
1997 InputContextData
*data
= (InputContextData
*)hIMC
;
1998 TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC
, dwFlags
, dwType
,
1999 lpImeParentMenu
, lpImeMenu
, dwSize
);
2000 if (data
->immKbd
->hIME
&& data
->immKbd
->pImeGetImeMenuItems
)
2002 if (!is_himc_ime_unicode(data
) || (!lpImeParentMenu
&& !lpImeMenu
))
2003 return data
->immKbd
->pImeGetImeMenuItems(hIMC
, dwFlags
, dwType
,
2004 (IMEMENUITEMINFOW
*)lpImeParentMenu
,
2005 (IMEMENUITEMINFOW
*)lpImeMenu
, dwSize
);
2008 IMEMENUITEMINFOW lpImeParentMenuW
;
2009 IMEMENUITEMINFOW
*lpImeMenuW
, *parent
= NULL
;
2012 if (lpImeParentMenu
)
2013 parent
= &lpImeParentMenuW
;
2016 int count
= dwSize
/ sizeof(LPIMEMENUITEMINFOA
);
2017 dwSize
= count
* sizeof(IMEMENUITEMINFOW
);
2018 lpImeMenuW
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
2023 rc
= data
->immKbd
->pImeGetImeMenuItems(hIMC
, dwFlags
, dwType
,
2024 parent
, lpImeMenuW
, dwSize
);
2026 if (lpImeParentMenu
)
2028 memcpy(lpImeParentMenu
,&lpImeParentMenuW
,sizeof(IMEMENUITEMINFOA
));
2029 lpImeParentMenu
->hbmpItem
= lpImeParentMenuW
.hbmpItem
;
2030 WideCharToMultiByte(CP_ACP
, 0, lpImeParentMenuW
.szString
,
2031 -1, lpImeParentMenu
->szString
, IMEMENUITEM_STRING_SIZE
,
2034 if (lpImeMenu
&& rc
)
2037 for (i
= 0; i
< rc
; i
++)
2039 memcpy(&lpImeMenu
[i
],&lpImeMenuW
[1],sizeof(IMEMENUITEMINFOA
));
2040 lpImeMenu
[i
].hbmpItem
= lpImeMenuW
[i
].hbmpItem
;
2041 WideCharToMultiByte(CP_ACP
, 0, lpImeMenuW
[i
].szString
,
2042 -1, lpImeMenu
[i
].szString
, IMEMENUITEM_STRING_SIZE
,
2046 HeapFree(GetProcessHeap(),0,lpImeMenuW
);
2054 /***********************************************************************
2055 * ImmGetImeMenuItemsW (IMM32.@)
2057 DWORD WINAPI
ImmGetImeMenuItemsW( HIMC hIMC
, DWORD dwFlags
, DWORD dwType
,
2058 LPIMEMENUITEMINFOW lpImeParentMenu
, LPIMEMENUITEMINFOW lpImeMenu
,
2061 InputContextData
*data
= (InputContextData
*)hIMC
;
2062 TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC
, dwFlags
, dwType
,
2063 lpImeParentMenu
, lpImeMenu
, dwSize
);
2064 if (data
->immKbd
->hIME
&& data
->immKbd
->pImeGetImeMenuItems
)
2066 if (is_himc_ime_unicode(data
) || (!lpImeParentMenu
&& !lpImeMenu
))
2067 return data
->immKbd
->pImeGetImeMenuItems(hIMC
, dwFlags
, dwType
,
2068 lpImeParentMenu
, lpImeMenu
, dwSize
);
2071 IMEMENUITEMINFOA lpImeParentMenuA
;
2072 IMEMENUITEMINFOA
*lpImeMenuA
, *parent
= NULL
;
2075 if (lpImeParentMenu
)
2076 parent
= &lpImeParentMenuA
;
2079 int count
= dwSize
/ sizeof(LPIMEMENUITEMINFOW
);
2080 dwSize
= count
* sizeof(IMEMENUITEMINFOA
);
2081 lpImeMenuA
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
2086 rc
= data
->immKbd
->pImeGetImeMenuItems(hIMC
, dwFlags
, dwType
,
2087 (IMEMENUITEMINFOW
*)parent
,
2088 (IMEMENUITEMINFOW
*)lpImeMenuA
, dwSize
);
2090 if (lpImeParentMenu
)
2092 memcpy(lpImeParentMenu
,&lpImeParentMenuA
,sizeof(IMEMENUITEMINFOA
));
2093 lpImeParentMenu
->hbmpItem
= lpImeParentMenuA
.hbmpItem
;
2094 MultiByteToWideChar(CP_ACP
, 0, lpImeParentMenuA
.szString
,
2095 -1, lpImeParentMenu
->szString
, IMEMENUITEM_STRING_SIZE
);
2097 if (lpImeMenu
&& rc
)
2100 for (i
= 0; i
< rc
; i
++)
2102 memcpy(&lpImeMenu
[i
],&lpImeMenuA
[1],sizeof(IMEMENUITEMINFOA
));
2103 lpImeMenu
[i
].hbmpItem
= lpImeMenuA
[i
].hbmpItem
;
2104 MultiByteToWideChar(CP_ACP
, 0, lpImeMenuA
[i
].szString
,
2105 -1, lpImeMenu
[i
].szString
, IMEMENUITEM_STRING_SIZE
);
2108 HeapFree(GetProcessHeap(),0,lpImeMenuA
);
2116 /***********************************************************************
2117 * ImmLockIMC(IMM32.@)
2119 LPINPUTCONTEXT WINAPI
ImmLockIMC(HIMC hIMC
)
2121 InputContextData
*data
= (InputContextData
*)hIMC
;
2129 /***********************************************************************
2130 * ImmUnlockIMC(IMM32.@)
2132 BOOL WINAPI
ImmUnlockIMC(HIMC hIMC
)
2134 InputContextData
*data
= (InputContextData
*)hIMC
;
2136 return (data
->dwLock
!=0);
2139 /***********************************************************************
2140 * ImmGetIMCLockCount(IMM32.@)
2142 DWORD WINAPI
ImmGetIMCLockCount(HIMC hIMC
)
2144 InputContextData
*data
= (InputContextData
*)hIMC
;
2145 return data
->dwLock
;
2148 /***********************************************************************
2149 * ImmCreateIMCC(IMM32.@)
2151 HIMCC WINAPI
ImmCreateIMCC(DWORD size
)
2153 IMCCInternal
*internal
;
2154 int real_size
= size
+ sizeof(IMCCInternal
);
2156 internal
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, real_size
);
2157 if (internal
== NULL
)
2160 internal
->dwSize
= size
;
2161 return (HIMCC
)internal
;
2164 /***********************************************************************
2165 * ImmDestroyIMCC(IMM32.@)
2167 HIMCC WINAPI
ImmDestroyIMCC(HIMCC block
)
2169 HeapFree(GetProcessHeap(),0,block
);
2173 /***********************************************************************
2174 * ImmLockIMCC(IMM32.@)
2176 LPVOID WINAPI
ImmLockIMCC(HIMCC imcc
)
2178 IMCCInternal
*internal
;
2179 internal
= (IMCCInternal
*) imcc
;
2181 internal
->dwLock
++;
2182 return internal
+ 1;
2185 /***********************************************************************
2186 * ImmUnlockIMCC(IMM32.@)
2188 BOOL WINAPI
ImmUnlockIMCC(HIMCC imcc
)
2190 IMCCInternal
*internal
;
2191 internal
= (IMCCInternal
*) imcc
;
2193 internal
->dwLock
--;
2194 return (internal
->dwLock
!=0);
2197 /***********************************************************************
2198 * ImmGetIMCCLockCount(IMM32.@)
2200 DWORD WINAPI
ImmGetIMCCLockCount(HIMCC imcc
)
2202 IMCCInternal
*internal
;
2203 internal
= (IMCCInternal
*) imcc
;
2205 return internal
->dwLock
;
2208 /***********************************************************************
2209 * ImmReSizeIMCC(IMM32.@)
2211 HIMCC WINAPI
ImmReSizeIMCC(HIMCC imcc
, DWORD size
)
2213 IMCCInternal
*internal
,*newone
;
2214 int real_size
= size
+ sizeof(IMCCInternal
);
2216 internal
= (IMCCInternal
*) imcc
;
2218 newone
= HeapReAlloc(GetProcessHeap(), 0, internal
, real_size
);
2219 newone
->dwSize
= size
;
2224 /***********************************************************************
2225 * ImmGetIMCCSize(IMM32.@)
2227 DWORD WINAPI
ImmGetIMCCSize(HIMCC imcc
)
2229 IMCCInternal
*internal
;
2230 internal
= (IMCCInternal
*) imcc
;
2232 return internal
->dwSize
;
2235 /***********************************************************************
2236 * ImmGenerateMessage(IMM32.@)
2238 BOOL WINAPI
ImmGenerateMessage(HIMC hIMC
)
2240 InputContextData
*data
= (InputContextData
*)hIMC
;
2242 TRACE("%i messages queued\n",data
->IMC
.dwNumMsgBuf
);
2243 if (data
->IMC
.dwNumMsgBuf
> 0)
2245 LPTRANSMSG lpTransMsg
;
2248 lpTransMsg
= (LPTRANSMSG
)ImmLockIMCC(data
->IMC
.hMsgBuf
);
2249 for (i
= 0; i
< data
->IMC
.dwNumMsgBuf
; i
++)
2250 ImmInternalPostIMEMessage(data
, lpTransMsg
[i
].message
, lpTransMsg
[i
].wParam
, lpTransMsg
[i
].lParam
);
2252 ImmUnlockIMCC(data
->IMC
.hMsgBuf
);
2254 data
->IMC
.dwNumMsgBuf
= 0;
2260 /***********************************************************************
2261 * ImmTranslateMessage(IMM32.@)
2262 * ( Undocumented, call internally and from user32.dll )
2264 BOOL WINAPI
ImmTranslateMessage(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lKeyData
)
2266 InputContextData
*data
;
2267 HIMC imc
= ImmGetContext(hwnd
);
2273 static const int list_count
= 10;
2275 TRACE("%p %x %x %x\n",hwnd
, msg
, (UINT
)wParam
, (UINT
)lKeyData
);
2278 data
= (InputContextData
*)imc
;
2282 if (!data
->immKbd
->hIME
|| !data
->immKbd
->pImeToAsciiEx
)
2285 GetKeyboardState(state
);
2286 scancode
= lKeyData
>> 0x10 & 0xff;
2288 list
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, list_count
* sizeof(TRANSMSG
) + sizeof(DWORD
));
2289 ((DWORD
*)list
)[0] = list_count
;
2291 if (data
->immKbd
->imeInfo
.fdwProperty
& IME_PROP_KBD_CHAR_FIRST
)
2295 if (!is_himc_ime_unicode(data
))
2296 ToAscii(data
->lastVK
, scancode
, state
, &chr
, 0);
2298 ToUnicodeEx(data
->lastVK
, scancode
, state
, &chr
, 1, 0, GetKeyboardLayout(0));
2299 uVirtKey
= MAKELONG(data
->lastVK
,chr
);
2302 uVirtKey
= data
->lastVK
;
2304 msg_count
= data
->immKbd
->pImeToAsciiEx(uVirtKey
, scancode
, state
, list
, 0, imc
);
2305 TRACE("%i messages generated\n",msg_count
);
2306 if (msg_count
&& msg_count
<= list_count
)
2309 LPTRANSMSG msgs
= (LPTRANSMSG
)((LPBYTE
)list
+ sizeof(DWORD
));
2311 for (i
= 0; i
< msg_count
; i
++)
2312 ImmInternalPostIMEMessage(data
, msgs
[i
].message
, msgs
[i
].wParam
, msgs
[i
].lParam
);
2314 else if (msg_count
> list_count
)
2315 ImmGenerateMessage(imc
);
2317 HeapFree(GetProcessHeap(),0,list
);
2319 data
->lastVK
= VK_PROCESSKEY
;
2321 return (msg_count
> 0);
2324 /***********************************************************************
2325 * ImmProcessKey(IMM32.@)
2326 * ( Undocumented, called from user32.dll )
2328 BOOL WINAPI
ImmProcessKey(HWND hwnd
, HKL hKL
, UINT vKey
, LPARAM lKeyData
, DWORD unknown
)
2330 InputContextData
*data
;
2331 HIMC imc
= ImmGetContext(hwnd
);
2334 TRACE("%p %p %x %x %x\n",hwnd
, hKL
, vKey
, (UINT
)lKeyData
, unknown
);
2337 data
= (InputContextData
*)imc
;
2341 if (!data
->immKbd
->hIME
|| !data
->immKbd
->pImeProcessKey
)
2344 GetKeyboardState(state
);
2345 if (data
->immKbd
->pImeProcessKey(imc
, vKey
, lKeyData
, state
))
2347 data
->lastVK
= vKey
;
2351 data
->lastVK
= VK_PROCESSKEY
;