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
34 #include "wine/debug.h"
39 #include "wine/list.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(imm
);
43 #define IMM_INIT_MAGIC 0x19650412
44 BOOL WINAPI
User32InitializeImmEntryTable(DWORD
);
47 static UINT WM_MSIME_SERVICE
;
48 static UINT WM_MSIME_RECONVERTOPTIONS
;
49 static UINT WM_MSIME_MOUSE
;
50 static UINT WM_MSIME_RECONVERTREQUEST
;
51 static UINT WM_MSIME_RECONVERT
;
52 static UINT WM_MSIME_QUERYPOSITION
;
53 static UINT WM_MSIME_DOCUMENTFEED
;
55 typedef struct _tagImmHkl
{
60 WCHAR imeClassName
[17]; /* 16 character max */
64 /* Function Pointers */
65 BOOL (WINAPI
*pImeInquire
)(IMEINFO
*, WCHAR
*, const WCHAR
*);
66 BOOL (WINAPI
*pImeConfigure
)(HKL
, HWND
, DWORD
, void *);
67 BOOL (WINAPI
*pImeDestroy
)(UINT
);
68 LRESULT (WINAPI
*pImeEscape
)(HIMC
, UINT
, void *);
69 BOOL (WINAPI
*pImeSelect
)(HIMC
, BOOL
);
70 BOOL (WINAPI
*pImeSetActiveContext
)(HIMC
, BOOL
);
71 UINT (WINAPI
*pImeToAsciiEx
)(UINT
, UINT
, const BYTE
*, DWORD
*, UINT
, HIMC
);
72 BOOL (WINAPI
*pNotifyIME
)(HIMC
, DWORD
, DWORD
, DWORD
);
73 BOOL (WINAPI
*pImeRegisterWord
)(const WCHAR
*, DWORD
, const WCHAR
*);
74 BOOL (WINAPI
*pImeUnregisterWord
)(const WCHAR
*, DWORD
, const WCHAR
*);
75 UINT (WINAPI
*pImeEnumRegisterWord
)(REGISTERWORDENUMPROCW
, const WCHAR
*, DWORD
, const WCHAR
*, void *);
76 BOOL (WINAPI
*pImeSetCompositionString
)(HIMC
, DWORD
, const void *, DWORD
, const void *, DWORD
);
77 DWORD (WINAPI
*pImeConversionList
)(HIMC
, const WCHAR
*, CANDIDATELIST
*, DWORD
, UINT
);
78 BOOL (WINAPI
*pImeProcessKey
)(HIMC
, UINT
, LPARAM
, const BYTE
*);
79 UINT (WINAPI
*pImeGetRegisterWordStyle
)(UINT
, STYLEBUFW
*);
80 DWORD (WINAPI
*pImeGetImeMenuItems
)(HIMC
, DWORD
, DWORD
, IMEMENUITEMINFOW
*, IMEMENUITEMINFOW
*, DWORD
);
83 typedef struct tagInputContextData
95 #define WINE_IMC_VALID_MAGIC 0x56434D49
97 typedef struct _tagTRANSMSG
{
101 } TRANSMSG
, *LPTRANSMSG
;
105 IInitializeSpy IInitializeSpy_iface
;
107 ULARGE_INTEGER cookie
;
111 IMM_APT_CREATED
= 0x2,
112 IMM_APT_CAN_FREE
= 0x4,
117 static struct list ImmHklList
= LIST_INIT(ImmHklList
);
119 static const WCHAR szImeRegFmt
[] = L
"System\\CurrentControlSet\\Control\\Keyboard Layouts\\%08lx";
121 static inline BOOL
is_himc_ime_unicode(const InputContextData
*data
)
123 return !!(data
->immKbd
->imeInfo
.fdwProperty
& IME_PROP_UNICODE
);
126 static inline BOOL
is_kbd_ime_unicode(const ImmHkl
*hkl
)
128 return !!(hkl
->imeInfo
.fdwProperty
& IME_PROP_UNICODE
);
131 static BOOL
IMM_DestroyContext(HIMC hIMC
);
132 static InputContextData
* get_imc_data(HIMC hIMC
);
134 static inline WCHAR
*strdupAtoW( const char *str
)
139 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
140 if ((ret
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
141 MultiByteToWideChar( CP_ACP
, 0, str
, -1, ret
, len
);
146 static inline CHAR
*strdupWtoA( const WCHAR
*str
)
151 DWORD len
= WideCharToMultiByte( CP_ACP
, 0, str
, -1, NULL
, 0, NULL
, NULL
);
152 if ((ret
= HeapAlloc( GetProcessHeap(), 0, len
)))
153 WideCharToMultiByte( CP_ACP
, 0, str
, -1, ret
, len
, NULL
, NULL
);
158 static DWORD
convert_candidatelist_WtoA(
159 LPCANDIDATELIST lpSrc
, LPCANDIDATELIST lpDst
, DWORD dwBufLen
)
163 ret
= FIELD_OFFSET( CANDIDATELIST
, dwOffset
[lpSrc
->dwCount
] );
164 if ( lpDst
&& dwBufLen
> 0 )
167 lpDst
->dwOffset
[0] = ret
;
170 for ( i
= 0; i
< lpSrc
->dwCount
; i
++)
172 LPBYTE src
= (LPBYTE
)lpSrc
+ lpSrc
->dwOffset
[i
];
174 if ( lpDst
&& dwBufLen
> 0 )
176 LPBYTE dest
= (LPBYTE
)lpDst
+ lpDst
->dwOffset
[i
];
178 len
= WideCharToMultiByte(CP_ACP
, 0, (LPCWSTR
)src
, -1,
179 (LPSTR
)dest
, dwBufLen
, NULL
, NULL
);
181 if ( i
+ 1 < lpSrc
->dwCount
)
182 lpDst
->dwOffset
[i
+1] = lpDst
->dwOffset
[i
] + len
* sizeof(char);
183 dwBufLen
-= len
* sizeof(char);
186 len
= WideCharToMultiByte(CP_ACP
, 0, (LPCWSTR
)src
, -1, NULL
, 0, NULL
, NULL
);
188 ret
+= len
* sizeof(char);
197 static DWORD
convert_candidatelist_AtoW(
198 LPCANDIDATELIST lpSrc
, LPCANDIDATELIST lpDst
, DWORD dwBufLen
)
202 ret
= FIELD_OFFSET( CANDIDATELIST
, dwOffset
[lpSrc
->dwCount
] );
203 if ( lpDst
&& dwBufLen
> 0 )
206 lpDst
->dwOffset
[0] = ret
;
209 for ( i
= 0; i
< lpSrc
->dwCount
; i
++)
211 LPBYTE src
= (LPBYTE
)lpSrc
+ lpSrc
->dwOffset
[i
];
213 if ( lpDst
&& dwBufLen
> 0 )
215 LPBYTE dest
= (LPBYTE
)lpDst
+ lpDst
->dwOffset
[i
];
217 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)src
, -1,
218 (LPWSTR
)dest
, dwBufLen
);
220 if ( i
+ 1 < lpSrc
->dwCount
)
221 lpDst
->dwOffset
[i
+1] = lpDst
->dwOffset
[i
] + len
* sizeof(WCHAR
);
222 dwBufLen
-= len
* sizeof(WCHAR
);
225 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)src
, -1, NULL
, 0);
227 ret
+= len
* sizeof(WCHAR
);
236 static struct coinit_spy
*get_thread_coinit_spy(void)
238 return (struct coinit_spy
*)(UINT_PTR
)NtUserGetThreadInfo()->client_imm
;
241 static void imm_couninit_thread(BOOL cleanup
)
243 struct coinit_spy
*spy
;
245 TRACE("implicit COM deinitialization\n");
247 if (!(spy
= get_thread_coinit_spy()) || (spy
->apt_flags
& IMM_APT_BROKEN
))
250 if (cleanup
&& spy
->cookie
.QuadPart
)
252 CoRevokeInitializeSpy(spy
->cookie
);
253 spy
->cookie
.QuadPart
= 0;
256 if (!(spy
->apt_flags
& IMM_APT_INIT
))
258 spy
->apt_flags
&= ~IMM_APT_INIT
;
260 if (spy
->apt_flags
& IMM_APT_CREATED
)
262 spy
->apt_flags
&= ~IMM_APT_CREATED
;
263 if (spy
->apt_flags
& IMM_APT_CAN_FREE
)
270 static inline struct coinit_spy
*impl_from_IInitializeSpy(IInitializeSpy
*iface
)
272 return CONTAINING_RECORD(iface
, struct coinit_spy
, IInitializeSpy_iface
);
275 static HRESULT WINAPI
InitializeSpy_QueryInterface(IInitializeSpy
*iface
, REFIID riid
, void **obj
)
277 if (IsEqualIID(&IID_IInitializeSpy
, riid
) ||
278 IsEqualIID(&IID_IUnknown
, riid
))
281 IInitializeSpy_AddRef(iface
);
286 return E_NOINTERFACE
;
289 static ULONG WINAPI
InitializeSpy_AddRef(IInitializeSpy
*iface
)
291 struct coinit_spy
*spy
= impl_from_IInitializeSpy(iface
);
292 return InterlockedIncrement(&spy
->ref
);
295 static ULONG WINAPI
InitializeSpy_Release(IInitializeSpy
*iface
)
297 struct coinit_spy
*spy
= impl_from_IInitializeSpy(iface
);
298 LONG ref
= InterlockedDecrement(&spy
->ref
);
301 HeapFree(GetProcessHeap(), 0, spy
);
302 NtUserGetThreadInfo()->client_imm
= 0;
307 static HRESULT WINAPI
InitializeSpy_PreInitialize(IInitializeSpy
*iface
,
308 DWORD coinit
, DWORD refs
)
310 struct coinit_spy
*spy
= impl_from_IInitializeSpy(iface
);
312 if ((spy
->apt_flags
& IMM_APT_CREATED
) &&
313 !(coinit
& COINIT_APARTMENTTHREADED
) && refs
== 1)
315 imm_couninit_thread(TRUE
);
316 spy
->apt_flags
|= IMM_APT_BROKEN
;
321 static HRESULT WINAPI
InitializeSpy_PostInitialize(IInitializeSpy
*iface
,
322 HRESULT hr
, DWORD coinit
, DWORD refs
)
324 struct coinit_spy
*spy
= impl_from_IInitializeSpy(iface
);
326 if ((spy
->apt_flags
& IMM_APT_CREATED
) && hr
== S_FALSE
&& refs
== 2)
329 spy
->apt_flags
|= IMM_APT_CAN_FREE
;
333 static HRESULT WINAPI
InitializeSpy_PreUninitialize(IInitializeSpy
*iface
, DWORD refs
)
338 static HRESULT WINAPI
InitializeSpy_PostUninitialize(IInitializeSpy
*iface
, DWORD refs
)
340 struct coinit_spy
*spy
= impl_from_IInitializeSpy(iface
);
342 TRACE("%lu %p\n", refs
, ImmGetDefaultIMEWnd(0));
344 if (refs
== 1 && !ImmGetDefaultIMEWnd(0))
345 imm_couninit_thread(FALSE
);
347 spy
->apt_flags
&= ~IMM_APT_CAN_FREE
;
351 static const IInitializeSpyVtbl InitializeSpyVtbl
=
353 InitializeSpy_QueryInterface
,
354 InitializeSpy_AddRef
,
355 InitializeSpy_Release
,
356 InitializeSpy_PreInitialize
,
357 InitializeSpy_PostInitialize
,
358 InitializeSpy_PreUninitialize
,
359 InitializeSpy_PostUninitialize
,
362 static void imm_coinit_thread(void)
364 struct coinit_spy
*spy
;
367 TRACE("implicit COM initialization\n");
369 if (!(spy
= get_thread_coinit_spy()))
371 if (!(spy
= HeapAlloc(GetProcessHeap(), 0, sizeof(*spy
)))) return;
372 spy
->IInitializeSpy_iface
.lpVtbl
= &InitializeSpyVtbl
;
374 spy
->cookie
.QuadPart
= 0;
376 NtUserGetThreadInfo()->client_imm
= (UINT_PTR
)spy
;
380 if (spy
->apt_flags
& (IMM_APT_INIT
| IMM_APT_BROKEN
))
382 spy
->apt_flags
|= IMM_APT_INIT
;
384 if(!spy
->cookie
.QuadPart
)
386 hr
= CoRegisterInitializeSpy(&spy
->IInitializeSpy_iface
, &spy
->cookie
);
391 hr
= CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
393 spy
->apt_flags
|= IMM_APT_CREATED
;
396 static BOOL
IMM_IsDefaultContext(HIMC imc
)
398 InputContextData
*data
= get_imc_data(imc
);
403 return data
->threadDefault
;
406 static InputContextData
*query_imc_data(HIMC handle
)
408 InputContextData
*ret
;
410 if (!handle
) return NULL
;
411 ret
= (void *)NtUserQueryInputContext(handle
, NtUserInputContextClientPtr
);
412 return ret
&& ret
->handle
== handle
? ret
: NULL
;
415 static BOOL
free_input_context_data(HIMC hIMC
)
417 InputContextData
*data
= query_imc_data(hIMC
);
422 TRACE("Destroying %p\n", hIMC
);
424 data
->immKbd
->uSelected
--;
425 data
->immKbd
->pImeSelect(hIMC
, FALSE
);
426 SendMessageW(data
->IMC
.hWnd
, WM_IME_SELECT
, FALSE
, (LPARAM
)data
->immKbd
);
428 ImmDestroyIMCC(data
->IMC
.hCompStr
);
429 ImmDestroyIMCC(data
->IMC
.hCandInfo
);
430 ImmDestroyIMCC(data
->IMC
.hGuideLine
);
431 ImmDestroyIMCC(data
->IMC
.hPrivate
);
432 ImmDestroyIMCC(data
->IMC
.hMsgBuf
);
434 HeapFree(GetProcessHeap(), 0, data
);
439 static void IMM_FreeThreadData(void)
441 struct coinit_spy
*spy
;
443 free_input_context_data(UlongToHandle(NtUserGetThreadInfo()->default_imc
));
444 if ((spy
= get_thread_coinit_spy()))
445 IInitializeSpy_Release(&spy
->IInitializeSpy_iface
);
448 static HMODULE
load_graphics_driver(void)
450 static const WCHAR key_pathW
[] = L
"System\\CurrentControlSet\\Control\\Video\\{";
451 static const WCHAR displayW
[] = L
"}\\0000";
456 WCHAR path
[MAX_PATH
];
457 WCHAR key
[ARRAY_SIZE( key_pathW
) + ARRAY_SIZE( displayW
) + 40];
458 UINT guid_atom
= HandleToULong( GetPropW( GetDesktopWindow(), L
"__wine_display_device_guid" ));
460 if (!guid_atom
) return 0;
461 memcpy( key
, key_pathW
, sizeof(key_pathW
) );
462 if (!GlobalGetAtomNameW( guid_atom
, key
+ lstrlenW(key
), 40 )) return 0;
463 lstrcatW( key
, displayW
);
464 if (RegOpenKeyW( HKEY_LOCAL_MACHINE
, key
, &hkey
)) return 0;
466 if (!RegQueryValueExW( hkey
, L
"GraphicsDriver", NULL
, NULL
, (BYTE
*)path
, &size
))
467 ret
= LoadLibraryW( path
);
469 TRACE( "%s %p\n", debugstr_w(path
), ret
);
473 /* ImmHkl loading and freeing */
474 #define LOAD_FUNCPTR(f) if((ptr->p##f = (LPVOID)GetProcAddress(ptr->hIME, #f)) == NULL){WARN("Can't find function %s in ime\n", #f);}
475 static ImmHkl
*IMM_GetImmHkl(HKL hkl
)
478 WCHAR filename
[MAX_PATH
];
480 TRACE("Seeking ime for keyboard %p\n",hkl
);
482 LIST_FOR_EACH_ENTRY(ptr
, &ImmHklList
, ImmHkl
, entry
)
487 /* not found... create it */
489 ptr
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ImmHkl
));
492 if (ImmGetIMEFileNameW(hkl
, filename
, MAX_PATH
)) ptr
->hIME
= LoadLibraryW(filename
);
493 if (!ptr
->hIME
) ptr
->hIME
= load_graphics_driver();
496 LOAD_FUNCPTR(ImeInquire
);
497 if (!ptr
->pImeInquire
|| !ptr
->pImeInquire(&ptr
->imeInfo
, ptr
->imeClassName
, NULL
))
499 FreeLibrary(ptr
->hIME
);
504 LOAD_FUNCPTR(ImeDestroy
);
505 LOAD_FUNCPTR(ImeSelect
);
506 if (!ptr
->pImeSelect
|| !ptr
->pImeDestroy
)
508 FreeLibrary(ptr
->hIME
);
513 LOAD_FUNCPTR(ImeConfigure
);
514 LOAD_FUNCPTR(ImeEscape
);
515 LOAD_FUNCPTR(ImeSetActiveContext
);
516 LOAD_FUNCPTR(ImeToAsciiEx
);
517 LOAD_FUNCPTR(NotifyIME
);
518 LOAD_FUNCPTR(ImeRegisterWord
);
519 LOAD_FUNCPTR(ImeUnregisterWord
);
520 LOAD_FUNCPTR(ImeEnumRegisterWord
);
521 LOAD_FUNCPTR(ImeSetCompositionString
);
522 LOAD_FUNCPTR(ImeConversionList
);
523 LOAD_FUNCPTR(ImeProcessKey
);
524 LOAD_FUNCPTR(ImeGetRegisterWordStyle
);
525 LOAD_FUNCPTR(ImeGetImeMenuItems
);
526 /* make sure our classname is WCHAR */
527 if (!is_kbd_ime_unicode(ptr
))
530 MultiByteToWideChar(CP_ACP
, 0, (LPSTR
)ptr
->imeClassName
,
532 lstrcpyW(ptr
->imeClassName
, bufW
);
537 list_add_head(&ImmHklList
,&ptr
->entry
);
544 static void IMM_FreeAllImmHkl(void)
546 ImmHkl
*ptr
,*cursor2
;
548 LIST_FOR_EACH_ENTRY_SAFE(ptr
, cursor2
, &ImmHklList
, ImmHkl
, entry
)
550 list_remove(&ptr
->entry
);
554 FreeLibrary(ptr
->hIME
);
557 DestroyWindow(ptr
->UIWnd
);
558 HeapFree(GetProcessHeap(),0,ptr
);
562 BOOL WINAPI
DllMain(HINSTANCE hInstDLL
, DWORD fdwReason
, LPVOID lpReserved
)
564 TRACE("%p, %lx, %p\n",hInstDLL
,fdwReason
,lpReserved
);
567 case DLL_PROCESS_ATTACH
:
568 if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC
))
573 case DLL_THREAD_ATTACH
:
575 case DLL_THREAD_DETACH
:
576 IMM_FreeThreadData();
578 case DLL_PROCESS_DETACH
:
579 if (lpReserved
) break;
580 IMM_FreeThreadData();
587 /* for posting messages as the IME */
588 static void ImmInternalPostIMEMessage(InputContextData
*data
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
590 HWND target
= GetFocus();
592 PostMessageW(data
->IMC
.hWnd
,msg
,wParam
,lParam
);
594 PostMessageW(target
, msg
, wParam
, lParam
);
597 /* for sending messages as the IME */
598 static void ImmInternalSendIMEMessage(InputContextData
*data
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
600 HWND target
= GetFocus();
602 SendMessageW(data
->IMC
.hWnd
,msg
,wParam
,lParam
);
604 SendMessageW(target
, msg
, wParam
, lParam
);
607 static LRESULT
ImmInternalSendIMENotify(InputContextData
*data
, WPARAM notify
, LPARAM lParam
)
611 target
= data
->IMC
.hWnd
;
612 if (!target
) target
= GetFocus();
615 return SendMessageW(target
, WM_IME_NOTIFY
, notify
, lParam
);
620 static HIMCC
ImmCreateBlankCompStr(void)
623 LPCOMPOSITIONSTRING ptr
;
624 rc
= ImmCreateIMCC(sizeof(COMPOSITIONSTRING
));
625 ptr
= ImmLockIMCC(rc
);
626 memset(ptr
,0,sizeof(COMPOSITIONSTRING
));
627 ptr
->dwSize
= sizeof(COMPOSITIONSTRING
);
632 static BOOL
IMM_IsCrossThreadAccess(HWND hWnd
, HIMC hIMC
)
634 InputContextData
*data
;
638 DWORD thread
= GetWindowThreadProcessId(hWnd
, NULL
);
639 if (thread
!= GetCurrentThreadId()) return TRUE
;
641 data
= get_imc_data(hIMC
);
642 if (data
&& data
->threadID
!= GetCurrentThreadId())
648 /***********************************************************************
649 * ImmSetActiveContext (IMM32.@)
651 BOOL WINAPI
ImmSetActiveContext(HWND hwnd
, HIMC himc
, BOOL activate
)
653 InputContextData
*data
= get_imc_data(himc
);
655 TRACE("(%p, %p, %x)\n", hwnd
, himc
, activate
);
657 if (himc
&& !data
&& activate
)
664 data
->IMC
.hWnd
= activate
? hwnd
: NULL
;
666 if (data
->immKbd
->hIME
&& data
->immKbd
->pImeSetActiveContext
)
667 data
->immKbd
->pImeSetActiveContext(himc
, activate
);
672 SendMessageW(hwnd
, WM_IME_SETCONTEXT
, activate
, ISC_SHOWUIALL
);
673 /* TODO: send WM_IME_NOTIFY */
679 /***********************************************************************
680 * ImmAssociateContext (IMM32.@)
682 HIMC WINAPI
ImmAssociateContext(HWND hwnd
, HIMC imc
)
687 TRACE("(%p, %p):\n", hwnd
, imc
);
689 old
= NtUserGetWindowInputContext(hwnd
);
690 ret
= NtUserAssociateInputContext(hwnd
, imc
, 0);
691 if (ret
== AICR_FOCUS_CHANGED
)
693 ImmSetActiveContext(hwnd
, old
, FALSE
);
694 ImmSetActiveContext(hwnd
, imc
, TRUE
);
696 return ret
== AICR_FAILED
? 0 : old
;
701 * Helper function for ImmAssociateContextEx
703 static BOOL CALLBACK
_ImmAssociateContextExEnumProc(HWND hwnd
, LPARAM lParam
)
705 HIMC hImc
= (HIMC
)lParam
;
706 ImmAssociateContext(hwnd
,hImc
);
710 /***********************************************************************
711 * ImmAssociateContextEx (IMM32.@)
713 BOOL WINAPI
ImmAssociateContextEx(HWND hwnd
, HIMC imc
, DWORD flags
)
718 TRACE("(%p, %p, 0x%lx):\n", hwnd
, imc
, flags
);
723 if (flags
== IACE_CHILDREN
)
725 EnumChildWindows(hwnd
, _ImmAssociateContextExEnumProc
, (LPARAM
)imc
);
729 old
= NtUserGetWindowInputContext(hwnd
);
730 ret
= NtUserAssociateInputContext(hwnd
, imc
, flags
);
731 if (ret
== AICR_FOCUS_CHANGED
)
733 ImmSetActiveContext(hwnd
, old
, FALSE
);
734 ImmSetActiveContext(hwnd
, imc
, TRUE
);
736 return ret
!= AICR_FAILED
;
739 /***********************************************************************
740 * ImmConfigureIMEA (IMM32.@)
742 BOOL WINAPI
ImmConfigureIMEA(
743 HKL hKL
, HWND hWnd
, DWORD dwMode
, LPVOID lpData
)
745 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
747 TRACE("(%p, %p, %ld, %p):\n", hKL
, hWnd
, dwMode
, lpData
);
749 if (dwMode
== IME_CONFIG_REGISTERWORD
&& !lpData
)
752 if (immHkl
->hIME
&& immHkl
->pImeConfigure
)
754 if (dwMode
!= IME_CONFIG_REGISTERWORD
|| !is_kbd_ime_unicode(immHkl
))
755 return immHkl
->pImeConfigure(hKL
,hWnd
,dwMode
,lpData
);
759 REGISTERWORDA
*rwa
= lpData
;
762 rww
.lpReading
= strdupAtoW(rwa
->lpReading
);
763 rww
.lpWord
= strdupAtoW(rwa
->lpWord
);
764 rc
= immHkl
->pImeConfigure(hKL
,hWnd
,dwMode
,&rww
);
765 HeapFree(GetProcessHeap(),0,rww
.lpReading
);
766 HeapFree(GetProcessHeap(),0,rww
.lpWord
);
774 /***********************************************************************
775 * ImmConfigureIMEW (IMM32.@)
777 BOOL WINAPI
ImmConfigureIMEW(
778 HKL hKL
, HWND hWnd
, DWORD dwMode
, LPVOID lpData
)
780 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
782 TRACE("(%p, %p, %ld, %p):\n", hKL
, hWnd
, dwMode
, lpData
);
784 if (dwMode
== IME_CONFIG_REGISTERWORD
&& !lpData
)
787 if (immHkl
->hIME
&& immHkl
->pImeConfigure
)
789 if (dwMode
!= IME_CONFIG_REGISTERWORD
|| is_kbd_ime_unicode(immHkl
))
790 return immHkl
->pImeConfigure(hKL
,hWnd
,dwMode
,lpData
);
793 REGISTERWORDW
*rww
= lpData
;
797 rwa
.lpReading
= strdupWtoA(rww
->lpReading
);
798 rwa
.lpWord
= strdupWtoA(rww
->lpWord
);
799 rc
= immHkl
->pImeConfigure(hKL
,hWnd
,dwMode
,&rwa
);
800 HeapFree(GetProcessHeap(),0,rwa
.lpReading
);
801 HeapFree(GetProcessHeap(),0,rwa
.lpWord
);
809 static InputContextData
*create_input_context(HIMC default_imc
)
811 InputContextData
*new_context
;
816 new_context
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(InputContextData
));
819 new_context
->threadDefault
= !!default_imc
;
820 new_context
->immKbd
= IMM_GetImmHkl(GetKeyboardLayout(0));
822 if (!new_context
->immKbd
->hIME
)
824 TRACE("IME dll could not be loaded\n");
825 HeapFree(GetProcessHeap(),0,new_context
);
829 /* the HIMCCs are never NULL */
830 new_context
->IMC
.hCompStr
= ImmCreateBlankCompStr();
831 new_context
->IMC
.hMsgBuf
= ImmCreateIMCC(0);
832 new_context
->IMC
.hCandInfo
= ImmCreateIMCC(sizeof(CANDIDATEINFO
));
833 ci
= ImmLockIMCC(new_context
->IMC
.hCandInfo
);
834 memset(ci
,0,sizeof(CANDIDATEINFO
));
835 ci
->dwSize
= sizeof(CANDIDATEINFO
);
836 ImmUnlockIMCC(new_context
->IMC
.hCandInfo
);
837 new_context
->IMC
.hGuideLine
= ImmCreateIMCC(sizeof(GUIDELINE
));
838 gl
= ImmLockIMCC(new_context
->IMC
.hGuideLine
);
839 memset(gl
,0,sizeof(GUIDELINE
));
840 gl
->dwSize
= sizeof(GUIDELINE
);
841 ImmUnlockIMCC(new_context
->IMC
.hGuideLine
);
843 for (i
= 0; i
< ARRAY_SIZE(new_context
->IMC
.cfCandForm
); i
++)
844 new_context
->IMC
.cfCandForm
[i
].dwIndex
= ~0u;
846 /* Initialize the IME Private */
847 new_context
->IMC
.hPrivate
= ImmCreateIMCC(new_context
->immKbd
->imeInfo
.dwPrivateDataSize
);
849 new_context
->IMC
.fdwConversion
= new_context
->immKbd
->imeInfo
.fdwConversionCaps
;
850 new_context
->IMC
.fdwSentence
= new_context
->immKbd
->imeInfo
.fdwSentenceCaps
;
853 new_context
->handle
= NtUserCreateInputContext((UINT_PTR
)new_context
);
854 else if (NtUserUpdateInputContext(default_imc
, NtUserInputContextClientPtr
, (UINT_PTR
)new_context
))
855 new_context
->handle
= default_imc
;
856 if (!new_context
->handle
)
858 free_input_context_data(new_context
);
862 if (!new_context
->immKbd
->pImeSelect(new_context
->handle
, TRUE
))
864 TRACE("Selection of IME failed\n");
865 IMM_DestroyContext(new_context
);
868 new_context
->threadID
= GetCurrentThreadId();
869 SendMessageW(GetFocus(), WM_IME_SELECT
, TRUE
, (LPARAM
)new_context
->immKbd
);
871 new_context
->immKbd
->uSelected
++;
872 TRACE("Created context %p\n", new_context
);
876 static InputContextData
* get_imc_data(HIMC handle
)
878 InputContextData
*ret
;
880 if ((ret
= query_imc_data(handle
)) || !handle
) return ret
;
881 return create_input_context(handle
);
884 /***********************************************************************
885 * ImmCreateContext (IMM32.@)
887 HIMC WINAPI
ImmCreateContext(void)
889 InputContextData
*new_context
;
891 if (!(new_context
= create_input_context(0))) return 0;
892 return new_context
->handle
;
895 static BOOL
IMM_DestroyContext(HIMC hIMC
)
897 if (!free_input_context_data(hIMC
)) return FALSE
;
898 NtUserDestroyInputContext(hIMC
);
902 /***********************************************************************
903 * ImmDestroyContext (IMM32.@)
905 BOOL WINAPI
ImmDestroyContext(HIMC hIMC
)
907 if (!IMM_IsDefaultContext(hIMC
) && !IMM_IsCrossThreadAccess(NULL
, hIMC
))
908 return IMM_DestroyContext(hIMC
);
913 /***********************************************************************
914 * ImmEnumRegisterWordA (IMM32.@)
916 UINT WINAPI
ImmEnumRegisterWordA(
917 HKL hKL
, REGISTERWORDENUMPROCA lpfnEnumProc
,
918 LPCSTR lpszReading
, DWORD dwStyle
,
919 LPCSTR lpszRegister
, LPVOID lpData
)
921 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
922 TRACE("(%p, %p, %s, %ld, %s, %p):\n", hKL
, lpfnEnumProc
,
923 debugstr_a(lpszReading
), dwStyle
, debugstr_a(lpszRegister
), lpData
);
924 if (immHkl
->hIME
&& immHkl
->pImeEnumRegisterWord
)
926 if (!is_kbd_ime_unicode(immHkl
))
927 return immHkl
->pImeEnumRegisterWord((REGISTERWORDENUMPROCW
)lpfnEnumProc
,
928 (LPCWSTR
)lpszReading
, dwStyle
, (LPCWSTR
)lpszRegister
, lpData
);
931 LPWSTR lpszwReading
= strdupAtoW(lpszReading
);
932 LPWSTR lpszwRegister
= strdupAtoW(lpszRegister
);
935 rc
= immHkl
->pImeEnumRegisterWord((REGISTERWORDENUMPROCW
)lpfnEnumProc
,
936 lpszwReading
, dwStyle
, lpszwRegister
,
939 HeapFree(GetProcessHeap(),0,lpszwReading
);
940 HeapFree(GetProcessHeap(),0,lpszwRegister
);
948 /***********************************************************************
949 * ImmEnumRegisterWordW (IMM32.@)
951 UINT WINAPI
ImmEnumRegisterWordW(
952 HKL hKL
, REGISTERWORDENUMPROCW lpfnEnumProc
,
953 LPCWSTR lpszReading
, DWORD dwStyle
,
954 LPCWSTR lpszRegister
, LPVOID lpData
)
956 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
957 TRACE("(%p, %p, %s, %ld, %s, %p):\n", hKL
, lpfnEnumProc
,
958 debugstr_w(lpszReading
), dwStyle
, debugstr_w(lpszRegister
), lpData
);
959 if (immHkl
->hIME
&& immHkl
->pImeEnumRegisterWord
)
961 if (is_kbd_ime_unicode(immHkl
))
962 return immHkl
->pImeEnumRegisterWord(lpfnEnumProc
, lpszReading
, dwStyle
,
963 lpszRegister
, lpData
);
966 LPSTR lpszaReading
= strdupWtoA(lpszReading
);
967 LPSTR lpszaRegister
= strdupWtoA(lpszRegister
);
970 rc
= immHkl
->pImeEnumRegisterWord(lpfnEnumProc
, (LPCWSTR
)lpszaReading
,
971 dwStyle
, (LPCWSTR
)lpszaRegister
, lpData
);
973 HeapFree(GetProcessHeap(),0,lpszaReading
);
974 HeapFree(GetProcessHeap(),0,lpszaRegister
);
982 static inline BOOL
EscapeRequiresWA(UINT uEscape
)
984 if (uEscape
== IME_ESC_GET_EUDC_DICTIONARY
||
985 uEscape
== IME_ESC_SET_EUDC_DICTIONARY
||
986 uEscape
== IME_ESC_IME_NAME
||
987 uEscape
== IME_ESC_GETHELPFILENAME
)
992 /***********************************************************************
993 * ImmEscapeA (IMM32.@)
995 LRESULT WINAPI
ImmEscapeA(
997 UINT uEscape
, LPVOID lpData
)
999 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1000 TRACE("(%p, %p, %d, %p):\n", hKL
, hIMC
, uEscape
, lpData
);
1002 if (immHkl
->hIME
&& immHkl
->pImeEscape
)
1004 if (!EscapeRequiresWA(uEscape
) || !is_kbd_ime_unicode(immHkl
))
1005 return immHkl
->pImeEscape(hIMC
,uEscape
,lpData
);
1008 WCHAR buffer
[81]; /* largest required buffer should be 80 */
1010 if (uEscape
== IME_ESC_SET_EUDC_DICTIONARY
)
1012 MultiByteToWideChar(CP_ACP
,0,lpData
,-1,buffer
,81);
1013 rc
= immHkl
->pImeEscape(hIMC
,uEscape
,buffer
);
1017 rc
= immHkl
->pImeEscape(hIMC
,uEscape
,buffer
);
1018 WideCharToMultiByte(CP_ACP
,0,buffer
,-1,lpData
,80, NULL
, NULL
);
1027 /***********************************************************************
1028 * ImmEscapeW (IMM32.@)
1030 LRESULT WINAPI
ImmEscapeW(
1032 UINT uEscape
, LPVOID lpData
)
1034 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1035 TRACE("(%p, %p, %d, %p):\n", hKL
, hIMC
, uEscape
, lpData
);
1037 if (immHkl
->hIME
&& immHkl
->pImeEscape
)
1039 if (!EscapeRequiresWA(uEscape
) || is_kbd_ime_unicode(immHkl
))
1040 return immHkl
->pImeEscape(hIMC
,uEscape
,lpData
);
1043 CHAR buffer
[81]; /* largest required buffer should be 80 */
1045 if (uEscape
== IME_ESC_SET_EUDC_DICTIONARY
)
1047 WideCharToMultiByte(CP_ACP
,0,lpData
,-1,buffer
,81, NULL
, NULL
);
1048 rc
= immHkl
->pImeEscape(hIMC
,uEscape
,buffer
);
1052 rc
= immHkl
->pImeEscape(hIMC
,uEscape
,buffer
);
1053 MultiByteToWideChar(CP_ACP
,0,buffer
,-1,lpData
,80);
1062 /***********************************************************************
1063 * ImmGetCandidateListA (IMM32.@)
1065 DWORD WINAPI
ImmGetCandidateListA(
1066 HIMC hIMC
, DWORD dwIndex
,
1067 LPCANDIDATELIST lpCandList
, DWORD dwBufLen
)
1069 InputContextData
*data
= get_imc_data(hIMC
);
1070 LPCANDIDATEINFO candinfo
;
1071 LPCANDIDATELIST candlist
;
1074 TRACE("%p, %ld, %p, %ld\n", hIMC
, dwIndex
, lpCandList
, dwBufLen
);
1076 if (!data
|| !data
->IMC
.hCandInfo
)
1079 candinfo
= ImmLockIMCC(data
->IMC
.hCandInfo
);
1080 if (dwIndex
>= candinfo
->dwCount
|| dwIndex
>= ARRAY_SIZE(candinfo
->dwOffset
))
1083 candlist
= (LPCANDIDATELIST
)((LPBYTE
)candinfo
+ candinfo
->dwOffset
[dwIndex
]);
1084 if ( !candlist
->dwSize
|| !candlist
->dwCount
)
1087 if ( !is_himc_ime_unicode(data
) )
1089 ret
= candlist
->dwSize
;
1090 if ( lpCandList
&& dwBufLen
>= ret
)
1091 memcpy(lpCandList
, candlist
, ret
);
1094 ret
= convert_candidatelist_WtoA( candlist
, lpCandList
, dwBufLen
);
1097 ImmUnlockIMCC(data
->IMC
.hCandInfo
);
1101 /***********************************************************************
1102 * ImmGetCandidateListCountA (IMM32.@)
1104 DWORD WINAPI
ImmGetCandidateListCountA(
1105 HIMC hIMC
, LPDWORD lpdwListCount
)
1107 InputContextData
*data
= get_imc_data(hIMC
);
1108 LPCANDIDATEINFO candinfo
;
1111 TRACE("%p, %p\n", hIMC
, lpdwListCount
);
1113 if (!data
|| !lpdwListCount
|| !data
->IMC
.hCandInfo
)
1116 candinfo
= ImmLockIMCC(data
->IMC
.hCandInfo
);
1118 *lpdwListCount
= count
= candinfo
->dwCount
;
1120 if ( !is_himc_ime_unicode(data
) )
1121 ret
= candinfo
->dwSize
;
1124 ret
= sizeof(CANDIDATEINFO
);
1126 ret
+= ImmGetCandidateListA(hIMC
, count
, NULL
, 0);
1129 ImmUnlockIMCC(data
->IMC
.hCandInfo
);
1133 /***********************************************************************
1134 * ImmGetCandidateListCountW (IMM32.@)
1136 DWORD WINAPI
ImmGetCandidateListCountW(
1137 HIMC hIMC
, LPDWORD lpdwListCount
)
1139 InputContextData
*data
= get_imc_data(hIMC
);
1140 LPCANDIDATEINFO candinfo
;
1143 TRACE("%p, %p\n", hIMC
, lpdwListCount
);
1145 if (!data
|| !lpdwListCount
|| !data
->IMC
.hCandInfo
)
1148 candinfo
= ImmLockIMCC(data
->IMC
.hCandInfo
);
1150 *lpdwListCount
= count
= candinfo
->dwCount
;
1152 if ( is_himc_ime_unicode(data
) )
1153 ret
= candinfo
->dwSize
;
1156 ret
= sizeof(CANDIDATEINFO
);
1158 ret
+= ImmGetCandidateListW(hIMC
, count
, NULL
, 0);
1161 ImmUnlockIMCC(data
->IMC
.hCandInfo
);
1165 /***********************************************************************
1166 * ImmGetCandidateListW (IMM32.@)
1168 DWORD WINAPI
ImmGetCandidateListW(
1169 HIMC hIMC
, DWORD dwIndex
,
1170 LPCANDIDATELIST lpCandList
, DWORD dwBufLen
)
1172 InputContextData
*data
= get_imc_data(hIMC
);
1173 LPCANDIDATEINFO candinfo
;
1174 LPCANDIDATELIST candlist
;
1177 TRACE("%p, %ld, %p, %ld\n", hIMC
, dwIndex
, lpCandList
, dwBufLen
);
1179 if (!data
|| !data
->IMC
.hCandInfo
)
1182 candinfo
= ImmLockIMCC(data
->IMC
.hCandInfo
);
1183 if (dwIndex
>= candinfo
->dwCount
|| dwIndex
>= ARRAY_SIZE(candinfo
->dwOffset
))
1186 candlist
= (LPCANDIDATELIST
)((LPBYTE
)candinfo
+ candinfo
->dwOffset
[dwIndex
]);
1187 if ( !candlist
->dwSize
|| !candlist
->dwCount
)
1190 if ( is_himc_ime_unicode(data
) )
1192 ret
= candlist
->dwSize
;
1193 if ( lpCandList
&& dwBufLen
>= ret
)
1194 memcpy(lpCandList
, candlist
, ret
);
1197 ret
= convert_candidatelist_AtoW( candlist
, lpCandList
, dwBufLen
);
1200 ImmUnlockIMCC(data
->IMC
.hCandInfo
);
1204 /***********************************************************************
1205 * ImmGetCandidateWindow (IMM32.@)
1207 BOOL WINAPI
ImmGetCandidateWindow(
1208 HIMC hIMC
, DWORD dwIndex
, LPCANDIDATEFORM lpCandidate
)
1210 InputContextData
*data
= get_imc_data(hIMC
);
1212 TRACE("%p, %ld, %p\n", hIMC
, dwIndex
, lpCandidate
);
1214 if (!data
|| !lpCandidate
)
1217 if (dwIndex
>= ARRAY_SIZE(data
->IMC
.cfCandForm
))
1220 if (data
->IMC
.cfCandForm
[dwIndex
].dwIndex
!= dwIndex
)
1223 *lpCandidate
= data
->IMC
.cfCandForm
[dwIndex
];
1228 /***********************************************************************
1229 * ImmGetCompositionFontA (IMM32.@)
1231 BOOL WINAPI
ImmGetCompositionFontA(HIMC hIMC
, LPLOGFONTA lplf
)
1236 TRACE("(%p, %p):\n", hIMC
, lplf
);
1238 rc
= ImmGetCompositionFontW(hIMC
,&lfW
);
1242 memcpy(lplf
,&lfW
,sizeof(LOGFONTA
));
1243 WideCharToMultiByte(CP_ACP
, 0, lfW
.lfFaceName
, -1, lplf
->lfFaceName
,
1244 LF_FACESIZE
, NULL
, NULL
);
1248 /***********************************************************************
1249 * ImmGetCompositionFontW (IMM32.@)
1251 BOOL WINAPI
ImmGetCompositionFontW(HIMC hIMC
, LPLOGFONTW lplf
)
1253 InputContextData
*data
= get_imc_data(hIMC
);
1255 TRACE("(%p, %p):\n", hIMC
, lplf
);
1260 *lplf
= data
->IMC
.lfFont
.W
;
1266 /* Helpers for the GetCompositionString functions */
1268 /* Source encoding is defined by context, source length is always given in respective characters. Destination buffer
1269 length is always in bytes. */
1270 static INT
CopyCompStringIMEtoClient(const InputContextData
*data
, const void *src
, INT src_len
, void *dst
,
1271 INT dst_len
, BOOL unicode
)
1273 int char_size
= unicode
? sizeof(WCHAR
) : sizeof(char);
1276 if (is_himc_ime_unicode(data
) ^ unicode
)
1279 ret
= MultiByteToWideChar(CP_ACP
, 0, src
, src_len
, dst
, dst_len
/ sizeof(WCHAR
));
1281 ret
= WideCharToMultiByte(CP_ACP
, 0, src
, src_len
, dst
, dst_len
, NULL
, NULL
);
1288 ret
= min(src_len
* char_size
, dst_len
);
1289 memcpy(dst
, src
, ret
);
1292 ret
= src_len
* char_size
;
1298 /* Composition string encoding is defined by context, returned attributes correspond to string, converted according to
1299 passed mode. String length is in characters, attributes are in byte arrays. */
1300 static INT
CopyCompAttrIMEtoClient(const InputContextData
*data
, const BYTE
*src
, INT src_len
, const void *comp_string
,
1301 INT str_len
, BYTE
*dst
, INT dst_len
, BOOL unicode
)
1311 string
.str
= comp_string
;
1313 if (is_himc_ime_unicode(data
) && !unicode
)
1315 rc
= WideCharToMultiByte(CP_ACP
, 0, string
.strW
, str_len
, NULL
, 0, NULL
, NULL
);
1318 int i
, j
= 0, k
= 0;
1322 for (i
= 0; i
< str_len
; ++i
)
1326 len
= WideCharToMultiByte(CP_ACP
, 0, string
.strW
+ i
, 1, NULL
, 0, NULL
, NULL
);
1327 for (; len
> 0; --len
)
1340 else if (!is_himc_ime_unicode(data
) && unicode
)
1342 rc
= MultiByteToWideChar(CP_ACP
, 0, string
.strA
, str_len
, NULL
, 0);
1349 for (i
= 0; i
< str_len
; ++i
)
1351 if (IsDBCSLeadByte(string
.strA
[i
]))
1364 memcpy(dst
, src
, min(src_len
, dst_len
));
1371 static INT
CopyCompClauseIMEtoClient(InputContextData
*data
, LPBYTE source
, INT slen
, LPBYTE ssource
,
1372 LPBYTE target
, INT tlen
, BOOL unicode
)
1376 if (is_himc_ime_unicode(data
) && !unicode
)
1384 tlen
/= sizeof (DWORD
);
1385 for (i
= 0; i
< tlen
; ++i
)
1387 ((DWORD
*)target
)[i
] = WideCharToMultiByte(CP_ACP
, 0, (LPWSTR
)ssource
,
1388 ((DWORD
*)source
)[i
],
1392 rc
= sizeof (DWORD
) * i
;
1397 else if (!is_himc_ime_unicode(data
) && unicode
)
1405 tlen
/= sizeof (DWORD
);
1406 for (i
= 0; i
< tlen
; ++i
)
1408 ((DWORD
*)target
)[i
] = MultiByteToWideChar(CP_ACP
, 0, (LPSTR
)ssource
,
1409 ((DWORD
*)source
)[i
],
1412 rc
= sizeof (DWORD
) * i
;
1419 memcpy( target
, source
, min(slen
,tlen
));
1426 static INT
CopyCompOffsetIMEtoClient(InputContextData
*data
, DWORD offset
, LPBYTE ssource
, BOOL unicode
)
1430 if (is_himc_ime_unicode(data
) && !unicode
)
1432 rc
= WideCharToMultiByte(CP_ACP
, 0, (LPWSTR
)ssource
, offset
, NULL
, 0, NULL
, NULL
);
1434 else if (!is_himc_ime_unicode(data
) && unicode
)
1436 rc
= MultiByteToWideChar(CP_ACP
, 0, (LPSTR
)ssource
, offset
, NULL
, 0);
1444 static LONG
ImmGetCompositionStringT( HIMC hIMC
, DWORD dwIndex
, LPVOID lpBuf
,
1445 DWORD dwBufLen
, BOOL unicode
)
1448 InputContextData
*data
= get_imc_data(hIMC
);
1449 LPCOMPOSITIONSTRING compstr
;
1452 TRACE("(%p, 0x%lx, %p, %ld)\n", hIMC
, dwIndex
, lpBuf
, dwBufLen
);
1457 if (!data
->IMC
.hCompStr
)
1460 compdata
= ImmLockIMCC(data
->IMC
.hCompStr
);
1461 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
1466 TRACE("GCS_RESULTSTR\n");
1467 rc
= CopyCompStringIMEtoClient(data
, compdata
+ compstr
->dwResultStrOffset
, compstr
->dwResultStrLen
, lpBuf
, dwBufLen
, unicode
);
1470 TRACE("GCS_COMPSTR\n");
1471 rc
= CopyCompStringIMEtoClient(data
, compdata
+ compstr
->dwCompStrOffset
, compstr
->dwCompStrLen
, lpBuf
, dwBufLen
, unicode
);
1474 TRACE("GCS_COMPATTR\n");
1475 rc
= CopyCompAttrIMEtoClient(data
, compdata
+ compstr
->dwCompAttrOffset
, compstr
->dwCompAttrLen
,
1476 compdata
+ compstr
->dwCompStrOffset
, compstr
->dwCompStrLen
,
1477 lpBuf
, dwBufLen
, unicode
);
1479 case GCS_COMPCLAUSE
:
1480 TRACE("GCS_COMPCLAUSE\n");
1481 rc
= CopyCompClauseIMEtoClient(data
, compdata
+ compstr
->dwCompClauseOffset
,compstr
->dwCompClauseLen
,
1482 compdata
+ compstr
->dwCompStrOffset
,
1483 lpBuf
, dwBufLen
, unicode
);
1485 case GCS_RESULTCLAUSE
:
1486 TRACE("GCS_RESULTCLAUSE\n");
1487 rc
= CopyCompClauseIMEtoClient(data
, compdata
+ compstr
->dwResultClauseOffset
,compstr
->dwResultClauseLen
,
1488 compdata
+ compstr
->dwResultStrOffset
,
1489 lpBuf
, dwBufLen
, unicode
);
1491 case GCS_RESULTREADSTR
:
1492 TRACE("GCS_RESULTREADSTR\n");
1493 rc
= CopyCompStringIMEtoClient(data
, compdata
+ compstr
->dwResultReadStrOffset
, compstr
->dwResultReadStrLen
, lpBuf
, dwBufLen
, unicode
);
1495 case GCS_RESULTREADCLAUSE
:
1496 TRACE("GCS_RESULTREADCLAUSE\n");
1497 rc
= CopyCompClauseIMEtoClient(data
, compdata
+ compstr
->dwResultReadClauseOffset
,compstr
->dwResultReadClauseLen
,
1498 compdata
+ compstr
->dwResultStrOffset
,
1499 lpBuf
, dwBufLen
, unicode
);
1501 case GCS_COMPREADSTR
:
1502 TRACE("GCS_COMPREADSTR\n");
1503 rc
= CopyCompStringIMEtoClient(data
, compdata
+ compstr
->dwCompReadStrOffset
, compstr
->dwCompReadStrLen
, lpBuf
, dwBufLen
, unicode
);
1505 case GCS_COMPREADATTR
:
1506 TRACE("GCS_COMPREADATTR\n");
1507 rc
= CopyCompAttrIMEtoClient(data
, compdata
+ compstr
->dwCompReadAttrOffset
, compstr
->dwCompReadAttrLen
,
1508 compdata
+ compstr
->dwCompReadStrOffset
, compstr
->dwCompReadStrLen
,
1509 lpBuf
, dwBufLen
, unicode
);
1511 case GCS_COMPREADCLAUSE
:
1512 TRACE("GCS_COMPREADCLAUSE\n");
1513 rc
= CopyCompClauseIMEtoClient(data
, compdata
+ compstr
->dwCompReadClauseOffset
,compstr
->dwCompReadClauseLen
,
1514 compdata
+ compstr
->dwCompStrOffset
,
1515 lpBuf
, dwBufLen
, unicode
);
1518 TRACE("GCS_CURSORPOS\n");
1519 rc
= CopyCompOffsetIMEtoClient(data
, compstr
->dwCursorPos
, compdata
+ compstr
->dwCompStrOffset
, unicode
);
1521 case GCS_DELTASTART
:
1522 TRACE("GCS_DELTASTART\n");
1523 rc
= CopyCompOffsetIMEtoClient(data
, compstr
->dwDeltaStart
, compdata
+ compstr
->dwCompStrOffset
, unicode
);
1526 FIXME("Unhandled index 0x%lx\n",dwIndex
);
1530 ImmUnlockIMCC(data
->IMC
.hCompStr
);
1535 /***********************************************************************
1536 * ImmGetCompositionStringA (IMM32.@)
1538 LONG WINAPI
ImmGetCompositionStringA(
1539 HIMC hIMC
, DWORD dwIndex
, LPVOID lpBuf
, DWORD dwBufLen
)
1541 return ImmGetCompositionStringT(hIMC
, dwIndex
, lpBuf
, dwBufLen
, FALSE
);
1545 /***********************************************************************
1546 * ImmGetCompositionStringW (IMM32.@)
1548 LONG WINAPI
ImmGetCompositionStringW(
1549 HIMC hIMC
, DWORD dwIndex
,
1550 LPVOID lpBuf
, DWORD dwBufLen
)
1552 return ImmGetCompositionStringT(hIMC
, dwIndex
, lpBuf
, dwBufLen
, TRUE
);
1555 /***********************************************************************
1556 * ImmGetCompositionWindow (IMM32.@)
1558 BOOL WINAPI
ImmGetCompositionWindow(HIMC hIMC
, LPCOMPOSITIONFORM lpCompForm
)
1560 InputContextData
*data
= get_imc_data(hIMC
);
1562 TRACE("(%p, %p)\n", hIMC
, lpCompForm
);
1567 *lpCompForm
= data
->IMC
.cfCompForm
;
1571 /***********************************************************************
1572 * ImmGetContext (IMM32.@)
1575 HIMC WINAPI
ImmGetContext(HWND hWnd
)
1579 TRACE("%p\n", hWnd
);
1581 rc
= NtUserGetWindowInputContext(hWnd
);
1585 InputContextData
*data
= get_imc_data(rc
);
1586 if (data
) data
->IMC
.hWnd
= hWnd
;
1590 TRACE("returning %p\n", rc
);
1595 /***********************************************************************
1596 * ImmGetConversionListA (IMM32.@)
1598 DWORD WINAPI
ImmGetConversionListA(
1600 LPCSTR pSrc
, LPCANDIDATELIST lpDst
,
1601 DWORD dwBufLen
, UINT uFlag
)
1603 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1604 TRACE("(%p, %p, %s, %p, %ld, %d):\n", hKL
, hIMC
, debugstr_a(pSrc
), lpDst
,
1606 if (immHkl
->hIME
&& immHkl
->pImeConversionList
)
1608 if (!is_kbd_ime_unicode(immHkl
))
1609 return immHkl
->pImeConversionList(hIMC
,(LPCWSTR
)pSrc
,lpDst
,dwBufLen
,uFlag
);
1612 LPCANDIDATELIST lpwDst
;
1614 LPWSTR pwSrc
= strdupAtoW(pSrc
);
1616 len
= immHkl
->pImeConversionList(hIMC
, pwSrc
, NULL
, 0, uFlag
);
1617 lpwDst
= HeapAlloc(GetProcessHeap(), 0, len
);
1620 immHkl
->pImeConversionList(hIMC
, pwSrc
, lpwDst
, len
, uFlag
);
1621 ret
= convert_candidatelist_WtoA( lpwDst
, lpDst
, dwBufLen
);
1622 HeapFree(GetProcessHeap(), 0, lpwDst
);
1624 HeapFree(GetProcessHeap(), 0, pwSrc
);
1633 /***********************************************************************
1634 * ImmGetConversionListW (IMM32.@)
1636 DWORD WINAPI
ImmGetConversionListW(
1638 LPCWSTR pSrc
, LPCANDIDATELIST lpDst
,
1639 DWORD dwBufLen
, UINT uFlag
)
1641 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1642 TRACE("(%p, %p, %s, %p, %ld, %d):\n", hKL
, hIMC
, debugstr_w(pSrc
), lpDst
,
1644 if (immHkl
->hIME
&& immHkl
->pImeConversionList
)
1646 if (is_kbd_ime_unicode(immHkl
))
1647 return immHkl
->pImeConversionList(hIMC
,pSrc
,lpDst
,dwBufLen
,uFlag
);
1650 LPCANDIDATELIST lpaDst
;
1652 LPSTR paSrc
= strdupWtoA(pSrc
);
1654 len
= immHkl
->pImeConversionList(hIMC
, (LPCWSTR
)paSrc
, NULL
, 0, uFlag
);
1655 lpaDst
= HeapAlloc(GetProcessHeap(), 0, len
);
1658 immHkl
->pImeConversionList(hIMC
, (LPCWSTR
)paSrc
, lpaDst
, len
, uFlag
);
1659 ret
= convert_candidatelist_AtoW( lpaDst
, lpDst
, dwBufLen
);
1660 HeapFree(GetProcessHeap(), 0, lpaDst
);
1662 HeapFree(GetProcessHeap(), 0, paSrc
);
1671 /***********************************************************************
1672 * ImmGetConversionStatus (IMM32.@)
1674 BOOL WINAPI
ImmGetConversionStatus(
1675 HIMC hIMC
, LPDWORD lpfdwConversion
, LPDWORD lpfdwSentence
)
1677 InputContextData
*data
= get_imc_data(hIMC
);
1679 TRACE("%p %p %p\n", hIMC
, lpfdwConversion
, lpfdwSentence
);
1684 if (lpfdwConversion
)
1685 *lpfdwConversion
= data
->IMC
.fdwConversion
;
1687 *lpfdwSentence
= data
->IMC
.fdwSentence
;
1692 /***********************************************************************
1693 * ImmGetDefaultIMEWnd (IMM32.@)
1695 HWND WINAPI
ImmGetDefaultIMEWnd(HWND hWnd
)
1697 return NtUserGetDefaultImeWindow(hWnd
);
1700 /***********************************************************************
1701 * ImmGetDescriptionA (IMM32.@)
1703 UINT WINAPI
ImmGetDescriptionA(
1704 HKL hKL
, LPSTR lpszDescription
, UINT uBufLen
)
1709 TRACE("%p %p %d\n", hKL
, lpszDescription
, uBufLen
);
1711 /* find out how many characters in the unicode buffer */
1712 len
= ImmGetDescriptionW( hKL
, NULL
, 0 );
1716 /* allocate a buffer of that size */
1717 buf
= HeapAlloc( GetProcessHeap(), 0, (len
+ 1) * sizeof (WCHAR
) );
1721 /* fetch the unicode buffer */
1722 len
= ImmGetDescriptionW( hKL
, buf
, len
+ 1 );
1724 /* convert it back to ANSI */
1725 len
= WideCharToMultiByte( CP_ACP
, 0, buf
, len
+ 1,
1726 lpszDescription
, uBufLen
, NULL
, NULL
);
1728 HeapFree( GetProcessHeap(), 0, buf
);
1736 /***********************************************************************
1737 * ImmGetDescriptionW (IMM32.@)
1739 UINT WINAPI
ImmGetDescriptionW(HKL hKL
, LPWSTR lpszDescription
, UINT uBufLen
)
1741 FIXME("(%p, %p, %d): semi stub\n", hKL
, lpszDescription
, uBufLen
);
1744 if (!uBufLen
) return lstrlenW(L
"Wine XIM" );
1745 lstrcpynW( lpszDescription
, L
"Wine XIM", uBufLen
);
1746 return lstrlenW( lpszDescription
);
1749 /***********************************************************************
1750 * ImmGetGuideLineA (IMM32.@)
1752 DWORD WINAPI
ImmGetGuideLineA(
1753 HIMC hIMC
, DWORD dwIndex
, LPSTR lpBuf
, DWORD dwBufLen
)
1755 FIXME("(%p, %ld, %s, %ld): stub\n",
1756 hIMC
, dwIndex
, debugstr_a(lpBuf
), dwBufLen
1758 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1762 /***********************************************************************
1763 * ImmGetGuideLineW (IMM32.@)
1765 DWORD WINAPI
ImmGetGuideLineW(HIMC hIMC
, DWORD dwIndex
, LPWSTR lpBuf
, DWORD dwBufLen
)
1767 FIXME("(%p, %ld, %s, %ld): stub\n",
1768 hIMC
, dwIndex
, debugstr_w(lpBuf
), dwBufLen
1770 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1774 /***********************************************************************
1775 * ImmGetIMEFileNameA (IMM32.@)
1777 UINT WINAPI
ImmGetIMEFileNameA( HKL hKL
, LPSTR lpszFileName
, UINT uBufLen
)
1780 UINT wBufLen
= uBufLen
;
1783 if (uBufLen
&& lpszFileName
)
1784 bufW
= HeapAlloc(GetProcessHeap(),0,uBufLen
* sizeof(WCHAR
));
1785 else /* We need this to get the number of byte required */
1787 bufW
= HeapAlloc(GetProcessHeap(),0,MAX_PATH
* sizeof(WCHAR
));
1791 rc
= ImmGetIMEFileNameW(hKL
,bufW
,wBufLen
);
1795 if (uBufLen
&& lpszFileName
)
1796 rc
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, lpszFileName
,
1797 uBufLen
, NULL
, NULL
);
1798 else /* get the length */
1799 rc
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
,
1803 HeapFree(GetProcessHeap(),0,bufW
);
1807 /***********************************************************************
1808 * ImmGetIMEFileNameW (IMM32.@)
1810 UINT WINAPI
ImmGetIMEFileNameW(HKL hKL
, LPWSTR lpszFileName
, UINT uBufLen
)
1815 WCHAR regKey
[ARRAY_SIZE(szImeRegFmt
)+8];
1817 wsprintfW( regKey
, szImeRegFmt
, (ULONG_PTR
)hKL
);
1818 rc
= RegOpenKeyW( HKEY_LOCAL_MACHINE
, regKey
, &hkey
);
1819 if (rc
!= ERROR_SUCCESS
)
1826 rc
= RegGetValueW(hkey
, NULL
, L
"Ime File", RRF_RT_REG_SZ
, NULL
, NULL
, &length
);
1828 if (rc
!= ERROR_SUCCESS
)
1834 if (length
> uBufLen
* sizeof(WCHAR
) || !lpszFileName
)
1839 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1843 return length
/ sizeof(WCHAR
);
1846 RegGetValueW(hkey
, NULL
, L
"Ime File", RRF_RT_REG_SZ
, NULL
, lpszFileName
, &length
);
1850 return length
/ sizeof(WCHAR
);
1853 /***********************************************************************
1854 * ImmGetOpenStatus (IMM32.@)
1856 BOOL WINAPI
ImmGetOpenStatus(HIMC hIMC
)
1858 InputContextData
*data
= get_imc_data(hIMC
);
1864 TRACE("(%p): semi-stub\n", hIMC
);
1867 FIXME("(%p): semi-stub\n", hIMC
);
1869 return data
->IMC
.fOpen
;
1872 /***********************************************************************
1873 * ImmGetProperty (IMM32.@)
1875 DWORD WINAPI
ImmGetProperty(HKL hKL
, DWORD fdwIndex
)
1880 TRACE("(%p, %ld)\n", hKL
, fdwIndex
);
1881 kbd
= IMM_GetImmHkl(hKL
);
1883 if (kbd
&& kbd
->hIME
)
1887 case IGP_PROPERTY
: rc
= kbd
->imeInfo
.fdwProperty
; break;
1888 case IGP_CONVERSION
: rc
= kbd
->imeInfo
.fdwConversionCaps
; break;
1889 case IGP_SENTENCE
: rc
= kbd
->imeInfo
.fdwSentenceCaps
; break;
1890 case IGP_SETCOMPSTR
: rc
= kbd
->imeInfo
.fdwSCSCaps
; break;
1891 case IGP_SELECT
: rc
= kbd
->imeInfo
.fdwSelectCaps
; break;
1892 case IGP_GETIMEVERSION
: rc
= IMEVER_0400
; break;
1893 case IGP_UI
: rc
= 0; break;
1900 /***********************************************************************
1901 * ImmGetRegisterWordStyleA (IMM32.@)
1903 UINT WINAPI
ImmGetRegisterWordStyleA(
1904 HKL hKL
, UINT nItem
, LPSTYLEBUFA lpStyleBuf
)
1906 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1907 TRACE("(%p, %d, %p):\n", hKL
, nItem
, lpStyleBuf
);
1908 if (immHkl
->hIME
&& immHkl
->pImeGetRegisterWordStyle
)
1910 if (!is_kbd_ime_unicode(immHkl
))
1911 return immHkl
->pImeGetRegisterWordStyle(nItem
,(LPSTYLEBUFW
)lpStyleBuf
);
1917 rc
= immHkl
->pImeGetRegisterWordStyle(nItem
,&sbw
);
1918 WideCharToMultiByte(CP_ACP
, 0, sbw
.szDescription
, -1,
1919 lpStyleBuf
->szDescription
, 32, NULL
, NULL
);
1920 lpStyleBuf
->dwStyle
= sbw
.dwStyle
;
1928 /***********************************************************************
1929 * ImmGetRegisterWordStyleW (IMM32.@)
1931 UINT WINAPI
ImmGetRegisterWordStyleW(
1932 HKL hKL
, UINT nItem
, LPSTYLEBUFW lpStyleBuf
)
1934 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
1935 TRACE("(%p, %d, %p):\n", hKL
, nItem
, lpStyleBuf
);
1936 if (immHkl
->hIME
&& immHkl
->pImeGetRegisterWordStyle
)
1938 if (is_kbd_ime_unicode(immHkl
))
1939 return immHkl
->pImeGetRegisterWordStyle(nItem
,lpStyleBuf
);
1945 rc
= immHkl
->pImeGetRegisterWordStyle(nItem
,(LPSTYLEBUFW
)&sba
);
1946 MultiByteToWideChar(CP_ACP
, 0, sba
.szDescription
, -1,
1947 lpStyleBuf
->szDescription
, 32);
1948 lpStyleBuf
->dwStyle
= sba
.dwStyle
;
1956 /***********************************************************************
1957 * ImmGetStatusWindowPos (IMM32.@)
1959 BOOL WINAPI
ImmGetStatusWindowPos(HIMC hIMC
, LPPOINT lpptPos
)
1961 InputContextData
*data
= get_imc_data(hIMC
);
1963 TRACE("(%p, %p)\n", hIMC
, lpptPos
);
1965 if (!data
|| !lpptPos
)
1968 *lpptPos
= data
->IMC
.ptStatusWndPos
;
1973 /***********************************************************************
1974 * ImmGetVirtualKey (IMM32.@)
1976 UINT WINAPI
ImmGetVirtualKey(HWND hWnd
)
1978 OSVERSIONINFOA version
;
1979 InputContextData
*data
= get_imc_data( ImmGetContext( hWnd
));
1980 TRACE("%p\n", hWnd
);
1983 return data
->lastVK
;
1985 version
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
1986 GetVersionExA( &version
);
1987 switch(version
.dwPlatformId
)
1989 case VER_PLATFORM_WIN32_WINDOWS
:
1990 return VK_PROCESSKEY
;
1991 case VER_PLATFORM_WIN32_NT
:
1994 FIXME("%ld not supported\n",version
.dwPlatformId
);
1995 return VK_PROCESSKEY
;
1999 /***********************************************************************
2000 * ImmInstallIMEA (IMM32.@)
2002 HKL WINAPI
ImmInstallIMEA(
2003 LPCSTR lpszIMEFileName
, LPCSTR lpszLayoutText
)
2005 LPWSTR lpszwIMEFileName
;
2006 LPWSTR lpszwLayoutText
;
2009 TRACE ("(%s, %s)\n", debugstr_a(lpszIMEFileName
),
2010 debugstr_a(lpszLayoutText
));
2012 lpszwIMEFileName
= strdupAtoW(lpszIMEFileName
);
2013 lpszwLayoutText
= strdupAtoW(lpszLayoutText
);
2015 hkl
= ImmInstallIMEW(lpszwIMEFileName
, lpszwLayoutText
);
2017 HeapFree(GetProcessHeap(),0,lpszwIMEFileName
);
2018 HeapFree(GetProcessHeap(),0,lpszwLayoutText
);
2022 /***********************************************************************
2023 * ImmInstallIMEW (IMM32.@)
2025 HKL WINAPI
ImmInstallIMEW(
2026 LPCWSTR lpszIMEFileName
, LPCWSTR lpszLayoutText
)
2028 INT lcid
= GetUserDefaultLCID();
2033 WCHAR regKey
[ARRAY_SIZE(szImeRegFmt
)+8];
2035 TRACE ("(%s, %s):\n", debugstr_w(lpszIMEFileName
),
2036 debugstr_w(lpszLayoutText
));
2038 /* Start with 2. e001 will be blank and so default to the wine internal IME */
2041 while (count
< 0xfff)
2043 DWORD disposition
= 0;
2045 hkl
= (HKL
)MAKELPARAM( lcid
, 0xe000 | count
);
2046 wsprintfW( regKey
, szImeRegFmt
, (ULONG_PTR
)hkl
);
2048 rc
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, regKey
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hkey
, &disposition
);
2049 if (rc
== ERROR_SUCCESS
&& disposition
== REG_CREATED_NEW_KEY
)
2051 else if (rc
== ERROR_SUCCESS
)
2059 WARN("Unable to find slot to install IME\n");
2063 if (rc
== ERROR_SUCCESS
)
2065 rc
= RegSetValueExW(hkey
, L
"Ime File", 0, REG_SZ
, (const BYTE
*)lpszIMEFileName
,
2066 (lstrlenW(lpszIMEFileName
) + 1) * sizeof(WCHAR
));
2067 if (rc
== ERROR_SUCCESS
)
2068 rc
= RegSetValueExW(hkey
, L
"Layout Text", 0, REG_SZ
, (const BYTE
*)lpszLayoutText
,
2069 (lstrlenW(lpszLayoutText
) + 1) * sizeof(WCHAR
));
2075 WARN("Unable to set IME registry values\n");
2080 /***********************************************************************
2081 * ImmIsIME (IMM32.@)
2083 BOOL WINAPI
ImmIsIME(HKL hKL
)
2086 TRACE("(%p):\n", hKL
);
2087 ptr
= IMM_GetImmHkl(hKL
);
2088 return (ptr
&& ptr
->hIME
);
2091 /***********************************************************************
2092 * ImmIsUIMessageA (IMM32.@)
2094 BOOL WINAPI
ImmIsUIMessageA(
2095 HWND hWndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2097 TRACE("(%p, %x, %Id, %Id)\n", hWndIME
, msg
, wParam
, lParam
);
2098 if ((msg
>= WM_IME_STARTCOMPOSITION
&& msg
<= WM_IME_KEYLAST
) ||
2099 (msg
== WM_IME_SETCONTEXT
) ||
2100 (msg
== WM_IME_NOTIFY
) ||
2101 (msg
== WM_IME_COMPOSITIONFULL
) ||
2102 (msg
== WM_IME_SELECT
) ||
2103 (msg
== 0x287 /* FIXME: WM_IME_SYSTEM */))
2106 SendMessageA(hWndIME
, msg
, wParam
, lParam
);
2113 /***********************************************************************
2114 * ImmIsUIMessageW (IMM32.@)
2116 BOOL WINAPI
ImmIsUIMessageW(
2117 HWND hWndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2119 TRACE("(%p, %x, %Id, %Id)\n", hWndIME
, msg
, wParam
, lParam
);
2120 if ((msg
>= WM_IME_STARTCOMPOSITION
&& msg
<= WM_IME_KEYLAST
) ||
2121 (msg
== WM_IME_SETCONTEXT
) ||
2122 (msg
== WM_IME_NOTIFY
) ||
2123 (msg
== WM_IME_COMPOSITIONFULL
) ||
2124 (msg
== WM_IME_SELECT
) ||
2125 (msg
== 0x287 /* FIXME: WM_IME_SYSTEM */))
2128 SendMessageW(hWndIME
, msg
, wParam
, lParam
);
2135 /***********************************************************************
2136 * ImmNotifyIME (IMM32.@)
2138 BOOL WINAPI
ImmNotifyIME(
2139 HIMC hIMC
, DWORD dwAction
, DWORD dwIndex
, DWORD dwValue
)
2141 InputContextData
*data
= get_imc_data(hIMC
);
2143 TRACE("(%p, %ld, %ld, %ld)\n",
2144 hIMC
, dwAction
, dwIndex
, dwValue
);
2148 SetLastError(ERROR_SUCCESS
);
2152 if (!data
|| ! data
->immKbd
->pNotifyIME
)
2157 return data
->immKbd
->pNotifyIME(hIMC
,dwAction
,dwIndex
,dwValue
);
2160 /***********************************************************************
2161 * ImmRegisterWordA (IMM32.@)
2163 BOOL WINAPI
ImmRegisterWordA(
2164 HKL hKL
, LPCSTR lpszReading
, DWORD dwStyle
, LPCSTR lpszRegister
)
2166 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
2167 TRACE("(%p, %s, %ld, %s):\n", hKL
, debugstr_a(lpszReading
), dwStyle
,
2168 debugstr_a(lpszRegister
));
2169 if (immHkl
->hIME
&& immHkl
->pImeRegisterWord
)
2171 if (!is_kbd_ime_unicode(immHkl
))
2172 return immHkl
->pImeRegisterWord((LPCWSTR
)lpszReading
,dwStyle
,
2173 (LPCWSTR
)lpszRegister
);
2176 LPWSTR lpszwReading
= strdupAtoW(lpszReading
);
2177 LPWSTR lpszwRegister
= strdupAtoW(lpszRegister
);
2180 rc
= immHkl
->pImeRegisterWord(lpszwReading
,dwStyle
,lpszwRegister
);
2181 HeapFree(GetProcessHeap(),0,lpszwReading
);
2182 HeapFree(GetProcessHeap(),0,lpszwRegister
);
2190 /***********************************************************************
2191 * ImmRegisterWordW (IMM32.@)
2193 BOOL WINAPI
ImmRegisterWordW(
2194 HKL hKL
, LPCWSTR lpszReading
, DWORD dwStyle
, LPCWSTR lpszRegister
)
2196 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
2197 TRACE("(%p, %s, %ld, %s):\n", hKL
, debugstr_w(lpszReading
), dwStyle
,
2198 debugstr_w(lpszRegister
));
2199 if (immHkl
->hIME
&& immHkl
->pImeRegisterWord
)
2201 if (is_kbd_ime_unicode(immHkl
))
2202 return immHkl
->pImeRegisterWord(lpszReading
,dwStyle
,lpszRegister
);
2205 LPSTR lpszaReading
= strdupWtoA(lpszReading
);
2206 LPSTR lpszaRegister
= strdupWtoA(lpszRegister
);
2209 rc
= immHkl
->pImeRegisterWord((LPCWSTR
)lpszaReading
,dwStyle
,
2210 (LPCWSTR
)lpszaRegister
);
2211 HeapFree(GetProcessHeap(),0,lpszaReading
);
2212 HeapFree(GetProcessHeap(),0,lpszaRegister
);
2220 /***********************************************************************
2221 * ImmReleaseContext (IMM32.@)
2223 BOOL WINAPI
ImmReleaseContext(HWND hWnd
, HIMC hIMC
)
2225 static BOOL shown
= FALSE
;
2228 FIXME("(%p, %p): stub\n", hWnd
, hIMC
);
2234 /***********************************************************************
2235 * ImmRequestMessageA(IMM32.@)
2237 LRESULT WINAPI
ImmRequestMessageA(HIMC hIMC
, WPARAM wParam
, LPARAM lParam
)
2239 InputContextData
*data
= get_imc_data(hIMC
);
2241 TRACE("%p %Id %Id\n", hIMC
, wParam
, wParam
);
2243 if (data
) return SendMessageA(data
->IMC
.hWnd
, WM_IME_REQUEST
, wParam
, lParam
);
2245 SetLastError(ERROR_INVALID_HANDLE
);
2249 /***********************************************************************
2250 * ImmRequestMessageW(IMM32.@)
2252 LRESULT WINAPI
ImmRequestMessageW(HIMC hIMC
, WPARAM wParam
, LPARAM lParam
)
2254 InputContextData
*data
= get_imc_data(hIMC
);
2256 TRACE("%p %Id %Id\n", hIMC
, wParam
, wParam
);
2258 if (data
) return SendMessageW(data
->IMC
.hWnd
, WM_IME_REQUEST
, wParam
, lParam
);
2260 SetLastError(ERROR_INVALID_HANDLE
);
2264 /***********************************************************************
2265 * ImmSetCandidateWindow (IMM32.@)
2267 BOOL WINAPI
ImmSetCandidateWindow(
2268 HIMC hIMC
, LPCANDIDATEFORM lpCandidate
)
2270 InputContextData
*data
= get_imc_data(hIMC
);
2272 TRACE("(%p, %p)\n", hIMC
, lpCandidate
);
2274 if (!data
|| !lpCandidate
)
2277 if (IMM_IsCrossThreadAccess(NULL
, hIMC
))
2280 TRACE("\t%lx, %lx, %s, %s\n",
2281 lpCandidate
->dwIndex
, lpCandidate
->dwStyle
,
2282 wine_dbgstr_point(&lpCandidate
->ptCurrentPos
),
2283 wine_dbgstr_rect(&lpCandidate
->rcArea
));
2285 if (lpCandidate
->dwIndex
>= ARRAY_SIZE(data
->IMC
.cfCandForm
))
2288 data
->IMC
.cfCandForm
[lpCandidate
->dwIndex
] = *lpCandidate
;
2289 ImmNotifyIME(hIMC
, NI_CONTEXTUPDATED
, 0, IMC_SETCANDIDATEPOS
);
2290 ImmInternalSendIMENotify(data
, IMN_SETCANDIDATEPOS
, 1 << lpCandidate
->dwIndex
);
2295 /***********************************************************************
2296 * ImmSetCompositionFontA (IMM32.@)
2298 BOOL WINAPI
ImmSetCompositionFontA(HIMC hIMC
, LPLOGFONTA lplf
)
2300 InputContextData
*data
= get_imc_data(hIMC
);
2301 TRACE("(%p, %p)\n", hIMC
, lplf
);
2305 SetLastError(ERROR_INVALID_HANDLE
);
2309 if (IMM_IsCrossThreadAccess(NULL
, hIMC
))
2312 memcpy(&data
->IMC
.lfFont
.W
,lplf
,sizeof(LOGFONTA
));
2313 MultiByteToWideChar(CP_ACP
, 0, lplf
->lfFaceName
, -1, data
->IMC
.lfFont
.W
.lfFaceName
,
2315 ImmNotifyIME(hIMC
, NI_CONTEXTUPDATED
, 0, IMC_SETCOMPOSITIONFONT
);
2316 ImmInternalSendIMENotify(data
, IMN_SETCOMPOSITIONFONT
, 0);
2321 /***********************************************************************
2322 * ImmSetCompositionFontW (IMM32.@)
2324 BOOL WINAPI
ImmSetCompositionFontW(HIMC hIMC
, LPLOGFONTW lplf
)
2326 InputContextData
*data
= get_imc_data(hIMC
);
2327 TRACE("(%p, %p)\n", hIMC
, lplf
);
2331 SetLastError(ERROR_INVALID_HANDLE
);
2335 if (IMM_IsCrossThreadAccess(NULL
, hIMC
))
2338 data
->IMC
.lfFont
.W
= *lplf
;
2339 ImmNotifyIME(hIMC
, NI_CONTEXTUPDATED
, 0, IMC_SETCOMPOSITIONFONT
);
2340 ImmInternalSendIMENotify(data
, IMN_SETCOMPOSITIONFONT
, 0);
2345 /***********************************************************************
2346 * ImmSetCompositionStringA (IMM32.@)
2348 BOOL WINAPI
ImmSetCompositionStringA(
2349 HIMC hIMC
, DWORD dwIndex
,
2350 LPCVOID lpComp
, DWORD dwCompLen
,
2351 LPCVOID lpRead
, DWORD dwReadLen
)
2355 WCHAR
*CompBuffer
= NULL
;
2356 WCHAR
*ReadBuffer
= NULL
;
2358 InputContextData
*data
= get_imc_data(hIMC
);
2360 TRACE("(%p, %ld, %p, %ld, %p, %ld):\n",
2361 hIMC
, dwIndex
, lpComp
, dwCompLen
, lpRead
, dwReadLen
);
2366 if (!(dwIndex
== SCS_SETSTR
||
2367 dwIndex
== SCS_CHANGEATTR
||
2368 dwIndex
== SCS_CHANGECLAUSE
||
2369 dwIndex
== SCS_SETRECONVERTSTRING
||
2370 dwIndex
== SCS_QUERYRECONVERTSTRING
))
2373 if (!is_himc_ime_unicode(data
))
2374 return data
->immKbd
->pImeSetCompositionString(hIMC
, dwIndex
, lpComp
,
2375 dwCompLen
, lpRead
, dwReadLen
);
2377 comp_len
= MultiByteToWideChar(CP_ACP
, 0, lpComp
, dwCompLen
, NULL
, 0);
2380 CompBuffer
= HeapAlloc(GetProcessHeap(),0,comp_len
* sizeof(WCHAR
));
2381 MultiByteToWideChar(CP_ACP
, 0, lpComp
, dwCompLen
, CompBuffer
, comp_len
);
2384 read_len
= MultiByteToWideChar(CP_ACP
, 0, lpRead
, dwReadLen
, NULL
, 0);
2387 ReadBuffer
= HeapAlloc(GetProcessHeap(),0,read_len
* sizeof(WCHAR
));
2388 MultiByteToWideChar(CP_ACP
, 0, lpRead
, dwReadLen
, ReadBuffer
, read_len
);
2391 rc
= ImmSetCompositionStringW(hIMC
, dwIndex
, CompBuffer
, comp_len
,
2392 ReadBuffer
, read_len
);
2394 HeapFree(GetProcessHeap(), 0, CompBuffer
);
2395 HeapFree(GetProcessHeap(), 0, ReadBuffer
);
2400 /***********************************************************************
2401 * ImmSetCompositionStringW (IMM32.@)
2403 BOOL WINAPI
ImmSetCompositionStringW(
2404 HIMC hIMC
, DWORD dwIndex
,
2405 LPCVOID lpComp
, DWORD dwCompLen
,
2406 LPCVOID lpRead
, DWORD dwReadLen
)
2410 CHAR
*CompBuffer
= NULL
;
2411 CHAR
*ReadBuffer
= NULL
;
2413 InputContextData
*data
= get_imc_data(hIMC
);
2415 TRACE("(%p, %ld, %p, %ld, %p, %ld):\n",
2416 hIMC
, dwIndex
, lpComp
, dwCompLen
, lpRead
, dwReadLen
);
2421 if (!(dwIndex
== SCS_SETSTR
||
2422 dwIndex
== SCS_CHANGEATTR
||
2423 dwIndex
== SCS_CHANGECLAUSE
||
2424 dwIndex
== SCS_SETRECONVERTSTRING
||
2425 dwIndex
== SCS_QUERYRECONVERTSTRING
))
2428 if (is_himc_ime_unicode(data
))
2429 return data
->immKbd
->pImeSetCompositionString(hIMC
, dwIndex
, lpComp
,
2430 dwCompLen
, lpRead
, dwReadLen
);
2432 comp_len
= WideCharToMultiByte(CP_ACP
, 0, lpComp
, dwCompLen
, NULL
, 0, NULL
,
2436 CompBuffer
= HeapAlloc(GetProcessHeap(),0,comp_len
);
2437 WideCharToMultiByte(CP_ACP
, 0, lpComp
, dwCompLen
, CompBuffer
, comp_len
,
2441 read_len
= WideCharToMultiByte(CP_ACP
, 0, lpRead
, dwReadLen
, NULL
, 0, NULL
,
2445 ReadBuffer
= HeapAlloc(GetProcessHeap(),0,read_len
);
2446 WideCharToMultiByte(CP_ACP
, 0, lpRead
, dwReadLen
, ReadBuffer
, read_len
,
2450 rc
= ImmSetCompositionStringA(hIMC
, dwIndex
, CompBuffer
, comp_len
,
2451 ReadBuffer
, read_len
);
2453 HeapFree(GetProcessHeap(), 0, CompBuffer
);
2454 HeapFree(GetProcessHeap(), 0, ReadBuffer
);
2459 /***********************************************************************
2460 * ImmSetCompositionWindow (IMM32.@)
2462 BOOL WINAPI
ImmSetCompositionWindow(
2463 HIMC hIMC
, LPCOMPOSITIONFORM lpCompForm
)
2465 BOOL reshow
= FALSE
;
2466 InputContextData
*data
= get_imc_data(hIMC
);
2468 TRACE("(%p, %p)\n", hIMC
, lpCompForm
);
2470 TRACE("\t%lx, %s, %s\n", lpCompForm
->dwStyle
,
2471 wine_dbgstr_point(&lpCompForm
->ptCurrentPos
),
2472 wine_dbgstr_rect(&lpCompForm
->rcArea
));
2476 SetLastError(ERROR_INVALID_HANDLE
);
2480 if (IMM_IsCrossThreadAccess(NULL
, hIMC
))
2483 data
->IMC
.cfCompForm
= *lpCompForm
;
2485 if (IsWindowVisible(data
->immKbd
->UIWnd
))
2488 ShowWindow(data
->immKbd
->UIWnd
,SW_HIDE
);
2491 /* FIXME: this is a partial stub */
2494 ShowWindow(data
->immKbd
->UIWnd
,SW_SHOWNOACTIVATE
);
2496 ImmInternalSendIMENotify(data
, IMN_SETCOMPOSITIONWINDOW
, 0);
2500 /***********************************************************************
2501 * ImmSetConversionStatus (IMM32.@)
2503 BOOL WINAPI
ImmSetConversionStatus(
2504 HIMC hIMC
, DWORD fdwConversion
, DWORD fdwSentence
)
2506 DWORD oldConversion
, oldSentence
;
2507 InputContextData
*data
= get_imc_data(hIMC
);
2509 TRACE("%p %ld %ld\n", hIMC
, fdwConversion
, fdwSentence
);
2513 SetLastError(ERROR_INVALID_HANDLE
);
2517 if (IMM_IsCrossThreadAccess(NULL
, hIMC
))
2520 if ( fdwConversion
!= data
->IMC
.fdwConversion
)
2522 oldConversion
= data
->IMC
.fdwConversion
;
2523 data
->IMC
.fdwConversion
= fdwConversion
;
2524 ImmNotifyIME(hIMC
, NI_CONTEXTUPDATED
, oldConversion
, IMC_SETCONVERSIONMODE
);
2525 ImmInternalSendIMENotify(data
, IMN_SETCONVERSIONMODE
, 0);
2527 if ( fdwSentence
!= data
->IMC
.fdwSentence
)
2529 oldSentence
= data
->IMC
.fdwSentence
;
2530 data
->IMC
.fdwSentence
= fdwSentence
;
2531 ImmNotifyIME(hIMC
, NI_CONTEXTUPDATED
, oldSentence
, IMC_SETSENTENCEMODE
);
2532 ImmInternalSendIMENotify(data
, IMN_SETSENTENCEMODE
, 0);
2538 /***********************************************************************
2539 * ImmSetOpenStatus (IMM32.@)
2541 BOOL WINAPI
ImmSetOpenStatus(HIMC hIMC
, BOOL fOpen
)
2543 InputContextData
*data
= get_imc_data(hIMC
);
2545 TRACE("%p %d\n", hIMC
, fOpen
);
2549 SetLastError(ERROR_INVALID_HANDLE
);
2553 if (IMM_IsCrossThreadAccess(NULL
, hIMC
))
2556 if (data
->immKbd
->UIWnd
== NULL
)
2558 /* create the ime window */
2559 data
->immKbd
->UIWnd
= CreateWindowExW( WS_EX_TOOLWINDOW
,
2560 data
->immKbd
->imeClassName
, NULL
, WS_POPUP
, 0, 0, 1, 1, 0,
2561 0, data
->immKbd
->hIME
, 0);
2562 SetWindowLongPtrW(data
->immKbd
->UIWnd
, IMMGWL_IMC
, (LONG_PTR
)data
);
2565 SetWindowLongPtrW(data
->immKbd
->UIWnd
, IMMGWL_IMC
, (LONG_PTR
)data
);
2567 if (!fOpen
!= !data
->IMC
.fOpen
)
2569 data
->IMC
.fOpen
= fOpen
;
2570 ImmNotifyIME( hIMC
, NI_CONTEXTUPDATED
, 0, IMC_SETOPENSTATUS
);
2571 ImmInternalSendIMENotify(data
, IMN_SETOPENSTATUS
, 0);
2577 /***********************************************************************
2578 * ImmSetStatusWindowPos (IMM32.@)
2580 BOOL WINAPI
ImmSetStatusWindowPos(HIMC hIMC
, LPPOINT lpptPos
)
2582 InputContextData
*data
= get_imc_data(hIMC
);
2584 TRACE("(%p, %p)\n", hIMC
, lpptPos
);
2586 if (!data
|| !lpptPos
)
2588 SetLastError(ERROR_INVALID_HANDLE
);
2592 if (IMM_IsCrossThreadAccess(NULL
, hIMC
))
2595 TRACE("\t%s\n", wine_dbgstr_point(lpptPos
));
2597 data
->IMC
.ptStatusWndPos
= *lpptPos
;
2598 ImmNotifyIME( hIMC
, NI_CONTEXTUPDATED
, 0, IMC_SETSTATUSWINDOWPOS
);
2599 ImmInternalSendIMENotify(data
, IMN_SETSTATUSWINDOWPOS
, 0);
2604 /***********************************************************************
2605 * ImmCreateSoftKeyboard(IMM32.@)
2607 HWND WINAPI
ImmCreateSoftKeyboard(UINT uType
, UINT hOwner
, int x
, int y
)
2609 FIXME("(%d, %d, %d, %d): stub\n", uType
, hOwner
, x
, y
);
2610 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2614 /***********************************************************************
2615 * ImmDestroySoftKeyboard(IMM32.@)
2617 BOOL WINAPI
ImmDestroySoftKeyboard(HWND hSoftWnd
)
2619 FIXME("(%p): stub\n", hSoftWnd
);
2620 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2624 /***********************************************************************
2625 * ImmShowSoftKeyboard(IMM32.@)
2627 BOOL WINAPI
ImmShowSoftKeyboard(HWND hSoftWnd
, int nCmdShow
)
2629 FIXME("(%p, %d): stub\n", hSoftWnd
, nCmdShow
);
2630 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2634 /***********************************************************************
2635 * ImmSimulateHotKey (IMM32.@)
2637 BOOL WINAPI
ImmSimulateHotKey(HWND hWnd
, DWORD dwHotKeyID
)
2639 FIXME("(%p, %ld): stub\n", hWnd
, dwHotKeyID
);
2640 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2644 /***********************************************************************
2645 * ImmUnregisterWordA (IMM32.@)
2647 BOOL WINAPI
ImmUnregisterWordA(
2648 HKL hKL
, LPCSTR lpszReading
, DWORD dwStyle
, LPCSTR lpszUnregister
)
2650 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
2651 TRACE("(%p, %s, %ld, %s):\n", hKL
, debugstr_a(lpszReading
), dwStyle
,
2652 debugstr_a(lpszUnregister
));
2653 if (immHkl
->hIME
&& immHkl
->pImeUnregisterWord
)
2655 if (!is_kbd_ime_unicode(immHkl
))
2656 return immHkl
->pImeUnregisterWord((LPCWSTR
)lpszReading
,dwStyle
,
2657 (LPCWSTR
)lpszUnregister
);
2660 LPWSTR lpszwReading
= strdupAtoW(lpszReading
);
2661 LPWSTR lpszwUnregister
= strdupAtoW(lpszUnregister
);
2664 rc
= immHkl
->pImeUnregisterWord(lpszwReading
,dwStyle
,lpszwUnregister
);
2665 HeapFree(GetProcessHeap(),0,lpszwReading
);
2666 HeapFree(GetProcessHeap(),0,lpszwUnregister
);
2674 /***********************************************************************
2675 * ImmUnregisterWordW (IMM32.@)
2677 BOOL WINAPI
ImmUnregisterWordW(
2678 HKL hKL
, LPCWSTR lpszReading
, DWORD dwStyle
, LPCWSTR lpszUnregister
)
2680 ImmHkl
*immHkl
= IMM_GetImmHkl(hKL
);
2681 TRACE("(%p, %s, %ld, %s):\n", hKL
, debugstr_w(lpszReading
), dwStyle
,
2682 debugstr_w(lpszUnregister
));
2683 if (immHkl
->hIME
&& immHkl
->pImeUnregisterWord
)
2685 if (is_kbd_ime_unicode(immHkl
))
2686 return immHkl
->pImeUnregisterWord(lpszReading
,dwStyle
,lpszUnregister
);
2689 LPSTR lpszaReading
= strdupWtoA(lpszReading
);
2690 LPSTR lpszaUnregister
= strdupWtoA(lpszUnregister
);
2693 rc
= immHkl
->pImeUnregisterWord((LPCWSTR
)lpszaReading
,dwStyle
,
2694 (LPCWSTR
)lpszaUnregister
);
2695 HeapFree(GetProcessHeap(),0,lpszaReading
);
2696 HeapFree(GetProcessHeap(),0,lpszaUnregister
);
2704 /***********************************************************************
2705 * ImmGetImeMenuItemsA (IMM32.@)
2707 DWORD WINAPI
ImmGetImeMenuItemsA( HIMC hIMC
, DWORD dwFlags
, DWORD dwType
,
2708 LPIMEMENUITEMINFOA lpImeParentMenu
, LPIMEMENUITEMINFOA lpImeMenu
,
2711 InputContextData
*data
= get_imc_data(hIMC
);
2712 TRACE("(%p, %li, %li, %p, %p, %li):\n", hIMC
, dwFlags
, dwType
,
2713 lpImeParentMenu
, lpImeMenu
, dwSize
);
2717 SetLastError(ERROR_INVALID_HANDLE
);
2721 if (data
->immKbd
->hIME
&& data
->immKbd
->pImeGetImeMenuItems
)
2723 if (!is_himc_ime_unicode(data
) || (!lpImeParentMenu
&& !lpImeMenu
))
2724 return data
->immKbd
->pImeGetImeMenuItems(hIMC
, dwFlags
, dwType
,
2725 (IMEMENUITEMINFOW
*)lpImeParentMenu
,
2726 (IMEMENUITEMINFOW
*)lpImeMenu
, dwSize
);
2729 IMEMENUITEMINFOW lpImeParentMenuW
;
2730 IMEMENUITEMINFOW
*lpImeMenuW
, *parent
= NULL
;
2733 if (lpImeParentMenu
)
2734 parent
= &lpImeParentMenuW
;
2737 int count
= dwSize
/ sizeof(LPIMEMENUITEMINFOA
);
2738 dwSize
= count
* sizeof(IMEMENUITEMINFOW
);
2739 lpImeMenuW
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
2744 rc
= data
->immKbd
->pImeGetImeMenuItems(hIMC
, dwFlags
, dwType
,
2745 parent
, lpImeMenuW
, dwSize
);
2747 if (lpImeParentMenu
)
2749 memcpy(lpImeParentMenu
,&lpImeParentMenuW
,sizeof(IMEMENUITEMINFOA
));
2750 lpImeParentMenu
->hbmpItem
= lpImeParentMenuW
.hbmpItem
;
2751 WideCharToMultiByte(CP_ACP
, 0, lpImeParentMenuW
.szString
,
2752 -1, lpImeParentMenu
->szString
, IMEMENUITEM_STRING_SIZE
,
2755 if (lpImeMenu
&& rc
)
2758 for (i
= 0; i
< rc
; i
++)
2760 memcpy(&lpImeMenu
[i
],&lpImeMenuW
[1],sizeof(IMEMENUITEMINFOA
));
2761 lpImeMenu
[i
].hbmpItem
= lpImeMenuW
[i
].hbmpItem
;
2762 WideCharToMultiByte(CP_ACP
, 0, lpImeMenuW
[i
].szString
,
2763 -1, lpImeMenu
[i
].szString
, IMEMENUITEM_STRING_SIZE
,
2767 HeapFree(GetProcessHeap(),0,lpImeMenuW
);
2775 /***********************************************************************
2776 * ImmGetImeMenuItemsW (IMM32.@)
2778 DWORD WINAPI
ImmGetImeMenuItemsW( HIMC hIMC
, DWORD dwFlags
, DWORD dwType
,
2779 LPIMEMENUITEMINFOW lpImeParentMenu
, LPIMEMENUITEMINFOW lpImeMenu
,
2782 InputContextData
*data
= get_imc_data(hIMC
);
2783 TRACE("(%p, %li, %li, %p, %p, %li):\n", hIMC
, dwFlags
, dwType
,
2784 lpImeParentMenu
, lpImeMenu
, dwSize
);
2788 SetLastError(ERROR_INVALID_HANDLE
);
2792 if (data
->immKbd
->hIME
&& data
->immKbd
->pImeGetImeMenuItems
)
2794 if (is_himc_ime_unicode(data
) || (!lpImeParentMenu
&& !lpImeMenu
))
2795 return data
->immKbd
->pImeGetImeMenuItems(hIMC
, dwFlags
, dwType
,
2796 lpImeParentMenu
, lpImeMenu
, dwSize
);
2799 IMEMENUITEMINFOA lpImeParentMenuA
;
2800 IMEMENUITEMINFOA
*lpImeMenuA
, *parent
= NULL
;
2803 if (lpImeParentMenu
)
2804 parent
= &lpImeParentMenuA
;
2807 int count
= dwSize
/ sizeof(LPIMEMENUITEMINFOW
);
2808 dwSize
= count
* sizeof(IMEMENUITEMINFOA
);
2809 lpImeMenuA
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
2814 rc
= data
->immKbd
->pImeGetImeMenuItems(hIMC
, dwFlags
, dwType
,
2815 (IMEMENUITEMINFOW
*)parent
,
2816 (IMEMENUITEMINFOW
*)lpImeMenuA
, dwSize
);
2818 if (lpImeParentMenu
)
2820 memcpy(lpImeParentMenu
,&lpImeParentMenuA
,sizeof(IMEMENUITEMINFOA
));
2821 lpImeParentMenu
->hbmpItem
= lpImeParentMenuA
.hbmpItem
;
2822 MultiByteToWideChar(CP_ACP
, 0, lpImeParentMenuA
.szString
,
2823 -1, lpImeParentMenu
->szString
, IMEMENUITEM_STRING_SIZE
);
2825 if (lpImeMenu
&& rc
)
2828 for (i
= 0; i
< rc
; i
++)
2830 memcpy(&lpImeMenu
[i
],&lpImeMenuA
[1],sizeof(IMEMENUITEMINFOA
));
2831 lpImeMenu
[i
].hbmpItem
= lpImeMenuA
[i
].hbmpItem
;
2832 MultiByteToWideChar(CP_ACP
, 0, lpImeMenuA
[i
].szString
,
2833 -1, lpImeMenu
[i
].szString
, IMEMENUITEM_STRING_SIZE
);
2836 HeapFree(GetProcessHeap(),0,lpImeMenuA
);
2844 /***********************************************************************
2845 * ImmLockIMC(IMM32.@)
2847 LPINPUTCONTEXT WINAPI
ImmLockIMC(HIMC hIMC
)
2849 InputContextData
*data
= get_imc_data(hIMC
);
2857 /***********************************************************************
2858 * ImmUnlockIMC(IMM32.@)
2860 BOOL WINAPI
ImmUnlockIMC(HIMC hIMC
)
2862 InputContextData
*data
= get_imc_data(hIMC
);
2871 /***********************************************************************
2872 * ImmGetIMCLockCount(IMM32.@)
2874 DWORD WINAPI
ImmGetIMCLockCount(HIMC hIMC
)
2876 InputContextData
*data
= get_imc_data(hIMC
);
2879 return data
->dwLock
;
2882 /***********************************************************************
2883 * ImmCreateIMCC(IMM32.@)
2885 HIMCC WINAPI
ImmCreateIMCC(DWORD size
)
2887 return GlobalAlloc(GMEM_ZEROINIT
| GMEM_MOVEABLE
, size
);
2890 /***********************************************************************
2891 * ImmDestroyIMCC(IMM32.@)
2893 HIMCC WINAPI
ImmDestroyIMCC(HIMCC block
)
2895 return GlobalFree(block
);
2898 /***********************************************************************
2899 * ImmLockIMCC(IMM32.@)
2901 LPVOID WINAPI
ImmLockIMCC(HIMCC imcc
)
2903 return GlobalLock(imcc
);
2906 /***********************************************************************
2907 * ImmUnlockIMCC(IMM32.@)
2909 BOOL WINAPI
ImmUnlockIMCC(HIMCC imcc
)
2911 return GlobalUnlock(imcc
);
2914 /***********************************************************************
2915 * ImmGetIMCCLockCount(IMM32.@)
2917 DWORD WINAPI
ImmGetIMCCLockCount(HIMCC imcc
)
2919 return GlobalFlags(imcc
) & GMEM_LOCKCOUNT
;
2922 /***********************************************************************
2923 * ImmReSizeIMCC(IMM32.@)
2925 HIMCC WINAPI
ImmReSizeIMCC(HIMCC imcc
, DWORD size
)
2927 return GlobalReAlloc(imcc
, size
, GMEM_ZEROINIT
| GMEM_MOVEABLE
);
2930 /***********************************************************************
2931 * ImmGetIMCCSize(IMM32.@)
2933 DWORD WINAPI
ImmGetIMCCSize(HIMCC imcc
)
2935 return GlobalSize(imcc
);
2938 /***********************************************************************
2939 * ImmGenerateMessage(IMM32.@)
2941 BOOL WINAPI
ImmGenerateMessage(HIMC hIMC
)
2943 InputContextData
*data
= get_imc_data(hIMC
);
2947 SetLastError(ERROR_INVALID_HANDLE
);
2951 TRACE("%li messages queued\n",data
->IMC
.dwNumMsgBuf
);
2952 if (data
->IMC
.dwNumMsgBuf
> 0)
2954 LPTRANSMSG lpTransMsg
;
2956 DWORD i
, dwNumMsgBuf
;
2958 /* We are going to detach our hMsgBuff so that if processing messages
2959 generates new messages they go into a new buffer */
2960 hMsgBuf
= data
->IMC
.hMsgBuf
;
2961 dwNumMsgBuf
= data
->IMC
.dwNumMsgBuf
;
2963 data
->IMC
.hMsgBuf
= ImmCreateIMCC(0);
2964 data
->IMC
.dwNumMsgBuf
= 0;
2966 lpTransMsg
= ImmLockIMCC(hMsgBuf
);
2967 for (i
= 0; i
< dwNumMsgBuf
; i
++)
2968 ImmInternalSendIMEMessage(data
, lpTransMsg
[i
].message
, lpTransMsg
[i
].wParam
, lpTransMsg
[i
].lParam
);
2970 ImmUnlockIMCC(hMsgBuf
);
2971 ImmDestroyIMCC(hMsgBuf
);
2977 /***********************************************************************
2978 * ImmTranslateMessage(IMM32.@)
2979 * ( Undocumented, call internally and from user32.dll )
2981 BOOL WINAPI
ImmTranslateMessage(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lKeyData
)
2983 InputContextData
*data
;
2984 HIMC imc
= ImmGetContext(hwnd
);
2990 static const DWORD list_count
= 10;
2992 TRACE("%p %x %x %x\n",hwnd
, msg
, (UINT
)wParam
, (UINT
)lKeyData
);
2994 if (!(data
= get_imc_data( imc
))) return FALSE
;
2996 if (!data
->immKbd
->hIME
|| !data
->immKbd
->pImeToAsciiEx
|| data
->lastVK
== VK_PROCESSKEY
)
2999 GetKeyboardState(state
);
3000 scancode
= lKeyData
>> 0x10 & 0xff;
3002 list
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, list_count
* sizeof(TRANSMSG
) + sizeof(DWORD
));
3003 ((DWORD
*)list
)[0] = list_count
;
3005 if (data
->immKbd
->imeInfo
.fdwProperty
& IME_PROP_KBD_CHAR_FIRST
)
3009 if (!is_himc_ime_unicode(data
))
3010 ToAscii(data
->lastVK
, scancode
, state
, &chr
, 0);
3012 ToUnicodeEx(data
->lastVK
, scancode
, state
, &chr
, 1, 0, GetKeyboardLayout(0));
3013 uVirtKey
= MAKELONG(data
->lastVK
,chr
);
3016 uVirtKey
= data
->lastVK
;
3018 msg_count
= data
->immKbd
->pImeToAsciiEx(uVirtKey
, scancode
, state
, list
, 0, imc
);
3019 TRACE("%i messages generated\n",msg_count
);
3020 if (msg_count
&& msg_count
<= list_count
)
3023 LPTRANSMSG msgs
= (LPTRANSMSG
)((LPBYTE
)list
+ sizeof(DWORD
));
3025 for (i
= 0; i
< msg_count
; i
++)
3026 ImmInternalPostIMEMessage(data
, msgs
[i
].message
, msgs
[i
].wParam
, msgs
[i
].lParam
);
3028 else if (msg_count
> list_count
)
3029 ImmGenerateMessage(imc
);
3031 HeapFree(GetProcessHeap(),0,list
);
3033 data
->lastVK
= VK_PROCESSKEY
;
3035 return (msg_count
> 0);
3038 /***********************************************************************
3039 * ImmProcessKey(IMM32.@)
3040 * ( Undocumented, called from user32.dll )
3042 BOOL WINAPI
ImmProcessKey(HWND hwnd
, HKL hKL
, UINT vKey
, LPARAM lKeyData
, DWORD unknown
)
3044 InputContextData
*data
;
3045 HIMC imc
= ImmGetContext(hwnd
);
3048 TRACE("%p %p %x %x %lx\n",hwnd
, hKL
, vKey
, (UINT
)lKeyData
, unknown
);
3050 if (!(data
= get_imc_data( imc
))) return FALSE
;
3052 /* Make sure we are inputting to the correct keyboard */
3053 if (data
->immKbd
->hkl
!= hKL
)
3055 ImmHkl
*new_hkl
= IMM_GetImmHkl(hKL
);
3058 data
->immKbd
->pImeSelect(imc
, FALSE
);
3059 data
->immKbd
->uSelected
--;
3060 data
->immKbd
= new_hkl
;
3061 data
->immKbd
->pImeSelect(imc
, TRUE
);
3062 data
->immKbd
->uSelected
++;
3068 if (!data
->immKbd
->hIME
|| !data
->immKbd
->pImeProcessKey
)
3071 GetKeyboardState(state
);
3072 if (data
->immKbd
->pImeProcessKey(imc
, vKey
, lKeyData
, state
))
3074 data
->lastVK
= vKey
;
3078 data
->lastVK
= VK_PROCESSKEY
;
3082 /***********************************************************************
3083 * ImmDisableTextFrameService(IMM32.@)
3085 BOOL WINAPI
ImmDisableTextFrameService(DWORD idThread
)
3091 /***********************************************************************
3092 * ImmEnumInputContext(IMM32.@)
3095 BOOL WINAPI
ImmEnumInputContext(DWORD idThread
, IMCENUMPROC lpfn
, LPARAM lParam
)
3101 /***********************************************************************
3102 * ImmGetHotKey(IMM32.@)
3105 BOOL WINAPI
ImmGetHotKey(DWORD hotkey
, UINT
*modifiers
, UINT
*key
, HKL hkl
)
3107 FIXME("%lx, %p, %p, %p: stub\n", hotkey
, modifiers
, key
, hkl
);
3111 /***********************************************************************
3112 * ImmDisableLegacyIME(IMM32.@)
3114 BOOL WINAPI
ImmDisableLegacyIME(void)
3120 static HWND
get_ui_window(HKL hkl
)
3122 ImmHkl
*immHkl
= IMM_GetImmHkl(hkl
);
3123 return immHkl
->UIWnd
;
3126 static BOOL
is_ime_ui_msg(UINT msg
)
3130 case WM_IME_STARTCOMPOSITION
:
3131 case WM_IME_ENDCOMPOSITION
:
3132 case WM_IME_COMPOSITION
:
3133 case WM_IME_SETCONTEXT
:
3135 case WM_IME_CONTROL
:
3136 case WM_IME_COMPOSITIONFULL
:
3139 case WM_IME_REQUEST
:
3140 case WM_IME_KEYDOWN
:
3144 return msg
== WM_MSIME_RECONVERTOPTIONS
||
3145 msg
== WM_MSIME_SERVICE
||
3146 msg
== WM_MSIME_MOUSE
||
3147 msg
== WM_MSIME_RECONVERTREQUEST
||
3148 msg
== WM_MSIME_RECONVERT
||
3149 msg
== WM_MSIME_QUERYPOSITION
||
3150 msg
== WM_MSIME_DOCUMENTFEED
;
3154 static LRESULT
ime_internal_msg( WPARAM wparam
, LPARAM lparam
)
3156 HWND hwnd
= (HWND
)lparam
;
3161 case IME_INTERNAL_ACTIVATE
:
3162 case IME_INTERNAL_DEACTIVATE
:
3163 himc
= ImmGetContext(hwnd
);
3164 ImmSetActiveContext(hwnd
, himc
, wparam
== IME_INTERNAL_ACTIVATE
);
3165 ImmReleaseContext(hwnd
, himc
);
3168 FIXME("wparam = %Ix\n", wparam
);
3175 static void init_messages(void)
3177 static BOOL initialized
;
3179 if (initialized
) return;
3181 WM_MSIME_SERVICE
= RegisterWindowMessageW(L
"MSIMEService");
3182 WM_MSIME_RECONVERTOPTIONS
= RegisterWindowMessageW(L
"MSIMEReconvertOptions");
3183 WM_MSIME_MOUSE
= RegisterWindowMessageW(L
"MSIMEMouseOperation");
3184 WM_MSIME_RECONVERTREQUEST
= RegisterWindowMessageW(L
"MSIMEReconvertRequest");
3185 WM_MSIME_RECONVERT
= RegisterWindowMessageW(L
"MSIMEReconvert");
3186 WM_MSIME_QUERYPOSITION
= RegisterWindowMessageW(L
"MSIMEQueryPosition");
3187 WM_MSIME_DOCUMENTFEED
= RegisterWindowMessageW(L
"MSIMEDocumentFeed");
3191 LRESULT WINAPI
__wine_ime_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
, BOOL ansi
)
3203 HWND default_hwnd
= ImmGetDefaultIMEWnd(0);
3204 if (!default_hwnd
|| hwnd
== default_hwnd
)
3205 imm_couninit_thread(TRUE
);
3209 case WM_IME_INTERNAL
:
3210 return ime_internal_msg(wparam
, lparam
);
3213 if (is_ime_ui_msg(msg
))
3215 if ((uiwnd
= get_ui_window(NtUserGetKeyboardLayout(0))))
3218 return SendMessageA(uiwnd
, msg
, wparam
, lparam
);
3220 return SendMessageW(uiwnd
, msg
, wparam
, lparam
);
3226 return DefWindowProcA(hwnd
, msg
, wparam
, lparam
);
3228 return DefWindowProcW(hwnd
, msg
, wparam
, lparam
);