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
29 #include "wine/debug.h"
34 #include "wine/list.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(imm
);
38 #define FROM_IME 0xcafe1337
40 static void (*pX11DRV_ForceXIMReset
)(HWND
);
42 typedef struct tagIMCCInternal
48 #define MAKE_FUNCPTR(f) typeof(f) * p##f
49 typedef struct _tagImmHkl
{
54 WCHAR imeClassName
[17]; /* 16 character max */
57 /* Function Pointers */
58 MAKE_FUNCPTR(ImeInquire
);
59 MAKE_FUNCPTR(ImeConfigure
);
60 MAKE_FUNCPTR(ImeDestroy
);
61 MAKE_FUNCPTR(ImeEscape
);
62 MAKE_FUNCPTR(ImeSelect
);
63 MAKE_FUNCPTR(ImeSetActiveContext
);
64 MAKE_FUNCPTR(ImeToAsciiEx
);
65 MAKE_FUNCPTR(NotifyIME
);
66 MAKE_FUNCPTR(ImeRegisterWord
);
67 MAKE_FUNCPTR(ImeUnregisterWord
);
68 MAKE_FUNCPTR(ImeEnumRegisterWord
);
69 MAKE_FUNCPTR(ImeSetCompositionString
);
70 MAKE_FUNCPTR(ImeConversionList
);
71 MAKE_FUNCPTR(ImeProcessKey
);
72 MAKE_FUNCPTR(ImeGetRegisterWordStyle
);
73 MAKE_FUNCPTR(ImeGetImeMenuItems
);
77 typedef struct tagInputContextData
90 typedef struct _tagTRANSMSG
{
94 } TRANSMSG
, *LPTRANSMSG
;
96 static InputContextData
*root_context
= NULL
;
97 static HWND hwndDefault
= NULL
;
98 static HANDLE hImeInst
;
99 static const WCHAR WC_IMECLASSNAME
[] = {'I','M','E',0};
100 static ATOM atIMEClass
= 0;
102 static struct list ImmHklList
= LIST_INIT(ImmHklList
);
105 static UINT WM_MSIME_SERVICE
;
106 static UINT WM_MSIME_RECONVERTOPTIONS
;
107 static UINT WM_MSIME_MOUSE
;
108 static UINT WM_MSIME_RECONVERTREQUEST
;
109 static UINT WM_MSIME_RECONVERT
;
110 static UINT WM_MSIME_QUERYPOSITION
;
111 static UINT WM_MSIME_DOCUMENTFEED
;
116 static LRESULT WINAPI
IME_WindowProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
,
118 static void UpdateDataInDefaultIMEWindow(HWND hwnd
, BOOL showable
);
119 static void ImmInternalPostIMEMessage(InputContextData
*, UINT
, WPARAM
, LPARAM
);
120 static void ImmInternalSetOpenStatus(BOOL fOpen
);
121 static HIMCC
updateResultStr(HIMCC old
, LPWSTR resultstr
, DWORD len
);
123 /* ImmHkl loading and freeing */
124 #define LOAD_FUNCPTR(f) if((ptr->p##f = (LPVOID)GetProcAddress(ptr->hIME, #f)) == NULL){WARN("Can't find function %s in ime\n", #f);}
125 static ImmHkl
*IMM_GetImmHkl(HKL hkl
)
128 WCHAR filename
[MAX_PATH
];
130 TRACE("Seeking ime for keyboard 0x%x\n",(unsigned)hkl
);
132 LIST_FOR_EACH_ENTRY(ptr
, &ImmHklList
, ImmHkl
, entry
)
137 /* not found... create it */
139 ptr
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ImmHkl
));
142 if (ImmGetIMEFileNameW(hkl
, filename
, MAX_PATH
)) ptr
->hIME
= LoadLibraryW(filename
);
145 LOAD_FUNCPTR(ImeInquire
);
146 LOAD_FUNCPTR(ImeDestroy
);
147 LOAD_FUNCPTR(ImeSelect
);
148 if (!ptr
->pImeInquire
|| !ptr
->pImeDestroy
|| !ptr
->pImeSelect
)
150 FreeLibrary(ptr
->hIME
);
155 ptr
->pImeInquire(&ptr
->imeInfo
, ptr
->imeClassName
, NULL
);
156 LOAD_FUNCPTR(ImeConfigure
);
157 LOAD_FUNCPTR(ImeEscape
);
158 LOAD_FUNCPTR(ImeSetActiveContext
);
159 LOAD_FUNCPTR(ImeToAsciiEx
);
160 LOAD_FUNCPTR(NotifyIME
);
161 LOAD_FUNCPTR(ImeRegisterWord
);
162 LOAD_FUNCPTR(ImeUnregisterWord
);
163 LOAD_FUNCPTR(ImeEnumRegisterWord
);
164 LOAD_FUNCPTR(ImeSetCompositionString
);
165 LOAD_FUNCPTR(ImeConversionList
);
166 LOAD_FUNCPTR(ImeProcessKey
);
167 LOAD_FUNCPTR(ImeGetRegisterWordStyle
);
168 LOAD_FUNCPTR(ImeGetImeMenuItems
);
171 list_add_head(&ImmHklList
,&ptr
->entry
);
177 static void IMM_FreeAllImmHkl(void)
179 ImmHkl
*ptr
,*cursor2
;
181 LIST_FOR_EACH_ENTRY_SAFE(ptr
, cursor2
, &ImmHklList
, ImmHkl
, entry
)
183 list_remove(&ptr
->entry
);
187 FreeLibrary(ptr
->hIME
);
189 HeapFree(GetProcessHeap(),0,ptr
);
193 static VOID
IMM_PostResult(InputContextData
*data
)
196 LPCOMPOSITIONSTRING compstr
;
201 TRACE("Posting result as IME_CHAR\n");
202 compdata
= ImmLockIMCC(root_context
->IMC
.hCompStr
);
203 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
204 ResultStr
= (LPWSTR
)(compdata
+ compstr
->dwResultStrOffset
);
206 for (i
= 0; i
< compstr
->dwResultStrLen
; i
++)
207 ImmInternalPostIMEMessage (root_context
, WM_IME_CHAR
, ResultStr
[i
], 1);
209 ImmUnlockIMCC(root_context
->IMC
.hCompStr
);
211 /* clear the buffer */
212 newCompStr
= updateResultStr(root_context
->IMC
.hCompStr
, NULL
, 0);
213 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
214 root_context
->IMC
.hCompStr
= newCompStr
;
217 static void IMM_Register(void)
220 ZeroMemory(&wndClass
, sizeof(WNDCLASSW
));
221 wndClass
.style
= CS_GLOBALCLASS
| CS_IME
| CS_HREDRAW
| CS_VREDRAW
;
222 wndClass
.lpfnWndProc
= (WNDPROC
) IME_WindowProc
;
223 wndClass
.cbClsExtra
= 0;
224 wndClass
.cbWndExtra
= 0;
225 wndClass
.hInstance
= hImeInst
;
226 wndClass
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
227 wndClass
.hIcon
= NULL
;
228 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+1);
229 wndClass
.lpszMenuName
= 0;
230 wndClass
.lpszClassName
= WC_IMECLASSNAME
;
231 atIMEClass
= RegisterClassW(&wndClass
);
234 static void IMM_Unregister(void)
237 UnregisterClassW(WC_IMECLASSNAME
, NULL
);
241 static void IMM_RegisterMessages(void)
243 WM_MSIME_SERVICE
= RegisterWindowMessageA("MSIMEService");
244 WM_MSIME_RECONVERTOPTIONS
= RegisterWindowMessageA("MSIMEReconvertOptions");
245 WM_MSIME_MOUSE
= RegisterWindowMessageA("MSIMEMouseOperation");
246 WM_MSIME_RECONVERTREQUEST
= RegisterWindowMessageA("MSIMEReconvertRequest");
247 WM_MSIME_RECONVERT
= RegisterWindowMessageA("MSIMEReconvert");
248 WM_MSIME_QUERYPOSITION
= RegisterWindowMessageA("MSIMEQueryPosition");
249 WM_MSIME_DOCUMENTFEED
= RegisterWindowMessageA("MSIMEDocumentFeed");
253 BOOL WINAPI
DllMain(HINSTANCE hInstDLL
, DWORD fdwReason
, LPVOID lpReserved
)
257 TRACE("%p, %x, %p\n",hInstDLL
,fdwReason
,lpReserved
);
260 case DLL_PROCESS_ATTACH
:
261 DisableThreadLibraryCalls(hInstDLL
);
263 IMM_RegisterMessages();
264 x11drv
= GetModuleHandleA("winex11.drv");
265 if (x11drv
) pX11DRV_ForceXIMReset
= (void *)GetProcAddress( x11drv
, "ForceXIMReset");
267 case DLL_PROCESS_DETACH
:
270 DestroyWindow(hwndDefault
);
280 /* for posting messages as the IME */
281 static void ImmInternalPostIMEMessage(InputContextData
*data
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
283 HWND target
= GetFocus();
285 PostMessageW(data
->IMC
.hWnd
,msg
,wParam
,lParam
);
287 PostMessageW(target
, msg
, wParam
, lParam
);
290 static LRESULT
ImmInternalSendIMENotify(InputContextData
*data
, WPARAM notify
, LPARAM lParam
)
294 target
= data
->IMC
.hWnd
;
295 if (!target
) target
= GetFocus();
298 return SendMessageW(target
, WM_IME_NOTIFY
, notify
, lParam
);
303 static HIMCC
ImmCreateBlankCompStr(void)
306 LPCOMPOSITIONSTRING ptr
;
307 rc
= ImmCreateIMCC(sizeof(COMPOSITIONSTRING
));
308 ptr
= (LPCOMPOSITIONSTRING
)ImmLockIMCC(rc
);
309 memset(ptr
,0,sizeof(COMPOSITIONSTRING
));
310 ptr
->dwSize
= sizeof(COMPOSITIONSTRING
);
315 static void ImmInternalSetOpenStatus(BOOL fOpen
)
317 TRACE("Setting internal state to %s\n",(fOpen
)?"OPEN":"CLOSED");
319 if (root_context
->IMC
.fOpen
&& fOpen
== FALSE
)
321 ShowWindow(hwndDefault
,SW_HIDE
);
322 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
323 root_context
->IMC
.hCompStr
= ImmCreateBlankCompStr();
326 root_context
->IMC
.fOpen
= fOpen
;
327 root_context
->bInternalState
= fOpen
;
329 ImmInternalSendIMENotify(root_context
, IMN_SETOPENSTATUS
, 0);
332 static int updateField(DWORD origLen
, DWORD origOffset
, DWORD currentOffset
,
333 LPBYTE target
, LPBYTE source
, DWORD
* lenParam
,
334 DWORD
* offsetParam
, BOOL wchars
)
336 if (origLen
> 0 && origOffset
> 0)
338 int truelen
= origLen
;
340 truelen
*= sizeof(WCHAR
);
342 memcpy(&target
[currentOffset
], &source
[origOffset
], truelen
);
345 *offsetParam
= currentOffset
;
346 currentOffset
+= truelen
;
348 return currentOffset
;
351 static HIMCC
updateCompStr(HIMCC old
, LPWSTR compstr
, DWORD len
)
353 /* we need to make sure the CompStr, CompClaus and CompAttr fields are all
357 LPBYTE newdata
= NULL
;
358 LPBYTE olddata
= NULL
;
359 LPCOMPOSITIONSTRING new_one
;
360 LPCOMPOSITIONSTRING lpcs
= NULL
;
361 INT current_offset
= 0;
363 TRACE("%s, %i\n",debugstr_wn(compstr
,len
),len
);
365 if (old
== NULL
&& compstr
== NULL
&& len
== 0)
370 olddata
= ImmLockIMCC(old
);
371 lpcs
= (LPCOMPOSITIONSTRING
)olddata
;
374 needed_size
= sizeof(COMPOSITIONSTRING
) + len
* sizeof(WCHAR
) +
375 len
+ sizeof(DWORD
) * 2;
379 needed_size
+= lpcs
->dwCompReadAttrLen
;
380 needed_size
+= lpcs
->dwCompReadClauseLen
;
381 needed_size
+= lpcs
->dwCompReadStrLen
* sizeof(DWORD
);
382 needed_size
+= lpcs
->dwResultReadClauseLen
;
383 needed_size
+= lpcs
->dwResultReadStrLen
* sizeof(DWORD
);
384 needed_size
+= lpcs
->dwResultClauseLen
;
385 needed_size
+= lpcs
->dwResultStrLen
* sizeof(DWORD
);
386 needed_size
+= lpcs
->dwPrivateSize
;
388 rc
= ImmCreateIMCC(needed_size
);
389 newdata
= ImmLockIMCC(rc
);
390 new_one
= (LPCOMPOSITIONSTRING
)newdata
;
392 new_one
->dwSize
= needed_size
;
393 current_offset
= sizeof(COMPOSITIONSTRING
);
396 current_offset
= updateField(lpcs
->dwCompReadAttrLen
,
397 lpcs
->dwCompReadAttrOffset
,
398 current_offset
, newdata
, olddata
,
399 &new_one
->dwCompReadAttrLen
,
400 &new_one
->dwCompReadAttrOffset
, FALSE
);
402 current_offset
= updateField(lpcs
->dwCompReadClauseLen
,
403 lpcs
->dwCompReadClauseOffset
,
404 current_offset
, newdata
, olddata
,
405 &new_one
->dwCompReadClauseLen
,
406 &new_one
->dwCompReadClauseOffset
, FALSE
);
408 current_offset
= updateField(lpcs
->dwCompReadStrLen
,
409 lpcs
->dwCompReadStrOffset
,
410 current_offset
, newdata
, olddata
,
411 &new_one
->dwCompReadStrLen
,
412 &new_one
->dwCompReadStrOffset
, TRUE
);
414 /* new CompAttr, CompClause, CompStr, dwCursorPos */
415 new_one
->dwDeltaStart
= 0;
417 current_offset
= updateField(lpcs
->dwResultReadClauseLen
,
418 lpcs
->dwResultReadClauseOffset
,
419 current_offset
, newdata
, olddata
,
420 &new_one
->dwResultReadClauseLen
,
421 &new_one
->dwResultReadClauseOffset
, FALSE
);
423 current_offset
= updateField(lpcs
->dwResultReadStrLen
,
424 lpcs
->dwResultReadStrOffset
,
425 current_offset
, newdata
, olddata
,
426 &new_one
->dwResultReadStrLen
,
427 &new_one
->dwResultReadStrOffset
, TRUE
);
429 current_offset
= updateField(lpcs
->dwResultClauseLen
,
430 lpcs
->dwResultClauseOffset
,
431 current_offset
, newdata
, olddata
,
432 &new_one
->dwResultClauseLen
,
433 &new_one
->dwResultClauseOffset
, FALSE
);
435 current_offset
= updateField(lpcs
->dwResultStrLen
,
436 lpcs
->dwResultStrOffset
,
437 current_offset
, newdata
, olddata
,
438 &new_one
->dwResultStrLen
,
439 &new_one
->dwResultStrOffset
, TRUE
);
441 current_offset
= updateField(lpcs
->dwPrivateSize
,
442 lpcs
->dwPrivateOffset
,
443 current_offset
, newdata
, olddata
,
444 &new_one
->dwPrivateSize
,
445 &new_one
->dwPrivateOffset
, FALSE
);
450 new_one
->dwCompAttrLen
= len
;
453 new_one
->dwCompAttrOffset
= current_offset
;
454 memset(&newdata
[current_offset
],ATTR_INPUT
,len
);
455 current_offset
+= len
;
461 new_one
->dwCompClauseLen
= sizeof(DWORD
) * 2;
462 new_one
->dwCompClauseOffset
= current_offset
;
463 *(DWORD
*)(&newdata
[current_offset
]) = 0;
464 current_offset
+= sizeof(DWORD
);
465 *(DWORD
*)(&newdata
[current_offset
]) = len
;
466 current_offset
+= sizeof(DWORD
);
470 new_one
->dwCompStrLen
= len
;
473 new_one
->dwCompStrOffset
= current_offset
;
474 memcpy(&newdata
[current_offset
],compstr
,len
*sizeof(WCHAR
));
478 new_one
->dwCursorPos
= len
;
487 static HIMCC
updateResultStr(HIMCC old
, LPWSTR resultstr
, DWORD len
)
489 /* we need to make sure the ResultStr and ResultClause fields are all
493 LPBYTE newdata
= NULL
;
494 LPBYTE olddata
= NULL
;
495 LPCOMPOSITIONSTRING new_one
;
496 LPCOMPOSITIONSTRING lpcs
= NULL
;
497 INT current_offset
= 0;
499 TRACE("%s, %i\n",debugstr_wn(resultstr
,len
),len
);
501 if (old
== NULL
&& resultstr
== NULL
&& len
== 0)
506 olddata
= ImmLockIMCC(old
);
507 lpcs
= (LPCOMPOSITIONSTRING
)olddata
;
510 needed_size
= sizeof(COMPOSITIONSTRING
) + len
* sizeof(WCHAR
) +
515 needed_size
+= lpcs
->dwCompReadAttrLen
;
516 needed_size
+= lpcs
->dwCompReadClauseLen
;
517 needed_size
+= lpcs
->dwCompReadStrLen
* sizeof(DWORD
);
518 needed_size
+= lpcs
->dwCompAttrLen
;
519 needed_size
+= lpcs
->dwCompClauseLen
;
520 needed_size
+= lpcs
->dwCompStrLen
* sizeof(DWORD
);
521 needed_size
+= lpcs
->dwResultReadClauseLen
;
522 needed_size
+= lpcs
->dwResultReadStrLen
* sizeof(DWORD
);
523 needed_size
+= lpcs
->dwPrivateSize
;
525 rc
= ImmCreateIMCC(needed_size
);
526 newdata
= ImmLockIMCC(rc
);
527 new_one
= (LPCOMPOSITIONSTRING
)newdata
;
529 new_one
->dwSize
= needed_size
;
530 current_offset
= sizeof(COMPOSITIONSTRING
);
533 current_offset
= updateField(lpcs
->dwCompReadAttrLen
,
534 lpcs
->dwCompReadAttrOffset
,
535 current_offset
, newdata
, olddata
,
536 &new_one
->dwCompReadAttrLen
,
537 &new_one
->dwCompReadAttrOffset
, FALSE
);
539 current_offset
= updateField(lpcs
->dwCompReadClauseLen
,
540 lpcs
->dwCompReadClauseOffset
,
541 current_offset
, newdata
, olddata
,
542 &new_one
->dwCompReadClauseLen
,
543 &new_one
->dwCompReadClauseOffset
, FALSE
);
545 current_offset
= updateField(lpcs
->dwCompReadStrLen
,
546 lpcs
->dwCompReadStrOffset
,
547 current_offset
, newdata
, olddata
,
548 &new_one
->dwCompReadStrLen
,
549 &new_one
->dwCompReadStrOffset
, TRUE
);
551 current_offset
= updateField(lpcs
->dwCompAttrLen
,
552 lpcs
->dwCompAttrOffset
,
553 current_offset
, newdata
, olddata
,
554 &new_one
->dwCompAttrLen
,
555 &new_one
->dwCompAttrOffset
, FALSE
);
557 current_offset
= updateField(lpcs
->dwCompClauseLen
,
558 lpcs
->dwCompClauseOffset
,
559 current_offset
, newdata
, olddata
,
560 &new_one
->dwCompClauseLen
,
561 &new_one
->dwCompClauseOffset
, FALSE
);
563 current_offset
= updateField(lpcs
->dwCompStrLen
,
564 lpcs
->dwCompStrOffset
,
565 current_offset
, newdata
, olddata
,
566 &new_one
->dwCompStrLen
,
567 &new_one
->dwCompStrOffset
, TRUE
);
569 new_one
->dwCursorPos
= lpcs
->dwCursorPos
;
570 new_one
->dwDeltaStart
= 0;
572 current_offset
= updateField(lpcs
->dwResultReadClauseLen
,
573 lpcs
->dwResultReadClauseOffset
,
574 current_offset
, newdata
, olddata
,
575 &new_one
->dwResultReadClauseLen
,
576 &new_one
->dwResultReadClauseOffset
, FALSE
);
578 current_offset
= updateField(lpcs
->dwResultReadStrLen
,
579 lpcs
->dwResultReadStrOffset
,
580 current_offset
, newdata
, olddata
,
581 &new_one
->dwResultReadStrLen
,
582 &new_one
->dwResultReadStrOffset
, TRUE
);
584 /* new ResultClause , ResultStr */
586 current_offset
= updateField(lpcs
->dwPrivateSize
,
587 lpcs
->dwPrivateOffset
,
588 current_offset
, newdata
, olddata
,
589 &new_one
->dwPrivateSize
,
590 &new_one
->dwPrivateOffset
, FALSE
);
597 new_one
->dwResultClauseLen
= sizeof(DWORD
) * 2;
598 new_one
->dwResultClauseOffset
= current_offset
;
599 *(DWORD
*)(&newdata
[current_offset
]) = 0;
600 current_offset
+= sizeof(DWORD
);
601 *(DWORD
*)(&newdata
[current_offset
]) = len
;
602 current_offset
+= sizeof(DWORD
);
606 new_one
->dwResultStrLen
= len
;
609 new_one
->dwResultStrOffset
= current_offset
;
610 memcpy(&newdata
[current_offset
],resultstr
,len
*sizeof(WCHAR
));
621 /***********************************************************************
622 * ImmAssociateContext (IMM32.@)
624 HIMC WINAPI
ImmAssociateContext(HWND hWnd
, HIMC hIMC
)
626 InputContextData
*data
= (InputContextData
*)hIMC
;
628 WARN("(%p, %p): semi-stub\n", hWnd
, hIMC
);
634 * WINE SPECIFIC! MAY CONFLICT
635 * associate the root context we have an XIM created
639 root_context
= (InputContextData
*)hIMC
;
643 * If already associated just return
645 if (data
->IMC
.hWnd
== hWnd
)
648 if (IsWindow(data
->IMC
.hWnd
))
651 * Post a message that your context is switching
653 SendMessageW(data
->IMC
.hWnd
, WM_IME_SETCONTEXT
, FALSE
, ISC_SHOWUIALL
);
656 data
->IMC
.hWnd
= hWnd
;
658 if (IsWindow(data
->IMC
.hWnd
))
661 * Post a message that your context is switching
663 SendMessageW(data
->IMC
.hWnd
, WM_IME_SETCONTEXT
, TRUE
, ISC_SHOWUIALL
);
667 * TODO: We need to keep track of the old context associated
668 * with a window and return it for now we will return NULL;
673 /***********************************************************************
674 * ImmAssociateContextEx (IMM32.@)
676 BOOL WINAPI
ImmAssociateContextEx(HWND hWnd
, HIMC hIMC
, DWORD dwFlags
)
678 FIXME("(%p, %p, %d): stub\n", hWnd
, hIMC
, dwFlags
);
679 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
683 /***********************************************************************
684 * ImmConfigureIMEA (IMM32.@)
686 BOOL WINAPI
ImmConfigureIMEA(
687 HKL hKL
, HWND hWnd
, DWORD dwMode
, LPVOID lpData
)
689 FIXME("(%p, %p, %d, %p): stub\n",
690 hKL
, hWnd
, dwMode
, lpData
692 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
696 /***********************************************************************
697 * ImmConfigureIMEW (IMM32.@)
699 BOOL WINAPI
ImmConfigureIMEW(
700 HKL hKL
, HWND hWnd
, DWORD dwMode
, LPVOID lpData
)
702 FIXME("(%p, %p, %d, %p): stub\n",
703 hKL
, hWnd
, dwMode
, lpData
705 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
709 /***********************************************************************
710 * ImmCreateContext (IMM32.@)
712 HIMC WINAPI
ImmCreateContext(void)
714 InputContextData
*new_context
;
716 new_context
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(InputContextData
));
719 new_context
->immKbd
= IMM_GetImmHkl(GetKeyboardLayout(0));
722 * Once we depend on the IME for all the processing like we should
723 * these will become hard errors and result in creation failures
725 if (!new_context
->immKbd
->hIME
)
726 TRACE("IME dll could not be loaded\n");
728 /* hCompStr is never NULL */
729 new_context
->IMC
.hCompStr
= ImmCreateBlankCompStr();
730 new_context
->IMC
.hMsgBuf
= ImmCreateIMCC(1);
732 /* Initialize the IME Private */
733 new_context
->IMC
.hPrivate
= ImmCreateIMCC(new_context
->immKbd
->imeInfo
.dwPrivateDataSize
);
735 if (new_context
->immKbd
->hIME
&&
736 !new_context
->immKbd
->pImeSelect(new_context
, TRUE
))
738 TRACE("Selection of IME failed\n");
739 ImmDestroyContext(new_context
);
743 new_context
->immKbd
->uSelected
++;
744 TRACE("Created context 0x%x\n",(UINT
)new_context
);
746 return (HIMC
)new_context
;
749 /***********************************************************************
750 * ImmDestroyContext (IMM32.@)
752 BOOL WINAPI
ImmDestroyContext(HIMC hIMC
)
754 InputContextData
*data
= (InputContextData
*)hIMC
;
756 TRACE("Destroying %p\n",hIMC
);
760 data
->immKbd
->uSelected
--;
761 if (data
->immKbd
->hIME
)
762 data
->immKbd
->pImeSelect(hIMC
, FALSE
);
764 ImmDestroyIMCC(data
->IMC
.hCompStr
);
765 ImmDestroyIMCC(data
->IMC
.hCandInfo
);
766 ImmDestroyIMCC(data
->IMC
.hGuideLine
);
767 ImmDestroyIMCC(data
->IMC
.hPrivate
);
768 ImmDestroyIMCC(data
->IMC
.hMsgBuf
);
772 DeleteObject(data
->textfont
);
773 data
->textfont
= NULL
;
776 HeapFree(GetProcessHeap(),0,data
);
781 /***********************************************************************
782 * ImmDisableIME (IMM32.@)
784 BOOL WINAPI
ImmDisableIME(DWORD idThread
)
786 FIXME("(%d): stub\n", idThread
);
790 /***********************************************************************
791 * ImmEnumRegisterWordA (IMM32.@)
793 UINT WINAPI
ImmEnumRegisterWordA(
794 HKL hKL
, REGISTERWORDENUMPROCA lpfnEnumProc
,
795 LPCSTR lpszReading
, DWORD dwStyle
,
796 LPCSTR lpszRegister
, LPVOID lpData
)
798 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
800 debugstr_a(lpszReading
), dwStyle
,
801 debugstr_a(lpszRegister
), lpData
803 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
807 /***********************************************************************
808 * ImmEnumRegisterWordW (IMM32.@)
810 UINT WINAPI
ImmEnumRegisterWordW(
811 HKL hKL
, REGISTERWORDENUMPROCW lpfnEnumProc
,
812 LPCWSTR lpszReading
, DWORD dwStyle
,
813 LPCWSTR lpszRegister
, LPVOID lpData
)
815 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
817 debugstr_w(lpszReading
), dwStyle
,
818 debugstr_w(lpszRegister
), lpData
820 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
824 /***********************************************************************
825 * ImmEscapeA (IMM32.@)
827 LRESULT WINAPI
ImmEscapeA(
829 UINT uEscape
, LPVOID lpData
)
831 FIXME("(%p, %p, %d, %p): stub\n",
832 hKL
, hIMC
, uEscape
, lpData
834 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
838 /***********************************************************************
839 * ImmEscapeW (IMM32.@)
841 LRESULT WINAPI
ImmEscapeW(
843 UINT uEscape
, LPVOID lpData
)
845 FIXME("(%p, %p, %d, %p): stub\n",
846 hKL
, hIMC
, uEscape
, lpData
848 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
852 /***********************************************************************
853 * ImmGetCandidateListA (IMM32.@)
855 DWORD WINAPI
ImmGetCandidateListA(
856 HIMC hIMC
, DWORD deIndex
,
857 LPCANDIDATELIST lpCandList
, DWORD dwBufLen
)
859 FIXME("(%p, %d, %p, %d): stub\n",
863 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
867 /***********************************************************************
868 * ImmGetCandidateListCountA (IMM32.@)
870 DWORD WINAPI
ImmGetCandidateListCountA(
871 HIMC hIMC
, LPDWORD lpdwListCount
)
873 FIXME("(%p, %p): stub\n", hIMC
, lpdwListCount
);
874 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
878 /***********************************************************************
879 * ImmGetCandidateListCountW (IMM32.@)
881 DWORD WINAPI
ImmGetCandidateListCountW(
882 HIMC hIMC
, LPDWORD lpdwListCount
)
884 FIXME("(%p, %p): stub\n", hIMC
, lpdwListCount
);
885 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
889 /***********************************************************************
890 * ImmGetCandidateListW (IMM32.@)
892 DWORD WINAPI
ImmGetCandidateListW(
893 HIMC hIMC
, DWORD deIndex
,
894 LPCANDIDATELIST lpCandList
, DWORD dwBufLen
)
896 FIXME("(%p, %d, %p, %d): stub\n",
900 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
904 /***********************************************************************
905 * ImmGetCandidateWindow (IMM32.@)
907 BOOL WINAPI
ImmGetCandidateWindow(
908 HIMC hIMC
, DWORD dwBufLen
, LPCANDIDATEFORM lpCandidate
)
910 FIXME("(%p, %d, %p): stub\n", hIMC
, dwBufLen
, lpCandidate
);
911 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
915 /***********************************************************************
916 * ImmGetCompositionFontA (IMM32.@)
918 BOOL WINAPI
ImmGetCompositionFontA(HIMC hIMC
, LPLOGFONTA lplf
)
923 TRACE("(%p, %p):\n", hIMC
, lplf
);
925 rc
= ImmGetCompositionFontW(hIMC
,&lfW
);
928 memcpy(lplf
,&lfW
,sizeof(LOGFONTA
));
929 WideCharToMultiByte(CP_ACP
, 0, lfW
.lfFaceName
, -1, lplf
->lfFaceName
,
930 LF_FACESIZE
, NULL
, NULL
);
935 /***********************************************************************
936 * ImmGetCompositionFontW (IMM32.@)
938 BOOL WINAPI
ImmGetCompositionFontW(HIMC hIMC
, LPLOGFONTW lplf
)
940 InputContextData
*data
= (InputContextData
*)hIMC
;
942 TRACE("(%p, %p):\n", hIMC
, lplf
);
947 *lplf
= data
->IMC
.lfFont
.W
;
952 /***********************************************************************
953 * ImmGetCompositionStringA (IMM32.@)
955 LONG WINAPI
ImmGetCompositionStringA(
956 HIMC hIMC
, DWORD dwIndex
, LPVOID lpBuf
, DWORD dwBufLen
)
960 InputContextData
*data
= (InputContextData
*)hIMC
;
961 LPCOMPOSITIONSTRING compstr
;
964 TRACE("(%p, 0x%x, %p, %d)\n", hIMC
, dwIndex
, lpBuf
, dwBufLen
);
969 if (!data
->IMC
.hCompStr
)
972 compdata
= ImmLockIMCC(data
->IMC
.hCompStr
);
973 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
975 if (dwIndex
== GCS_RESULTSTR
&& compstr
->dwResultStrLen
> 0 &&
976 compstr
->dwResultStrOffset
> 0)
978 LPWSTR ResultStr
= (LPWSTR
)(compdata
+ compstr
->dwResultStrOffset
);
980 TRACE("GSC_RESULTSTR %p %i\n",ResultStr
,
981 compstr
->dwResultStrLen
);
983 buf
= HeapAlloc( GetProcessHeap(), 0, compstr
->dwResultStrLen
* 3 );
984 rc
= WideCharToMultiByte(CP_ACP
, 0, ResultStr
,
985 compstr
->dwResultStrLen
, buf
,
986 compstr
->dwResultStrLen
* 3, NULL
, NULL
);
988 memcpy(lpBuf
,buf
,rc
);
991 HeapFree( GetProcessHeap(), 0, buf
);
993 else if (dwIndex
== GCS_COMPSTR
&& compstr
->dwCompStrLen
> 0 &&
994 compstr
->dwCompStrOffset
> 0)
996 LPWSTR CompString
= (LPWSTR
)(compdata
+ compstr
->dwCompStrOffset
);
998 TRACE("GSC_COMPSTR %p %i\n", CompString
, compstr
->dwCompStrLen
);
1000 buf
= HeapAlloc( GetProcessHeap(), 0, compstr
->dwCompStrLen
* 3 );
1001 rc
= WideCharToMultiByte(CP_ACP
, 0, CompString
,
1002 compstr
->dwCompStrLen
, buf
,
1003 compstr
->dwCompStrLen
* 3, NULL
, NULL
);
1005 memcpy(lpBuf
,buf
,rc
);
1006 HeapFree( GetProcessHeap(), 0, buf
);
1008 else if (dwIndex
== GCS_COMPATTR
&& compstr
->dwCompAttrLen
> 0 &&
1009 compstr
->dwCompAttrOffset
> 0)
1011 LPWSTR Compattr
= (LPWSTR
)(compdata
+ compstr
->dwCompAttrOffset
);
1012 TRACE("GSC_COMPATTR %p %i\n", Compattr
, compstr
->dwCompAttrLen
);
1014 rc
= compstr
->dwCompAttrLen
;
1016 memcpy(lpBuf
,Compattr
,rc
);
1018 else if (dwIndex
== GCS_COMPCLAUSE
&& compstr
->dwCompClauseLen
> 0 &&
1019 compstr
->dwCompClauseOffset
> 0)
1021 LPWSTR Compclause
= (LPWSTR
)(compdata
+ compstr
->dwCompClauseOffset
);
1022 TRACE("GSC_COMPCLAUSE %p %i\n", Compclause
, compstr
->dwCompClauseLen
);
1024 rc
= compstr
->dwCompClauseLen
;
1025 if (dwBufLen
>= compstr
->dwCompClauseLen
)
1026 memcpy(lpBuf
,Compclause
,rc
);
1028 else if (dwIndex
== GCS_RESULTCLAUSE
&& compstr
->dwResultClauseLen
> 0 &&
1029 compstr
->dwResultClauseOffset
> 0)
1031 LPWSTR Resultclause
= (LPWSTR
)(compdata
+ compstr
->dwResultClauseOffset
);
1032 TRACE("GSC_RESULTCLAUSE %p %i\n", Resultclause
, compstr
->dwResultClauseLen
);
1034 rc
= compstr
->dwResultClauseLen
;
1035 if (dwBufLen
>= compstr
->dwResultClauseLen
)
1036 memcpy(lpBuf
,Resultclause
,rc
);
1038 else if (dwIndex
== GCS_CURSORPOS
)
1040 TRACE("GSC_CURSORPOS\n");
1041 rc
= compstr
->dwCursorPos
;
1043 else if (dwIndex
== GCS_DELTASTART
)
1045 TRACE("GCS_DELTASTART\n");
1046 rc
= compstr
->dwDeltaStart
;
1050 FIXME("Unhandled index 0x%x\n",dwIndex
);
1053 ImmUnlockIMCC(data
->IMC
.hCompStr
);
1058 /***********************************************************************
1059 * ImmGetCompositionStringW (IMM32.@)
1061 LONG WINAPI
ImmGetCompositionStringW(
1062 HIMC hIMC
, DWORD dwIndex
,
1063 LPVOID lpBuf
, DWORD dwBufLen
)
1066 InputContextData
*data
= (InputContextData
*)hIMC
;
1067 LPCOMPOSITIONSTRING compstr
;
1070 TRACE("(%p, 0x%x, %p, %d)\n", hIMC
, dwIndex
, lpBuf
, dwBufLen
);
1075 if (!data
->IMC
.hCompStr
)
1078 compdata
= ImmLockIMCC(data
->IMC
.hCompStr
);
1079 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
1081 if (dwIndex
== GCS_RESULTSTR
&& compstr
->dwResultStrLen
> 0 &&
1082 compstr
->dwResultStrOffset
> 0)
1084 LPWSTR ResultStr
= (LPWSTR
)(compdata
+ compstr
->dwResultStrOffset
);
1086 rc
= compstr
->dwResultStrLen
* sizeof(WCHAR
);
1089 memcpy(lpBuf
,ResultStr
,rc
);
1091 else if (dwIndex
== GCS_RESULTREADSTR
&& compstr
->dwResultReadStrLen
> 0 &&
1092 compstr
->dwResultReadStrOffset
> 0)
1094 LPWSTR ResultReadString
= (LPWSTR
)(compdata
+ compstr
->dwResultReadStrOffset
);
1096 rc
= compstr
->dwResultReadStrLen
* sizeof(WCHAR
);
1098 memcpy(lpBuf
,ResultReadString
,rc
);
1100 else if (dwIndex
== GCS_COMPSTR
&& compstr
->dwCompStrLen
> 0 &&
1101 compstr
->dwCompStrOffset
> 0)
1103 LPWSTR CompString
= (LPWSTR
)(compdata
+ compstr
->dwCompStrOffset
);
1104 rc
= compstr
->dwCompStrLen
* sizeof(WCHAR
);
1106 memcpy(lpBuf
,CompString
,rc
);
1108 else if (dwIndex
== GCS_COMPATTR
&& compstr
->dwCompAttrLen
> 0 &&
1109 compstr
->dwCompAttrOffset
> 0)
1112 LPWSTR Compattr
= (LPWSTR
)(compdata
+ compstr
->dwCompAttrOffset
);
1114 rc
= compstr
->dwCompAttrLen
;
1116 memcpy(lpBuf
,Compattr
,rc
);
1118 else if (dwIndex
== GCS_COMPCLAUSE
&& compstr
->dwCompClauseLen
> 0 &&
1119 compstr
->dwCompClauseOffset
> 0)
1121 LPWSTR Compclause
= (LPWSTR
)(compdata
+ compstr
->dwCompClauseOffset
);
1123 rc
= compstr
->dwCompClauseLen
;
1124 if (dwBufLen
>= compstr
->dwCompClauseLen
)
1125 memcpy(lpBuf
,Compclause
,rc
);
1127 else if (dwIndex
== GCS_COMPREADSTR
&& compstr
->dwCompReadStrLen
> 0 &&
1128 compstr
->dwCompReadStrOffset
> 0)
1130 LPWSTR CompReadString
= (LPWSTR
)(compdata
+ compstr
->dwCompReadStrOffset
);
1132 rc
= compstr
->dwCompReadStrLen
* sizeof(WCHAR
);
1135 memcpy(lpBuf
,CompReadString
,rc
);
1137 else if (dwIndex
== GCS_CURSORPOS
)
1139 TRACE("GSC_CURSORPOS\n");
1140 rc
= compstr
->dwCursorPos
;
1142 else if (dwIndex
== GCS_DELTASTART
)
1144 TRACE("GCS_DELTASTART\n");
1145 rc
= compstr
->dwDeltaStart
;
1149 FIXME("Unhandled index 0x%x\n",dwIndex
);
1152 ImmUnlockIMCC(data
->IMC
.hCompStr
);
1157 /***********************************************************************
1158 * ImmGetCompositionWindow (IMM32.@)
1160 BOOL WINAPI
ImmGetCompositionWindow(HIMC hIMC
, LPCOMPOSITIONFORM lpCompForm
)
1162 InputContextData
*data
= (InputContextData
*)hIMC
;
1164 TRACE("(%p, %p)\n", hIMC
, lpCompForm
);
1169 *lpCompForm
= data
->IMC
.cfCompForm
;
1173 /***********************************************************************
1174 * ImmGetContext (IMM32.@)
1177 HIMC WINAPI
ImmGetContext(HWND hWnd
)
1179 TRACE("%p\n", hWnd
);
1184 root_context
->IMC
.hWnd
= hWnd
;
1185 return (HIMC
)root_context
;
1188 /***********************************************************************
1189 * ImmGetConversionListA (IMM32.@)
1191 DWORD WINAPI
ImmGetConversionListA(
1193 LPCSTR pSrc
, LPCANDIDATELIST lpDst
,
1194 DWORD dwBufLen
, UINT uFlag
)
1196 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1197 hKL
, hIMC
, debugstr_a(pSrc
), lpDst
, dwBufLen
, uFlag
1199 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1203 /***********************************************************************
1204 * ImmGetConversionListW (IMM32.@)
1206 DWORD WINAPI
ImmGetConversionListW(
1208 LPCWSTR pSrc
, LPCANDIDATELIST lpDst
,
1209 DWORD dwBufLen
, UINT uFlag
)
1211 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1212 hKL
, hIMC
, debugstr_w(pSrc
), lpDst
, dwBufLen
, uFlag
1214 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1218 /***********************************************************************
1219 * ImmGetConversionStatus (IMM32.@)
1221 BOOL WINAPI
ImmGetConversionStatus(
1222 HIMC hIMC
, LPDWORD lpfdwConversion
, LPDWORD lpfdwSentence
)
1224 TRACE("(%p, %p, %p): best guess\n", hIMC
, lpfdwConversion
, lpfdwSentence
);
1225 if (lpfdwConversion
)
1226 *lpfdwConversion
= IME_CMODE_NATIVE
;
1228 *lpfdwSentence
= IME_SMODE_NONE
;
1232 /***********************************************************************
1233 * ImmGetDefaultIMEWnd (IMM32.@)
1235 HWND WINAPI
ImmGetDefaultIMEWnd(HWND hWnd
)
1237 static int shown
= 0;
1240 FIXME("(%p - %p %p ): semi-stub\n", hWnd
,hwndDefault
, root_context
);
1244 if (hwndDefault
== NULL
)
1246 static const WCHAR the_name
[] = {'I','M','E','\0'};
1249 hwndDefault
= CreateWindowExW( WS_EX_TOOLWINDOW
, WC_IMECLASSNAME
,
1250 the_name
, WS_POPUP
, 0, 0, 1, 1, 0, 0,
1253 TRACE("Default created (%p)\n",hwndDefault
);
1259 /***********************************************************************
1260 * ImmGetDescriptionA (IMM32.@)
1262 UINT WINAPI
ImmGetDescriptionA(
1263 HKL hKL
, LPSTR lpszDescription
, UINT uBufLen
)
1268 TRACE("%p %p %d\n", hKL
, lpszDescription
, uBufLen
);
1270 /* find out how many characters in the unicode buffer */
1271 len
= ImmGetDescriptionW( hKL
, NULL
, 0 );
1273 /* allocate a buffer of that size */
1274 buf
= HeapAlloc( GetProcessHeap(), 0, (len
+ 1) * sizeof (WCHAR
) );
1278 /* fetch the unicode buffer */
1279 len
= ImmGetDescriptionW( hKL
, buf
, len
+ 1 );
1281 /* convert it back to ASCII */
1282 len
= WideCharToMultiByte( CP_ACP
, 0, buf
, len
+ 1,
1283 lpszDescription
, uBufLen
, NULL
, NULL
);
1285 HeapFree( GetProcessHeap(), 0, buf
);
1290 /***********************************************************************
1291 * ImmGetDescriptionW (IMM32.@)
1293 UINT WINAPI
ImmGetDescriptionW(HKL hKL
, LPWSTR lpszDescription
, UINT uBufLen
)
1295 static const WCHAR name
[] = { 'W','i','n','e',' ','X','I','M',0 };
1297 FIXME("(%p, %p, %d): semi stub\n", hKL
, lpszDescription
, uBufLen
);
1299 if (!uBufLen
) return lstrlenW( name
);
1300 lstrcpynW( lpszDescription
, name
, uBufLen
);
1301 return lstrlenW( lpszDescription
);
1304 /***********************************************************************
1305 * ImmGetGuideLineA (IMM32.@)
1307 DWORD WINAPI
ImmGetGuideLineA(
1308 HIMC hIMC
, DWORD dwIndex
, LPSTR lpBuf
, DWORD dwBufLen
)
1310 FIXME("(%p, %d, %s, %d): stub\n",
1311 hIMC
, dwIndex
, debugstr_a(lpBuf
), dwBufLen
1313 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1317 /***********************************************************************
1318 * ImmGetGuideLineW (IMM32.@)
1320 DWORD WINAPI
ImmGetGuideLineW(HIMC hIMC
, DWORD dwIndex
, LPWSTR lpBuf
, DWORD dwBufLen
)
1322 FIXME("(%p, %d, %s, %d): stub\n",
1323 hIMC
, dwIndex
, debugstr_w(lpBuf
), dwBufLen
1325 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1329 /***********************************************************************
1330 * ImmGetIMEFileNameA (IMM32.@)
1332 UINT WINAPI
ImmGetIMEFileNameA( HKL hKL
, LPSTR lpszFileName
, UINT uBufLen
)
1335 UINT wBufLen
= uBufLen
;
1338 if (uBufLen
&& lpszFileName
)
1339 bufW
= HeapAlloc(GetProcessHeap(),0,uBufLen
* sizeof(WCHAR
));
1340 else /* We need this to get the number of byte required */
1342 bufW
= HeapAlloc(GetProcessHeap(),0,MAX_PATH
* sizeof(WCHAR
));
1346 rc
= ImmGetIMEFileNameW(hKL
,bufW
,wBufLen
);
1350 if (uBufLen
&& lpszFileName
)
1351 rc
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, lpszFileName
,
1352 uBufLen
, NULL
, NULL
);
1353 else /* get the length */
1354 rc
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
,
1358 HeapFree(GetProcessHeap(),0,bufW
);
1362 /***********************************************************************
1363 * ImmGetIMEFileNameW (IMM32.@)
1365 UINT WINAPI
ImmGetIMEFileNameW(HKL hKL
, LPWSTR lpszFileName
, UINT uBufLen
)
1367 static const WCHAR szImeFileW
[] = {'I','m','e',' ','F','i','l','e',0};
1368 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};
1373 WCHAR regKey
[sizeof(fmt
)/sizeof(WCHAR
)+8];
1375 wsprintfW( regKey
, fmt
, (unsigned)hKL
);
1376 rc
= RegOpenKeyW( HKEY_LOCAL_MACHINE
, regKey
, &hkey
);
1377 if (rc
!= ERROR_SUCCESS
)
1384 rc
= RegGetValueW(hkey
, NULL
, szImeFileW
, RRF_RT_REG_SZ
, NULL
, NULL
, &length
);
1386 if (rc
!= ERROR_SUCCESS
)
1392 if (length
> uBufLen
* sizeof(WCHAR
) || !lpszFileName
)
1397 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1401 return length
/ sizeof(WCHAR
);
1404 RegGetValueW(hkey
, NULL
, szImeFileW
, RRF_RT_REG_SZ
, NULL
, lpszFileName
, &length
);
1408 return length
/ sizeof(WCHAR
);
1411 /***********************************************************************
1412 * ImmGetOpenStatus (IMM32.@)
1414 BOOL WINAPI
ImmGetOpenStatus(HIMC hIMC
)
1416 InputContextData
*data
= (InputContextData
*)hIMC
;
1420 FIXME("(%p): semi-stub\n", hIMC
);
1422 return data
->IMC
.fOpen
;
1425 /***********************************************************************
1426 * ImmGetProperty (IMM32.@)
1428 DWORD WINAPI
ImmGetProperty(HKL hKL
, DWORD fdwIndex
)
1431 TRACE("(%p, %d)\n", hKL
, fdwIndex
);
1436 TRACE("(%s)\n", "IGP_PROPERTY");
1437 rc
= IME_PROP_UNICODE
| IME_PROP_AT_CARET
;
1439 case IGP_CONVERSION
:
1440 FIXME("(%s)\n", "IGP_CONVERSION");
1441 rc
= IME_CMODE_NATIVE
;
1444 FIXME("%s)\n", "IGP_SENTENCE");
1445 rc
= IME_SMODE_AUTOMATIC
;
1447 case IGP_SETCOMPSTR
:
1448 TRACE("(%s)\n", "IGP_SETCOMPSTR");
1452 TRACE("(%s)\n", "IGP_SELECT");
1453 rc
= SELECT_CAP_CONVERSION
| SELECT_CAP_SENTENCE
;
1455 case IGP_GETIMEVERSION
:
1456 TRACE("(%s)\n", "IGP_GETIMEVERSION");
1460 TRACE("(%s)\n", "IGP_UI");
1469 /***********************************************************************
1470 * ImmGetRegisterWordStyleA (IMM32.@)
1472 UINT WINAPI
ImmGetRegisterWordStyleA(
1473 HKL hKL
, UINT nItem
, LPSTYLEBUFA lpStyleBuf
)
1475 FIXME("(%p, %d, %p): stub\n", hKL
, nItem
, lpStyleBuf
);
1476 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1480 /***********************************************************************
1481 * ImmGetRegisterWordStyleW (IMM32.@)
1483 UINT WINAPI
ImmGetRegisterWordStyleW(
1484 HKL hKL
, UINT nItem
, LPSTYLEBUFW lpStyleBuf
)
1486 FIXME("(%p, %d, %p): stub\n", hKL
, nItem
, lpStyleBuf
);
1487 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1491 /***********************************************************************
1492 * ImmGetStatusWindowPos (IMM32.@)
1494 BOOL WINAPI
ImmGetStatusWindowPos(HIMC hIMC
, LPPOINT lpptPos
)
1496 FIXME("(%p, %p): stub\n", hIMC
, lpptPos
);
1497 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1501 /***********************************************************************
1502 * ImmGetVirtualKey (IMM32.@)
1504 UINT WINAPI
ImmGetVirtualKey(HWND hWnd
)
1506 OSVERSIONINFOA version
;
1507 FIXME("(%p): stub\n", hWnd
);
1508 GetVersionExA( &version
);
1509 switch(version
.dwPlatformId
)
1511 case VER_PLATFORM_WIN32_WINDOWS
:
1512 return VK_PROCESSKEY
;
1513 case VER_PLATFORM_WIN32_NT
:
1516 FIXME("%d not supported\n",version
.dwPlatformId
);
1517 return VK_PROCESSKEY
;
1521 /***********************************************************************
1522 * ImmInstallIMEA (IMM32.@)
1524 HKL WINAPI
ImmInstallIMEA(
1525 LPCSTR lpszIMEFileName
, LPCSTR lpszLayoutText
)
1527 FIXME("(%s, %s): stub\n",
1528 debugstr_a(lpszIMEFileName
), debugstr_a(lpszLayoutText
)
1530 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1534 /***********************************************************************
1535 * ImmInstallIMEW (IMM32.@)
1537 HKL WINAPI
ImmInstallIMEW(
1538 LPCWSTR lpszIMEFileName
, LPCWSTR lpszLayoutText
)
1540 FIXME("(%s, %s): stub\n",
1541 debugstr_w(lpszIMEFileName
), debugstr_w(lpszLayoutText
)
1543 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1547 /***********************************************************************
1548 * ImmIsIME (IMM32.@)
1550 BOOL WINAPI
ImmIsIME(HKL hKL
)
1552 TRACE("(%p): semi-stub\n", hKL
);
1554 * FIXME: Dead key locales will return TRUE here when they should not
1555 * There is probably a more proper way to check this.
1557 return (root_context
!= NULL
);
1560 /***********************************************************************
1561 * ImmIsUIMessageA (IMM32.@)
1563 BOOL WINAPI
ImmIsUIMessageA(
1564 HWND hWndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1568 TRACE("(%p, %x, %ld, %ld)\n", hWndIME
, msg
, wParam
, lParam
);
1569 if ((msg
>= WM_IME_STARTCOMPOSITION
&& msg
<= WM_IME_KEYLAST
) ||
1570 (msg
>= WM_IME_SETCONTEXT
&& msg
<= WM_IME_KEYUP
) ||
1571 (msg
== WM_MSIME_SERVICE
) ||
1572 (msg
== WM_MSIME_RECONVERTOPTIONS
) ||
1573 (msg
== WM_MSIME_MOUSE
) ||
1574 (msg
== WM_MSIME_RECONVERTREQUEST
) ||
1575 (msg
== WM_MSIME_RECONVERT
) ||
1576 (msg
== WM_MSIME_QUERYPOSITION
) ||
1577 (msg
== WM_MSIME_DOCUMENTFEED
))
1581 ImmGetDefaultIMEWnd(NULL
);
1583 if (hWndIME
== NULL
)
1584 PostMessageA(hwndDefault
, msg
, wParam
, lParam
);
1591 /***********************************************************************
1592 * ImmIsUIMessageW (IMM32.@)
1594 BOOL WINAPI
ImmIsUIMessageW(
1595 HWND hWndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1598 TRACE("(%p, %d, %ld, %ld): stub\n", hWndIME
, msg
, wParam
, lParam
);
1599 if ((msg
>= WM_IME_STARTCOMPOSITION
&& msg
<= WM_IME_KEYLAST
) ||
1600 (msg
>= WM_IME_SETCONTEXT
&& msg
<= WM_IME_KEYUP
) ||
1601 (msg
== WM_MSIME_SERVICE
) ||
1602 (msg
== WM_MSIME_RECONVERTOPTIONS
) ||
1603 (msg
== WM_MSIME_MOUSE
) ||
1604 (msg
== WM_MSIME_RECONVERTREQUEST
) ||
1605 (msg
== WM_MSIME_RECONVERT
) ||
1606 (msg
== WM_MSIME_QUERYPOSITION
) ||
1607 (msg
== WM_MSIME_DOCUMENTFEED
))
1612 /***********************************************************************
1613 * ImmNotifyIME (IMM32.@)
1615 BOOL WINAPI
ImmNotifyIME(
1616 HIMC hIMC
, DWORD dwAction
, DWORD dwIndex
, DWORD dwValue
)
1620 TRACE("(%p, %d, %d, %d)\n",
1621 hIMC
, dwAction
, dwIndex
, dwValue
);
1628 case NI_CHANGECANDIDATELIST
:
1629 FIXME("%s\n","NI_CHANGECANDIDATELIST");
1631 case NI_CLOSECANDIDATE
:
1632 FIXME("%s\n","NI_CLOSECANDIDATE");
1634 case NI_COMPOSITIONSTR
:
1638 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
1641 LPCOMPOSITIONSTRING lpCompStr
;
1643 if (pX11DRV_ForceXIMReset
)
1644 pX11DRV_ForceXIMReset(root_context
->IMC
.hWnd
);
1646 lpCompStr
= ImmLockIMCC(root_context
->IMC
.hCompStr
);
1647 send
= (lpCompStr
->dwCompStrLen
!= 0);
1648 ImmUnlockIMCC(root_context
->IMC
.hCompStr
);
1650 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1651 root_context
->IMC
.hCompStr
= ImmCreateBlankCompStr();
1654 ImmInternalPostIMEMessage(root_context
, WM_IME_COMPOSITION
, 0,
1660 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE");
1661 if (hIMC
!= (HIMC
)FROM_IME
&& pX11DRV_ForceXIMReset
)
1662 pX11DRV_ForceXIMReset(root_context
->IMC
.hWnd
);
1667 LPCOMPOSITIONSTRING cs
= NULL
;
1668 LPBYTE cdata
= NULL
;
1670 /* clear existing result */
1671 newCompStr
= updateResultStr(root_context
->IMC
.hCompStr
, NULL
, 0);
1672 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1673 root_context
->IMC
.hCompStr
= newCompStr
;
1675 if (root_context
->IMC
.hCompStr
)
1677 cdata
= ImmLockIMCC(root_context
->IMC
.hCompStr
);
1678 cs
= (LPCOMPOSITIONSTRING
)cdata
;
1679 cplen
= cs
->dwCompStrLen
;
1680 cpstr
= (LPWSTR
)&(cdata
[cs
->dwCompStrOffset
]);
1681 ImmUnlockIMCC(root_context
->IMC
.hCompStr
);
1685 WCHAR param
= cpstr
[0];
1686 newCompStr
= updateResultStr(root_context
->IMC
.hCompStr
, cpstr
, cplen
);
1687 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1688 root_context
->IMC
.hCompStr
= newCompStr
;
1689 newCompStr
= updateCompStr(root_context
->IMC
.hCompStr
, NULL
, 0);
1690 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1691 root_context
->IMC
.hCompStr
= newCompStr
;
1693 root_context
->bRead
= FALSE
;
1695 ImmInternalPostIMEMessage(root_context
, WM_IME_COMPOSITION
, 0,
1698 ImmInternalPostIMEMessage(root_context
, WM_IME_COMPOSITION
,
1700 GCS_RESULTSTR
|GCS_RESULTCLAUSE
);
1703 ImmInternalPostIMEMessage(root_context
, WM_IME_ENDCOMPOSITION
, 0, 0);
1704 root_context
->bInComposition
= FALSE
;
1708 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_CONVERT");
1711 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_REVERT");
1714 ERR("%s - %s (%i)\n","NI_COMPOSITIONSTR","UNKNOWN",dwIndex
);
1718 case NI_IMEMENUSELECTED
:
1719 FIXME("%s\n", "NI_IMEMENUSELECTED");
1721 case NI_OPENCANDIDATE
:
1722 FIXME("%s\n", "NI_OPENCANDIDATE");
1724 case NI_SELECTCANDIDATESTR
:
1725 FIXME("%s\n", "NI_SELECTCANDIDATESTR");
1727 case NI_SETCANDIDATE_PAGESIZE
:
1728 FIXME("%s\n", "NI_SETCANDIDATE_PAGESIZE");
1730 case NI_SETCANDIDATE_PAGESTART
:
1731 FIXME("%s\n", "NI_SETCANDIDATE_PAGESTART");
1740 /***********************************************************************
1741 * ImmRegisterWordA (IMM32.@)
1743 BOOL WINAPI
ImmRegisterWordA(
1744 HKL hKL
, LPCSTR lpszReading
, DWORD dwStyle
, LPCSTR lpszRegister
)
1746 FIXME("(%p, %s, %d, %s): stub\n",
1747 hKL
, debugstr_a(lpszReading
), dwStyle
, debugstr_a(lpszRegister
)
1749 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1753 /***********************************************************************
1754 * ImmRegisterWordW (IMM32.@)
1756 BOOL WINAPI
ImmRegisterWordW(
1757 HKL hKL
, LPCWSTR lpszReading
, DWORD dwStyle
, LPCWSTR lpszRegister
)
1759 FIXME("(%p, %s, %d, %s): stub\n",
1760 hKL
, debugstr_w(lpszReading
), dwStyle
, debugstr_w(lpszRegister
)
1762 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1766 /***********************************************************************
1767 * ImmReleaseContext (IMM32.@)
1769 BOOL WINAPI
ImmReleaseContext(HWND hWnd
, HIMC hIMC
)
1771 static int shown
= 0;
1774 FIXME("(%p, %p): stub\n", hWnd
, hIMC
);
1780 /***********************************************************************
1781 * ImmSetCandidateWindow (IMM32.@)
1783 BOOL WINAPI
ImmSetCandidateWindow(
1784 HIMC hIMC
, LPCANDIDATEFORM lpCandidate
)
1786 FIXME("(%p, %p): stub\n", hIMC
, lpCandidate
);
1787 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1791 /***********************************************************************
1792 * ImmSetCompositionFontA (IMM32.@)
1794 BOOL WINAPI
ImmSetCompositionFontA(HIMC hIMC
, LPLOGFONTA lplf
)
1796 InputContextData
*data
= (InputContextData
*)hIMC
;
1797 TRACE("(%p, %p)\n", hIMC
, lplf
);
1802 memcpy(&data
->IMC
.lfFont
.W
,lplf
,sizeof(LOGFONTA
));
1803 MultiByteToWideChar(CP_ACP
, 0, lplf
->lfFaceName
, -1, data
->IMC
.lfFont
.W
.lfFaceName
,
1806 ImmInternalSendIMENotify(data
, IMN_SETCOMPOSITIONFONT
, 0);
1810 DeleteObject(data
->textfont
);
1811 data
->textfont
= NULL
;
1814 data
->textfont
= CreateFontIndirectW(&data
->IMC
.lfFont
.W
);
1818 /***********************************************************************
1819 * ImmSetCompositionFontW (IMM32.@)
1821 BOOL WINAPI
ImmSetCompositionFontW(HIMC hIMC
, LPLOGFONTW lplf
)
1823 InputContextData
*data
= (InputContextData
*)hIMC
;
1824 TRACE("(%p, %p)\n", hIMC
, lplf
);
1829 data
->IMC
.lfFont
.W
= *lplf
;
1830 ImmInternalSendIMENotify(data
, IMN_SETCOMPOSITIONFONT
, 0);
1834 DeleteObject(data
->textfont
);
1835 data
->textfont
= NULL
;
1837 data
->textfont
= CreateFontIndirectW(&data
->IMC
.lfFont
.W
);
1841 /***********************************************************************
1842 * ImmSetCompositionStringA (IMM32.@)
1844 BOOL WINAPI
ImmSetCompositionStringA(
1845 HIMC hIMC
, DWORD dwIndex
,
1846 LPCVOID lpComp
, DWORD dwCompLen
,
1847 LPCVOID lpRead
, DWORD dwReadLen
)
1851 WCHAR
*CompBuffer
= NULL
;
1852 WCHAR
*ReadBuffer
= NULL
;
1855 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1856 hIMC
, dwIndex
, lpComp
, dwCompLen
, lpRead
, dwReadLen
);
1858 comp_len
= MultiByteToWideChar(CP_ACP
, 0, lpComp
, dwCompLen
, NULL
, 0);
1861 CompBuffer
= HeapAlloc(GetProcessHeap(),0,comp_len
* sizeof(WCHAR
));
1862 MultiByteToWideChar(CP_ACP
, 0, lpComp
, dwCompLen
, CompBuffer
, comp_len
);
1865 read_len
= MultiByteToWideChar(CP_ACP
, 0, lpRead
, dwReadLen
, NULL
, 0);
1868 ReadBuffer
= HeapAlloc(GetProcessHeap(),0,read_len
* sizeof(WCHAR
));
1869 MultiByteToWideChar(CP_ACP
, 0, lpRead
, dwReadLen
, ReadBuffer
, read_len
);
1872 rc
= ImmSetCompositionStringW(hIMC
, dwIndex
, CompBuffer
, comp_len
,
1873 ReadBuffer
, read_len
);
1875 HeapFree(GetProcessHeap(), 0, CompBuffer
);
1876 HeapFree(GetProcessHeap(), 0, ReadBuffer
);
1881 /***********************************************************************
1882 * ImmSetCompositionStringW (IMM32.@)
1884 BOOL WINAPI
ImmSetCompositionStringW(
1885 HIMC hIMC
, DWORD dwIndex
,
1886 LPCVOID lpComp
, DWORD dwCompLen
,
1887 LPCVOID lpRead
, DWORD dwReadLen
)
1892 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1893 hIMC
, dwIndex
, lpComp
, dwCompLen
, lpRead
, dwReadLen
);
1896 if (hIMC
!= (HIMC
)FROM_IME
)
1897 FIXME("PROBLEM: This only sets the wine level string\n");
1901 * this sets the composition string in the imm32.dll level
1902 * of the composition buffer. we cannot manipulate the xim level
1903 * buffer, which means that once the xim level buffer changes again
1904 * any call to this function from the application will be lost
1907 if (lpRead
&& dwReadLen
)
1908 FIXME("Reading string unimplemented\n");
1911 * app operating this api to also receive the message from xim
1914 if (dwIndex
== SCS_SETSTR
)
1917 if (!root_context
->bInComposition
)
1919 ImmInternalPostIMEMessage(root_context
, WM_IME_STARTCOMPOSITION
, 0, 0);
1920 root_context
->bInComposition
= TRUE
;
1923 flags
= GCS_COMPSTR
;
1925 if (dwCompLen
&& lpComp
)
1927 newCompStr
= updateCompStr(root_context
->IMC
.hCompStr
, (LPWSTR
)lpComp
, dwCompLen
/ sizeof(WCHAR
));
1928 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1929 root_context
->IMC
.hCompStr
= newCompStr
;
1931 wParam
= ((const WCHAR
*)lpComp
)[0];
1932 flags
|= GCS_COMPCLAUSE
| GCS_COMPATTR
| GCS_DELTASTART
;
1936 newCompStr
= updateCompStr(root_context
->IMC
.hCompStr
, NULL
, 0);
1937 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1938 root_context
->IMC
.hCompStr
= newCompStr
;
1942 UpdateDataInDefaultIMEWindow(hwndDefault
,FALSE
);
1944 ImmInternalPostIMEMessage(root_context
, WM_IME_COMPOSITION
, wParam
, flags
);
1949 /***********************************************************************
1950 * ImmSetCompositionWindow (IMM32.@)
1952 BOOL WINAPI
ImmSetCompositionWindow(
1953 HIMC hIMC
, LPCOMPOSITIONFORM lpCompForm
)
1955 BOOL reshow
= FALSE
;
1956 InputContextData
*data
= (InputContextData
*)hIMC
;
1958 TRACE("(%p, %p)\n", hIMC
, lpCompForm
);
1959 TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm
->dwStyle
,
1960 lpCompForm
->ptCurrentPos
.x
, lpCompForm
->ptCurrentPos
.y
, lpCompForm
->rcArea
.top
,
1961 lpCompForm
->rcArea
.left
, lpCompForm
->rcArea
.bottom
, lpCompForm
->rcArea
.right
);
1966 data
->IMC
.cfCompForm
= *lpCompForm
;
1968 if (IsWindowVisible(hwndDefault
))
1971 ShowWindow(hwndDefault
,SW_HIDE
);
1974 /* FIXME: this is a partial stub */
1977 ShowWindow(hwndDefault
,SW_SHOWNOACTIVATE
);
1979 ImmInternalSendIMENotify(data
, IMN_SETCOMPOSITIONWINDOW
, 0);
1983 /***********************************************************************
1984 * ImmSetConversionStatus (IMM32.@)
1986 BOOL WINAPI
ImmSetConversionStatus(
1987 HIMC hIMC
, DWORD fdwConversion
, DWORD fdwSentence
)
1989 static int shown
= 0;
1992 FIXME("(%p, %d, %d): stub\n",
1993 hIMC
, fdwConversion
, fdwSentence
1997 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2001 /***********************************************************************
2002 * ImmSetOpenStatus (IMM32.@)
2004 BOOL WINAPI
ImmSetOpenStatus(HIMC hIMC
, BOOL fOpen
)
2006 InputContextData
*data
= (InputContextData
*)hIMC
;
2008 TRACE("%p %d\n", hIMC
, fOpen
);
2010 if (hIMC
== (HIMC
)FROM_IME
)
2012 ImmInternalSetOpenStatus(fOpen
);
2013 ImmInternalSendIMENotify(root_context
, IMN_SETOPENSTATUS
, 0);
2020 if (fOpen
!= data
->bInternalState
)
2022 if (fOpen
== FALSE
&& pX11DRV_ForceXIMReset
)
2023 pX11DRV_ForceXIMReset(data
->IMC
.hWnd
);
2026 ImmInternalPostIMEMessage(data
, WM_IME_ENDCOMPOSITION
,0,0);
2028 ImmInternalPostIMEMessage(data
, WM_IME_STARTCOMPOSITION
,0,0);
2030 ImmInternalSetOpenStatus(fOpen
);
2031 ImmInternalSetOpenStatus(!fOpen
);
2033 if (data
->IMC
.fOpen
== FALSE
)
2034 ImmInternalPostIMEMessage(data
, WM_IME_ENDCOMPOSITION
,0,0);
2036 ImmInternalPostIMEMessage(data
, WM_IME_STARTCOMPOSITION
,0,0);
2043 /***********************************************************************
2044 * ImmSetStatusWindowPos (IMM32.@)
2046 BOOL WINAPI
ImmSetStatusWindowPos(HIMC hIMC
, LPPOINT lpptPos
)
2048 FIXME("(%p, %p): stub\n", hIMC
, lpptPos
);
2049 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2053 /***********************************************************************
2054 * ImmSimulateHotKey (IMM32.@)
2056 BOOL WINAPI
ImmSimulateHotKey(HWND hWnd
, DWORD dwHotKeyID
)
2058 FIXME("(%p, %d): stub\n", hWnd
, dwHotKeyID
);
2059 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2063 /***********************************************************************
2064 * ImmUnregisterWordA (IMM32.@)
2066 BOOL WINAPI
ImmUnregisterWordA(
2067 HKL hKL
, LPCSTR lpszReading
, DWORD dwStyle
, LPCSTR lpszUnregister
)
2069 FIXME("(%p, %s, %d, %s): stub\n",
2070 hKL
, debugstr_a(lpszReading
), dwStyle
, debugstr_a(lpszUnregister
)
2072 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2076 /***********************************************************************
2077 * ImmUnregisterWordW (IMM32.@)
2079 BOOL WINAPI
ImmUnregisterWordW(
2080 HKL hKL
, LPCWSTR lpszReading
, DWORD dwStyle
, LPCWSTR lpszUnregister
)
2082 FIXME("(%p, %s, %d, %s): stub\n",
2083 hKL
, debugstr_w(lpszReading
), dwStyle
, debugstr_w(lpszUnregister
)
2085 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2089 /***********************************************************************
2090 * ImmGetImeMenuItemsA (IMM32.@)
2092 DWORD WINAPI
ImmGetImeMenuItemsA( HIMC hIMC
, DWORD dwFlags
, DWORD dwType
,
2093 LPIMEMENUITEMINFOA lpImeParentMenu
, LPIMEMENUITEMINFOA lpImeMenu
,
2096 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC
, dwFlags
, dwType
,
2097 lpImeParentMenu
, lpImeMenu
, dwSize
);
2101 /***********************************************************************
2102 * ImmGetImeMenuItemsW (IMM32.@)
2104 DWORD WINAPI
ImmGetImeMenuItemsW( HIMC hIMC
, DWORD dwFlags
, DWORD dwType
,
2105 LPIMEMENUITEMINFOW lpImeParentMenu
, LPIMEMENUITEMINFOW lpImeMenu
,
2108 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC
, dwFlags
, dwType
,
2109 lpImeParentMenu
, lpImeMenu
, dwSize
);
2113 /***********************************************************************
2114 * ImmLockIMC(IMM32.@)
2116 LPINPUTCONTEXT WINAPI
ImmLockIMC(HIMC hIMC
)
2118 InputContextData
*data
= (InputContextData
*)hIMC
;
2126 /***********************************************************************
2127 * ImmUnlockIMC(IMM32.@)
2129 BOOL WINAPI
ImmUnlockIMC(HIMC hIMC
)
2131 InputContextData
*data
= (InputContextData
*)hIMC
;
2133 return (data
->dwLock
!=0);
2136 /***********************************************************************
2137 * ImmGetIMCLockCount(IMM32.@)
2139 DWORD WINAPI
ImmGetIMCLockCount(HIMC hIMC
)
2141 InputContextData
*data
= (InputContextData
*)hIMC
;
2142 return data
->dwLock
;
2145 /***********************************************************************
2146 * ImmCreateIMCC(IMM32.@)
2148 HIMCC WINAPI
ImmCreateIMCC(DWORD size
)
2150 IMCCInternal
*internal
;
2151 int real_size
= size
+ sizeof(IMCCInternal
);
2153 internal
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, real_size
);
2154 if (internal
== NULL
)
2157 internal
->dwSize
= size
;
2158 return (HIMCC
)internal
;
2161 /***********************************************************************
2162 * ImmDestroyIMCC(IMM32.@)
2164 HIMCC WINAPI
ImmDestroyIMCC(HIMCC block
)
2166 HeapFree(GetProcessHeap(),0,block
);
2170 /***********************************************************************
2171 * ImmLockIMCC(IMM32.@)
2173 LPVOID WINAPI
ImmLockIMCC(HIMCC imcc
)
2175 IMCCInternal
*internal
;
2176 internal
= (IMCCInternal
*) imcc
;
2178 internal
->dwLock
++;
2179 return internal
+ 1;
2182 /***********************************************************************
2183 * ImmUnlockIMCC(IMM32.@)
2185 BOOL WINAPI
ImmUnlockIMCC(HIMCC imcc
)
2187 IMCCInternal
*internal
;
2188 internal
= (IMCCInternal
*) imcc
;
2190 internal
->dwLock
--;
2191 return (internal
->dwLock
!=0);
2194 /***********************************************************************
2195 * ImmGetIMCCLockCount(IMM32.@)
2197 DWORD WINAPI
ImmGetIMCCLockCount(HIMCC imcc
)
2199 IMCCInternal
*internal
;
2200 internal
= (IMCCInternal
*) imcc
;
2202 return internal
->dwLock
;
2205 /***********************************************************************
2206 * ImmReSizeIMCC(IMM32.@)
2208 HIMCC WINAPI
ImmReSizeIMCC(HIMCC imcc
, DWORD size
)
2210 IMCCInternal
*internal
,*newone
;
2211 int real_size
= size
+ sizeof(IMCCInternal
);
2213 internal
= (IMCCInternal
*) imcc
;
2215 newone
= HeapReAlloc(GetProcessHeap(), 0, internal
, real_size
);
2216 newone
->dwSize
= size
;
2221 /***********************************************************************
2222 * ImmGetIMCCSize(IMM32.@)
2224 DWORD WINAPI
ImmGetIMCCSize(HIMCC imcc
)
2226 IMCCInternal
*internal
;
2227 internal
= (IMCCInternal
*) imcc
;
2229 return internal
->dwSize
;
2232 /***********************************************************************
2233 * ImmGenerateMessage(IMM32.@)
2235 BOOL WINAPI
ImmGenerateMessage(HIMC hIMC
)
2237 InputContextData
*data
= (InputContextData
*)hIMC
;
2239 TRACE("%i messages queued\n",data
->IMC
.dwNumMsgBuf
);
2240 if (data
->IMC
.dwNumMsgBuf
> 0)
2242 LPTRANSMSG lpTransMsg
;
2245 lpTransMsg
= (LPTRANSMSG
)ImmLockIMCC(data
->IMC
.hMsgBuf
);
2246 for (i
= 0; i
< data
->IMC
.dwNumMsgBuf
; i
++)
2247 ImmInternalPostIMEMessage(data
, lpTransMsg
[i
].message
, lpTransMsg
[i
].wParam
, lpTransMsg
[i
].lParam
);
2249 ImmUnlockIMCC(data
->IMC
.hMsgBuf
);
2251 data
->IMC
.dwNumMsgBuf
= 0;
2258 * Internal functions to help with IME window management
2260 static void PaintDefaultIMEWnd(HWND hwnd
)
2264 HDC hdc
= BeginPaint(hwnd
,&ps
);
2265 LPCOMPOSITIONSTRING compstr
;
2266 LPBYTE compdata
= NULL
;
2268 MONITORINFO mon_info
;
2271 GetClientRect(hwnd
,&rect
);
2272 FillRect(hdc
, &rect
, (HBRUSH
)(COLOR_WINDOW
+ 1));
2274 compdata
= ImmLockIMCC(root_context
->IMC
.hCompStr
);
2275 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
2277 if (compstr
->dwCompStrLen
&& compstr
->dwCompStrOffset
)
2281 HFONT oldfont
= NULL
;
2284 CompString
= (LPWSTR
)(compdata
+ compstr
->dwCompStrOffset
);
2285 if (root_context
->textfont
)
2286 oldfont
= SelectObject(hdc
,root_context
->textfont
);
2289 GetTextExtentPoint32W(hdc
, CompString
, compstr
->dwCompStrLen
, &size
);
2295 * How this works based on tests on windows:
2296 * CFS_POINT: then we start our window at the point and grow it as large
2297 * as it needs to be for the string.
2298 * CFS_RECT: we still use the ptCurrentPos as a starting point and our
2299 * window is only as large as we need for the string, but we do not
2300 * grow such that our window exceeds the given rect. Wrapping if
2301 * needed and possible. If our ptCurrentPos is outside of our rect
2302 * then no window is displayed.
2303 * CFS_FORCE_POSITION: appears to behave just like CFS_POINT
2304 * maybe becase the default MSIME does not do any IME adjusting.
2306 if (root_context
->IMC
.cfCompForm
.dwStyle
!= CFS_DEFAULT
)
2308 POINT cpt
= root_context
->IMC
.cfCompForm
.ptCurrentPos
;
2309 ClientToScreen(root_context
->IMC
.hWnd
,&cpt
);
2312 rect
.right
= rect
.left
+ pt
.x
;
2313 rect
.bottom
= rect
.top
+ pt
.y
;
2314 monitor
= MonitorFromPoint(cpt
, MONITOR_DEFAULTTOPRIMARY
);
2316 else /* CFS_DEFAULT */
2318 /* Windows places the default IME window in the bottom left */
2319 HWND target
= root_context
->IMC
.hWnd
;
2320 if (!target
) target
= GetFocus();
2322 GetWindowRect(target
,&rect
);
2323 rect
.top
= rect
.bottom
;
2324 rect
.right
= rect
.left
+ pt
.x
+ 20;
2325 rect
.bottom
= rect
.top
+ pt
.y
+ 20;
2327 monitor
= MonitorFromWindow(target
, MONITOR_DEFAULTTOPRIMARY
);
2330 if (root_context
->IMC
.cfCompForm
.dwStyle
== CFS_RECT
)
2333 client
=root_context
->IMC
.cfCompForm
.rcArea
;
2334 MapWindowPoints( root_context
->IMC
.hWnd
, 0, (POINT
*)&client
, 2 );
2335 IntersectRect(&rect
,&rect
,&client
);
2336 /* TODO: Wrap the input if needed */
2339 if (root_context
->IMC
.cfCompForm
.dwStyle
== CFS_DEFAULT
)
2341 /* make sure we are on the desktop */
2342 mon_info
.cbSize
= sizeof(mon_info
);
2343 GetMonitorInfoW(monitor
, &mon_info
);
2345 if (rect
.bottom
> mon_info
.rcWork
.bottom
)
2347 int shift
= rect
.bottom
- mon_info
.rcWork
.bottom
;
2349 rect
.bottom
-= shift
;
2353 rect
.right
-= rect
.left
;
2356 if (rect
.right
> mon_info
.rcWork
.right
)
2358 int shift
= rect
.right
- mon_info
.rcWork
.right
;
2360 rect
.right
-= shift
;
2364 SetWindowPos(hwnd
, HWND_TOPMOST
, rect
.left
, rect
.top
, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
, SWP_NOACTIVATE
);
2366 TextOutW(hdc
, offX
,offY
, CompString
, compstr
->dwCompStrLen
);
2369 SelectObject(hdc
,oldfont
);
2372 ImmUnlockIMCC(root_context
->IMC
.hCompStr
);
2377 static void UpdateDataInDefaultIMEWindow(HWND hwnd
, BOOL showable
)
2379 LPCOMPOSITIONSTRING compstr
;
2381 if (root_context
->IMC
.hCompStr
)
2382 compstr
= ImmLockIMCC(root_context
->IMC
.hCompStr
);
2386 if (compstr
== NULL
|| compstr
->dwCompStrLen
== 0)
2387 ShowWindow(hwndDefault
,SW_HIDE
);
2389 ShowWindow(hwndDefault
,SW_SHOWNOACTIVATE
);
2391 RedrawWindow(hwnd
,NULL
,NULL
,RDW_ERASENOW
|RDW_INVALIDATE
);
2393 if (compstr
!= NULL
)
2394 ImmUnlockIMCC(root_context
->IMC
.hCompStr
);
2398 * The window proc for the default IME window
2400 static LRESULT WINAPI
IME_WindowProc(HWND hwnd
, UINT msg
, WPARAM wParam
,
2405 TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", msg
, (UINT
)wParam
,
2411 PaintDefaultIMEWnd(hwnd
);
2418 SetWindowTextA(hwnd
,"Wine Ime Active");
2423 SetFocus((HWND
)wParam
);
2425 FIXME("Received focus, should never have focus\n");
2427 case WM_IME_COMPOSITION
:
2428 TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
2429 "WM_IME_COMPOSITION", (UINT
)wParam
, (UINT
)lParam
,
2430 root_context
->bRead
);
2431 if (lParam
& GCS_RESULTSTR
)
2432 IMM_PostResult(root_context
);
2434 UpdateDataInDefaultIMEWindow(hwnd
,TRUE
);
2436 case WM_IME_STARTCOMPOSITION
:
2437 TRACE("IME message %s, 0x%x, 0x%x\n",
2438 "WM_IME_STARTCOMPOSITION", (UINT
)wParam
, (UINT
)lParam
);
2439 root_context
->IMC
.hWnd
= GetFocus();
2440 ShowWindow(hwndDefault
,SW_SHOWNOACTIVATE
);
2442 case WM_IME_ENDCOMPOSITION
:
2443 TRACE("IME message %s, 0x%x, 0x%x\n",
2444 "WM_IME_ENDCOMPOSITION", (UINT
)wParam
, (UINT
)lParam
);
2445 ShowWindow(hwndDefault
,SW_HIDE
);
2448 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
2449 (UINT
)wParam
, (UINT
)lParam
);
2451 case WM_IME_CONTROL
:
2452 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
2453 (UINT
)wParam
, (UINT
)lParam
);
2457 TRACE("!! IME NOTIFY\n");
2460 TRACE("Non-standard message 0x%x\n",msg
);
2462 /* check the MSIME messages */
2463 if (msg
== WM_MSIME_SERVICE
)
2465 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
2466 (UINT
)wParam
, (UINT
)lParam
);
2469 else if (msg
== WM_MSIME_RECONVERTOPTIONS
)
2471 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
2472 (UINT
)wParam
, (UINT
)lParam
);
2474 else if (msg
== WM_MSIME_MOUSE
)
2476 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
2477 (UINT
)wParam
, (UINT
)lParam
);
2479 else if (msg
== WM_MSIME_RECONVERTREQUEST
)
2481 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
2482 (UINT
)wParam
, (UINT
)lParam
);
2484 else if (msg
== WM_MSIME_RECONVERT
)
2486 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
2487 (UINT
)wParam
, (UINT
)lParam
);
2489 else if (msg
== WM_MSIME_QUERYPOSITION
)
2491 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
2492 (UINT
)wParam
, (UINT
)lParam
);
2494 else if (msg
== WM_MSIME_DOCUMENTFEED
)
2496 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
2497 (UINT
)wParam
, (UINT
)lParam
);
2499 /* DefWndProc if not an IME message */
2500 else if (!rc
&& !((msg
>= WM_IME_STARTCOMPOSITION
&& msg
<= WM_IME_KEYLAST
) ||
2501 (msg
>= WM_IME_SETCONTEXT
&& msg
<= WM_IME_KEYUP
)))
2502 rc
= DefWindowProcW(hwnd
,msg
,wParam
,lParam
);