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"
35 WINE_DEFAULT_DEBUG_CHANNEL(imm
);
37 #define FROM_IME 0xcafe1337
39 static void (*pX11DRV_ForceXIMReset
)(HWND
);
41 typedef struct tagIMCCInternal
47 typedef struct tagInputContextData
58 typedef struct _tagTRANSMSG
{
62 } TRANSMSG
, *LPTRANSMSG
;
64 static InputContextData
*root_context
= NULL
;
65 static HWND hwndDefault
= NULL
;
66 static HANDLE hImeInst
;
67 static const WCHAR WC_IMECLASSNAME
[] = {'I','M','E',0};
68 static ATOM atIMEClass
= 0;
71 static UINT WM_MSIME_SERVICE
;
72 static UINT WM_MSIME_RECONVERTOPTIONS
;
73 static UINT WM_MSIME_MOUSE
;
74 static UINT WM_MSIME_RECONVERTREQUEST
;
75 static UINT WM_MSIME_RECONVERT
;
76 static UINT WM_MSIME_QUERYPOSITION
;
77 static UINT WM_MSIME_DOCUMENTFEED
;
82 static LRESULT WINAPI
IME_WindowProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
,
84 static void UpdateDataInDefaultIMEWindow(HWND hwnd
, BOOL showable
);
85 static void ImmInternalPostIMEMessage(UINT
, WPARAM
, LPARAM
);
86 static void ImmInternalSetOpenStatus(BOOL fOpen
);
87 static HIMCC
updateResultStr(HIMCC old
, LPWSTR resultstr
, DWORD len
);
89 static VOID
IMM_PostResult(InputContextData
*data
)
92 LPCOMPOSITIONSTRING compstr
;
97 TRACE("Posting result as IME_CHAR\n");
98 compdata
= ImmLockIMCC(root_context
->IMC
.hCompStr
);
99 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
100 ResultStr
= (LPWSTR
)(compdata
+ compstr
->dwResultStrOffset
);
102 for (i
= 0; i
< compstr
->dwResultStrLen
; i
++)
103 ImmInternalPostIMEMessage (WM_IME_CHAR
, ResultStr
[i
], 1);
105 ImmUnlockIMCC(root_context
->IMC
.hCompStr
);
107 /* clear the buffer */
108 newCompStr
= updateResultStr(root_context
->IMC
.hCompStr
, NULL
, 0);
109 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
110 root_context
->IMC
.hCompStr
= newCompStr
;
113 static void IMM_Register(void)
116 ZeroMemory(&wndClass
, sizeof(WNDCLASSW
));
117 wndClass
.style
= CS_GLOBALCLASS
| CS_IME
| CS_HREDRAW
| CS_VREDRAW
;
118 wndClass
.lpfnWndProc
= (WNDPROC
) IME_WindowProc
;
119 wndClass
.cbClsExtra
= 0;
120 wndClass
.cbWndExtra
= 0;
121 wndClass
.hInstance
= hImeInst
;
122 wndClass
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
123 wndClass
.hIcon
= NULL
;
124 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+1);
125 wndClass
.lpszMenuName
= 0;
126 wndClass
.lpszClassName
= WC_IMECLASSNAME
;
127 atIMEClass
= RegisterClassW(&wndClass
);
130 static void IMM_Unregister(void)
133 UnregisterClassW(WC_IMECLASSNAME
, NULL
);
137 static void IMM_RegisterMessages(void)
139 WM_MSIME_SERVICE
= RegisterWindowMessageA("MSIMEService");
140 WM_MSIME_RECONVERTOPTIONS
= RegisterWindowMessageA("MSIMEReconvertOptions");
141 WM_MSIME_MOUSE
= RegisterWindowMessageA("MSIMEMouseOperation");
142 WM_MSIME_RECONVERTREQUEST
= RegisterWindowMessageA("MSIMEReconvertRequest");
143 WM_MSIME_RECONVERT
= RegisterWindowMessageA("MSIMEReconvert");
144 WM_MSIME_QUERYPOSITION
= RegisterWindowMessageA("MSIMEQueryPosition");
145 WM_MSIME_DOCUMENTFEED
= RegisterWindowMessageA("MSIMEDocumentFeed");
149 BOOL WINAPI
DllMain(HINSTANCE hInstDLL
, DWORD fdwReason
, LPVOID lpReserved
)
153 TRACE("%p, %x, %p\n",hInstDLL
,fdwReason
,lpReserved
);
156 case DLL_PROCESS_ATTACH
:
157 DisableThreadLibraryCalls(hInstDLL
);
159 IMM_RegisterMessages();
160 x11drv
= GetModuleHandleA("winex11.drv");
161 if (x11drv
) pX11DRV_ForceXIMReset
= (void *)GetProcAddress( x11drv
, "ForceXIMReset");
163 case DLL_PROCESS_DETACH
:
166 DestroyWindow(hwndDefault
);
175 /* for posting messages as the IME */
176 static void ImmInternalPostIMEMessage(UINT msg
, WPARAM wParam
, LPARAM lParam
)
178 HWND target
= GetFocus();
180 PostMessageW(root_context
->IMC
.hWnd
,msg
,wParam
,lParam
);
182 PostMessageW(target
, msg
, wParam
, lParam
);
185 static LRESULT
ImmInternalSendIMENotify(WPARAM notify
, LPARAM lParam
)
189 target
= root_context
->IMC
.hWnd
;
190 if (!target
) target
= GetFocus();
193 return SendMessageW(target
, WM_IME_NOTIFY
, notify
, lParam
);
198 static HIMCC
ImmCreateBlankCompStr(void)
201 LPCOMPOSITIONSTRING ptr
;
202 rc
= ImmCreateIMCC(sizeof(COMPOSITIONSTRING
));
203 ptr
= (LPCOMPOSITIONSTRING
)ImmLockIMCC(rc
);
204 memset(ptr
,0,sizeof(COMPOSITIONSTRING
));
205 ptr
->dwSize
= sizeof(COMPOSITIONSTRING
);
210 static void ImmInternalSetOpenStatus(BOOL fOpen
)
212 TRACE("Setting internal state to %s\n",(fOpen
)?"OPEN":"CLOSED");
214 if (root_context
->IMC
.fOpen
&& fOpen
== FALSE
)
216 ShowWindow(hwndDefault
,SW_HIDE
);
217 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
218 root_context
->IMC
.hCompStr
= ImmCreateBlankCompStr();
221 root_context
->IMC
.fOpen
= fOpen
;
222 root_context
->bInternalState
= fOpen
;
224 ImmInternalSendIMENotify(IMN_SETOPENSTATUS
, 0);
227 static int updateField(DWORD origLen
, DWORD origOffset
, DWORD currentOffset
,
228 LPBYTE target
, LPBYTE source
, DWORD
* lenParam
,
229 DWORD
* offsetParam
, BOOL wchars
)
231 if (origLen
> 0 && origOffset
> 0)
233 int truelen
= origLen
;
235 truelen
*= sizeof(WCHAR
);
237 memcpy(&target
[currentOffset
], &source
[origOffset
], truelen
);
240 *offsetParam
= currentOffset
;
241 currentOffset
+= truelen
;
243 return currentOffset
;
246 static HIMCC
updateCompStr(HIMCC old
, LPWSTR compstr
, DWORD len
)
248 /* we need to make sure the CompStr, CompClaus and CompAttr fields are all
252 LPBYTE newdata
= NULL
;
253 LPBYTE olddata
= NULL
;
254 LPCOMPOSITIONSTRING new_one
;
255 LPCOMPOSITIONSTRING lpcs
= NULL
;
256 INT current_offset
= 0;
258 TRACE("%s, %i\n",debugstr_wn(compstr
,len
),len
);
260 if (old
== NULL
&& compstr
== NULL
&& len
== 0)
265 olddata
= ImmLockIMCC(old
);
266 lpcs
= (LPCOMPOSITIONSTRING
)olddata
;
269 needed_size
= sizeof(COMPOSITIONSTRING
) + len
* sizeof(WCHAR
) +
270 len
+ sizeof(DWORD
) * 2;
274 needed_size
+= lpcs
->dwCompReadAttrLen
;
275 needed_size
+= lpcs
->dwCompReadClauseLen
;
276 needed_size
+= lpcs
->dwCompReadStrLen
* sizeof(DWORD
);
277 needed_size
+= lpcs
->dwResultReadClauseLen
;
278 needed_size
+= lpcs
->dwResultReadStrLen
* sizeof(DWORD
);
279 needed_size
+= lpcs
->dwResultClauseLen
;
280 needed_size
+= lpcs
->dwResultStrLen
* sizeof(DWORD
);
281 needed_size
+= lpcs
->dwPrivateSize
;
283 rc
= ImmCreateIMCC(needed_size
);
284 newdata
= ImmLockIMCC(rc
);
285 new_one
= (LPCOMPOSITIONSTRING
)newdata
;
287 new_one
->dwSize
= needed_size
;
288 current_offset
= sizeof(COMPOSITIONSTRING
);
291 current_offset
= updateField(lpcs
->dwCompReadAttrLen
,
292 lpcs
->dwCompReadAttrOffset
,
293 current_offset
, newdata
, olddata
,
294 &new_one
->dwCompReadAttrLen
,
295 &new_one
->dwCompReadAttrOffset
, FALSE
);
297 current_offset
= updateField(lpcs
->dwCompReadClauseLen
,
298 lpcs
->dwCompReadClauseOffset
,
299 current_offset
, newdata
, olddata
,
300 &new_one
->dwCompReadClauseLen
,
301 &new_one
->dwCompReadClauseOffset
, FALSE
);
303 current_offset
= updateField(lpcs
->dwCompReadStrLen
,
304 lpcs
->dwCompReadStrOffset
,
305 current_offset
, newdata
, olddata
,
306 &new_one
->dwCompReadStrLen
,
307 &new_one
->dwCompReadStrOffset
, TRUE
);
309 /* new CompAttr, CompClause, CompStr, dwCursorPos */
310 new_one
->dwDeltaStart
= 0;
312 current_offset
= updateField(lpcs
->dwResultReadClauseLen
,
313 lpcs
->dwResultReadClauseOffset
,
314 current_offset
, newdata
, olddata
,
315 &new_one
->dwResultReadClauseLen
,
316 &new_one
->dwResultReadClauseOffset
, FALSE
);
318 current_offset
= updateField(lpcs
->dwResultReadStrLen
,
319 lpcs
->dwResultReadStrOffset
,
320 current_offset
, newdata
, olddata
,
321 &new_one
->dwResultReadStrLen
,
322 &new_one
->dwResultReadStrOffset
, TRUE
);
324 current_offset
= updateField(lpcs
->dwResultClauseLen
,
325 lpcs
->dwResultClauseOffset
,
326 current_offset
, newdata
, olddata
,
327 &new_one
->dwResultClauseLen
,
328 &new_one
->dwResultClauseOffset
, FALSE
);
330 current_offset
= updateField(lpcs
->dwResultStrLen
,
331 lpcs
->dwResultStrOffset
,
332 current_offset
, newdata
, olddata
,
333 &new_one
->dwResultStrLen
,
334 &new_one
->dwResultStrOffset
, TRUE
);
336 current_offset
= updateField(lpcs
->dwPrivateSize
,
337 lpcs
->dwPrivateOffset
,
338 current_offset
, newdata
, olddata
,
339 &new_one
->dwPrivateSize
,
340 &new_one
->dwPrivateOffset
, FALSE
);
345 new_one
->dwCompAttrLen
= len
;
348 new_one
->dwCompAttrOffset
= current_offset
;
349 memset(&newdata
[current_offset
],ATTR_INPUT
,len
);
350 current_offset
+= len
;
356 new_one
->dwCompClauseLen
= sizeof(DWORD
) * 2;
357 new_one
->dwCompClauseOffset
= current_offset
;
358 *(DWORD
*)(&newdata
[current_offset
]) = 0;
359 current_offset
+= sizeof(DWORD
);
360 *(DWORD
*)(&newdata
[current_offset
]) = len
;
361 current_offset
+= sizeof(DWORD
);
365 new_one
->dwCompStrLen
= len
;
368 new_one
->dwCompStrOffset
= current_offset
;
369 memcpy(&newdata
[current_offset
],compstr
,len
*sizeof(WCHAR
));
373 new_one
->dwCursorPos
= len
;
382 static HIMCC
updateResultStr(HIMCC old
, LPWSTR resultstr
, DWORD len
)
384 /* we need to make sure the ResultStr and ResultClause fields are all
388 LPBYTE newdata
= NULL
;
389 LPBYTE olddata
= NULL
;
390 LPCOMPOSITIONSTRING new_one
;
391 LPCOMPOSITIONSTRING lpcs
= NULL
;
392 INT current_offset
= 0;
394 TRACE("%s, %i\n",debugstr_wn(resultstr
,len
),len
);
396 if (old
== NULL
&& resultstr
== NULL
&& len
== 0)
401 olddata
= ImmLockIMCC(old
);
402 lpcs
= (LPCOMPOSITIONSTRING
)olddata
;
405 needed_size
= sizeof(COMPOSITIONSTRING
) + len
* sizeof(WCHAR
) +
410 needed_size
+= lpcs
->dwCompReadAttrLen
;
411 needed_size
+= lpcs
->dwCompReadClauseLen
;
412 needed_size
+= lpcs
->dwCompReadStrLen
* sizeof(DWORD
);
413 needed_size
+= lpcs
->dwCompAttrLen
;
414 needed_size
+= lpcs
->dwCompClauseLen
;
415 needed_size
+= lpcs
->dwCompStrLen
* sizeof(DWORD
);
416 needed_size
+= lpcs
->dwResultReadClauseLen
;
417 needed_size
+= lpcs
->dwResultReadStrLen
* sizeof(DWORD
);
418 needed_size
+= lpcs
->dwPrivateSize
;
420 rc
= ImmCreateIMCC(needed_size
);
421 newdata
= ImmLockIMCC(rc
);
422 new_one
= (LPCOMPOSITIONSTRING
)newdata
;
424 new_one
->dwSize
= needed_size
;
425 current_offset
= sizeof(COMPOSITIONSTRING
);
428 current_offset
= updateField(lpcs
->dwCompReadAttrLen
,
429 lpcs
->dwCompReadAttrOffset
,
430 current_offset
, newdata
, olddata
,
431 &new_one
->dwCompReadAttrLen
,
432 &new_one
->dwCompReadAttrOffset
, FALSE
);
434 current_offset
= updateField(lpcs
->dwCompReadClauseLen
,
435 lpcs
->dwCompReadClauseOffset
,
436 current_offset
, newdata
, olddata
,
437 &new_one
->dwCompReadClauseLen
,
438 &new_one
->dwCompReadClauseOffset
, FALSE
);
440 current_offset
= updateField(lpcs
->dwCompReadStrLen
,
441 lpcs
->dwCompReadStrOffset
,
442 current_offset
, newdata
, olddata
,
443 &new_one
->dwCompReadStrLen
,
444 &new_one
->dwCompReadStrOffset
, TRUE
);
446 current_offset
= updateField(lpcs
->dwCompAttrLen
,
447 lpcs
->dwCompAttrOffset
,
448 current_offset
, newdata
, olddata
,
449 &new_one
->dwCompAttrLen
,
450 &new_one
->dwCompAttrOffset
, FALSE
);
452 current_offset
= updateField(lpcs
->dwCompClauseLen
,
453 lpcs
->dwCompClauseOffset
,
454 current_offset
, newdata
, olddata
,
455 &new_one
->dwCompClauseLen
,
456 &new_one
->dwCompClauseOffset
, FALSE
);
458 current_offset
= updateField(lpcs
->dwCompStrLen
,
459 lpcs
->dwCompStrOffset
,
460 current_offset
, newdata
, olddata
,
461 &new_one
->dwCompStrLen
,
462 &new_one
->dwCompStrOffset
, TRUE
);
464 new_one
->dwCursorPos
= lpcs
->dwCursorPos
;
465 new_one
->dwDeltaStart
= 0;
467 current_offset
= updateField(lpcs
->dwResultReadClauseLen
,
468 lpcs
->dwResultReadClauseOffset
,
469 current_offset
, newdata
, olddata
,
470 &new_one
->dwResultReadClauseLen
,
471 &new_one
->dwResultReadClauseOffset
, FALSE
);
473 current_offset
= updateField(lpcs
->dwResultReadStrLen
,
474 lpcs
->dwResultReadStrOffset
,
475 current_offset
, newdata
, olddata
,
476 &new_one
->dwResultReadStrLen
,
477 &new_one
->dwResultReadStrOffset
, TRUE
);
479 /* new ResultClause , ResultStr */
481 current_offset
= updateField(lpcs
->dwPrivateSize
,
482 lpcs
->dwPrivateOffset
,
483 current_offset
, newdata
, olddata
,
484 &new_one
->dwPrivateSize
,
485 &new_one
->dwPrivateOffset
, FALSE
);
492 new_one
->dwResultClauseLen
= sizeof(DWORD
) * 2;
493 new_one
->dwResultClauseOffset
= current_offset
;
494 *(DWORD
*)(&newdata
[current_offset
]) = 0;
495 current_offset
+= sizeof(DWORD
);
496 *(DWORD
*)(&newdata
[current_offset
]) = len
;
497 current_offset
+= sizeof(DWORD
);
501 new_one
->dwResultStrLen
= len
;
504 new_one
->dwResultStrOffset
= current_offset
;
505 memcpy(&newdata
[current_offset
],resultstr
,len
*sizeof(WCHAR
));
516 /***********************************************************************
517 * ImmAssociateContext (IMM32.@)
519 HIMC WINAPI
ImmAssociateContext(HWND hWnd
, HIMC hIMC
)
521 InputContextData
*data
= (InputContextData
*)hIMC
;
523 WARN("(%p, %p): semi-stub\n", hWnd
, hIMC
);
529 * WINE SPECIFIC! MAY CONFLICT
530 * associate the root context we have an XIM created
534 root_context
= (InputContextData
*)hIMC
;
538 * If already associated just return
540 if (data
->IMC
.hWnd
== hWnd
)
543 if (IsWindow(data
->IMC
.hWnd
))
546 * Post a message that your context is switching
548 SendMessageW(data
->IMC
.hWnd
, WM_IME_SETCONTEXT
, FALSE
, ISC_SHOWUIALL
);
551 data
->IMC
.hWnd
= hWnd
;
553 if (IsWindow(data
->IMC
.hWnd
))
556 * Post a message that your context is switching
558 SendMessageW(data
->IMC
.hWnd
, WM_IME_SETCONTEXT
, TRUE
, ISC_SHOWUIALL
);
562 * TODO: We need to keep track of the old context associated
563 * with a window and return it for now we will return NULL;
568 /***********************************************************************
569 * ImmAssociateContextEx (IMM32.@)
571 BOOL WINAPI
ImmAssociateContextEx(HWND hWnd
, HIMC hIMC
, DWORD dwFlags
)
573 FIXME("(%p, %p, %d): stub\n", hWnd
, hIMC
, dwFlags
);
574 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
578 /***********************************************************************
579 * ImmConfigureIMEA (IMM32.@)
581 BOOL WINAPI
ImmConfigureIMEA(
582 HKL hKL
, HWND hWnd
, DWORD dwMode
, LPVOID lpData
)
584 FIXME("(%p, %p, %d, %p): stub\n",
585 hKL
, hWnd
, dwMode
, lpData
587 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
591 /***********************************************************************
592 * ImmConfigureIMEW (IMM32.@)
594 BOOL WINAPI
ImmConfigureIMEW(
595 HKL hKL
, HWND hWnd
, DWORD dwMode
, LPVOID lpData
)
597 FIXME("(%p, %p, %d, %p): stub\n",
598 hKL
, hWnd
, dwMode
, lpData
600 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
604 /***********************************************************************
605 * ImmCreateContext (IMM32.@)
607 HIMC WINAPI
ImmCreateContext(void)
609 InputContextData
*new_context
;
611 new_context
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(InputContextData
));
613 /* hCompStr is never NULL */
614 new_context
->IMC
.hCompStr
= ImmCreateBlankCompStr();
615 new_context
->IMC
.hMsgBuf
= ImmCreateIMCC(1);
617 return (HIMC
)new_context
;
620 /***********************************************************************
621 * ImmDestroyContext (IMM32.@)
623 BOOL WINAPI
ImmDestroyContext(HIMC hIMC
)
625 InputContextData
*data
= (InputContextData
*)hIMC
;
627 TRACE("Destroying %p\n",hIMC
);
631 ImmDestroyIMCC(data
->IMC
.hCompStr
);
632 ImmDestroyIMCC(data
->IMC
.hCandInfo
);
633 ImmDestroyIMCC(data
->IMC
.hGuideLine
);
634 ImmDestroyIMCC(data
->IMC
.hPrivate
);
635 ImmDestroyIMCC(data
->IMC
.hMsgBuf
);
639 DeleteObject(data
->textfont
);
640 data
->textfont
= NULL
;
643 HeapFree(GetProcessHeap(),0,data
);
648 /***********************************************************************
649 * ImmDisableIME (IMM32.@)
651 BOOL WINAPI
ImmDisableIME(DWORD idThread
)
653 FIXME("(%d): stub\n", idThread
);
657 /***********************************************************************
658 * ImmEnumRegisterWordA (IMM32.@)
660 UINT WINAPI
ImmEnumRegisterWordA(
661 HKL hKL
, REGISTERWORDENUMPROCA lpfnEnumProc
,
662 LPCSTR lpszReading
, DWORD dwStyle
,
663 LPCSTR lpszRegister
, LPVOID lpData
)
665 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
667 debugstr_a(lpszReading
), dwStyle
,
668 debugstr_a(lpszRegister
), lpData
670 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
674 /***********************************************************************
675 * ImmEnumRegisterWordW (IMM32.@)
677 UINT WINAPI
ImmEnumRegisterWordW(
678 HKL hKL
, REGISTERWORDENUMPROCW lpfnEnumProc
,
679 LPCWSTR lpszReading
, DWORD dwStyle
,
680 LPCWSTR lpszRegister
, LPVOID lpData
)
682 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
684 debugstr_w(lpszReading
), dwStyle
,
685 debugstr_w(lpszRegister
), lpData
687 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
691 /***********************************************************************
692 * ImmEscapeA (IMM32.@)
694 LRESULT WINAPI
ImmEscapeA(
696 UINT uEscape
, LPVOID lpData
)
698 FIXME("(%p, %p, %d, %p): stub\n",
699 hKL
, hIMC
, uEscape
, lpData
701 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
705 /***********************************************************************
706 * ImmEscapeW (IMM32.@)
708 LRESULT WINAPI
ImmEscapeW(
710 UINT uEscape
, LPVOID lpData
)
712 FIXME("(%p, %p, %d, %p): stub\n",
713 hKL
, hIMC
, uEscape
, lpData
715 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
719 /***********************************************************************
720 * ImmGetCandidateListA (IMM32.@)
722 DWORD WINAPI
ImmGetCandidateListA(
723 HIMC hIMC
, DWORD deIndex
,
724 LPCANDIDATELIST lpCandList
, DWORD dwBufLen
)
726 FIXME("(%p, %d, %p, %d): stub\n",
730 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
734 /***********************************************************************
735 * ImmGetCandidateListCountA (IMM32.@)
737 DWORD WINAPI
ImmGetCandidateListCountA(
738 HIMC hIMC
, LPDWORD lpdwListCount
)
740 FIXME("(%p, %p): stub\n", hIMC
, lpdwListCount
);
741 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
745 /***********************************************************************
746 * ImmGetCandidateListCountW (IMM32.@)
748 DWORD WINAPI
ImmGetCandidateListCountW(
749 HIMC hIMC
, LPDWORD lpdwListCount
)
751 FIXME("(%p, %p): stub\n", hIMC
, lpdwListCount
);
752 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
756 /***********************************************************************
757 * ImmGetCandidateListW (IMM32.@)
759 DWORD WINAPI
ImmGetCandidateListW(
760 HIMC hIMC
, DWORD deIndex
,
761 LPCANDIDATELIST lpCandList
, DWORD dwBufLen
)
763 FIXME("(%p, %d, %p, %d): stub\n",
767 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
771 /***********************************************************************
772 * ImmGetCandidateWindow (IMM32.@)
774 BOOL WINAPI
ImmGetCandidateWindow(
775 HIMC hIMC
, DWORD dwBufLen
, LPCANDIDATEFORM lpCandidate
)
777 FIXME("(%p, %d, %p): stub\n", hIMC
, dwBufLen
, lpCandidate
);
778 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
782 /***********************************************************************
783 * ImmGetCompositionFontA (IMM32.@)
785 BOOL WINAPI
ImmGetCompositionFontA(HIMC hIMC
, LPLOGFONTA lplf
)
787 FIXME("(%p, %p): stub\n", hIMC
, lplf
);
788 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
792 /***********************************************************************
793 * ImmGetCompositionFontW (IMM32.@)
795 BOOL WINAPI
ImmGetCompositionFontW(HIMC hIMC
, LPLOGFONTW lplf
)
797 FIXME("(%p, %p): stub\n", hIMC
, lplf
);
798 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
802 /***********************************************************************
803 * ImmGetCompositionStringA (IMM32.@)
805 LONG WINAPI
ImmGetCompositionStringA(
806 HIMC hIMC
, DWORD dwIndex
, LPVOID lpBuf
, DWORD dwBufLen
)
810 InputContextData
*data
= (InputContextData
*)hIMC
;
811 LPCOMPOSITIONSTRING compstr
;
814 TRACE("(%p, 0x%x, %p, %d)\n", hIMC
, dwIndex
, lpBuf
, dwBufLen
);
819 if (!data
->IMC
.hCompStr
)
822 compdata
= ImmLockIMCC(data
->IMC
.hCompStr
);
823 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
825 if (dwIndex
== GCS_RESULTSTR
&& compstr
->dwResultStrLen
> 0 &&
826 compstr
->dwResultStrOffset
> 0)
828 LPWSTR ResultStr
= (LPWSTR
)(compdata
+ compstr
->dwResultStrOffset
);
830 TRACE("GSC_RESULTSTR %p %i\n",ResultStr
,
831 compstr
->dwResultStrLen
);
833 buf
= HeapAlloc( GetProcessHeap(), 0, compstr
->dwResultStrLen
* 3 );
834 rc
= WideCharToMultiByte(CP_ACP
, 0, ResultStr
,
835 compstr
->dwResultStrLen
, buf
,
836 compstr
->dwResultStrLen
* 3, NULL
, NULL
);
838 memcpy(lpBuf
,buf
,rc
);
841 HeapFree( GetProcessHeap(), 0, buf
);
843 else if (dwIndex
== GCS_COMPSTR
&& compstr
->dwCompStrLen
> 0 &&
844 compstr
->dwCompStrOffset
> 0)
846 LPWSTR CompString
= (LPWSTR
)(compdata
+ compstr
->dwCompStrOffset
);
848 TRACE("GSC_COMPSTR %p %i\n", CompString
, compstr
->dwCompStrLen
);
850 buf
= HeapAlloc( GetProcessHeap(), 0, compstr
->dwCompStrLen
* 3 );
851 rc
= WideCharToMultiByte(CP_ACP
, 0, CompString
,
852 compstr
->dwCompStrLen
, buf
,
853 compstr
->dwCompStrLen
* 3, NULL
, NULL
);
855 memcpy(lpBuf
,buf
,rc
);
856 HeapFree( GetProcessHeap(), 0, buf
);
858 else if (dwIndex
== GCS_COMPATTR
&& compstr
->dwCompAttrLen
> 0 &&
859 compstr
->dwCompAttrOffset
> 0)
861 LPWSTR Compattr
= (LPWSTR
)(compdata
+ compstr
->dwCompAttrOffset
);
862 TRACE("GSC_COMPATTR %p %i\n", Compattr
, compstr
->dwCompAttrLen
);
864 rc
= compstr
->dwCompAttrLen
;
866 memcpy(lpBuf
,Compattr
,rc
);
868 else if (dwIndex
== GCS_COMPCLAUSE
&& compstr
->dwCompClauseLen
> 0 &&
869 compstr
->dwCompClauseOffset
> 0)
871 LPWSTR Compclause
= (LPWSTR
)(compdata
+ compstr
->dwCompClauseOffset
);
872 TRACE("GSC_COMPCLAUSE %p %i\n", Compclause
, compstr
->dwCompClauseLen
);
874 rc
= compstr
->dwCompClauseLen
;
875 if (dwBufLen
>= compstr
->dwCompClauseLen
)
876 memcpy(lpBuf
,Compclause
,rc
);
878 else if (dwIndex
== GCS_RESULTCLAUSE
&& compstr
->dwResultClauseLen
> 0 &&
879 compstr
->dwResultClauseOffset
> 0)
881 LPWSTR Resultclause
= (LPWSTR
)(compdata
+ compstr
->dwResultClauseOffset
);
882 TRACE("GSC_RESULTCLAUSE %p %i\n", Resultclause
, compstr
->dwResultClauseLen
);
884 rc
= compstr
->dwResultClauseLen
;
885 if (dwBufLen
>= compstr
->dwResultClauseLen
)
886 memcpy(lpBuf
,Resultclause
,rc
);
888 else if (dwIndex
== GCS_CURSORPOS
)
890 TRACE("GSC_CURSORPOS\n");
891 rc
= compstr
->dwCursorPos
;
893 else if (dwIndex
== GCS_DELTASTART
)
895 TRACE("GCS_DELTASTART\n");
896 rc
= compstr
->dwDeltaStart
;
900 FIXME("Unhandled index 0x%x\n",dwIndex
);
903 ImmUnlockIMCC(data
->IMC
.hCompStr
);
908 /***********************************************************************
909 * ImmGetCompositionStringW (IMM32.@)
911 LONG WINAPI
ImmGetCompositionStringW(
912 HIMC hIMC
, DWORD dwIndex
,
913 LPVOID lpBuf
, DWORD dwBufLen
)
916 InputContextData
*data
= (InputContextData
*)hIMC
;
917 LPCOMPOSITIONSTRING compstr
;
920 TRACE("(%p, 0x%x, %p, %d)\n", hIMC
, dwIndex
, lpBuf
, dwBufLen
);
925 if (!data
->IMC
.hCompStr
)
928 compdata
= ImmLockIMCC(data
->IMC
.hCompStr
);
929 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
931 if (dwIndex
== GCS_RESULTSTR
&& compstr
->dwResultStrLen
> 0 &&
932 compstr
->dwResultStrOffset
> 0)
934 LPWSTR ResultStr
= (LPWSTR
)(compdata
+ compstr
->dwResultStrOffset
);
936 rc
= compstr
->dwResultStrLen
* sizeof(WCHAR
);
939 memcpy(lpBuf
,ResultStr
,rc
);
941 else if (dwIndex
== GCS_RESULTREADSTR
&& compstr
->dwResultReadStrLen
> 0 &&
942 compstr
->dwResultReadStrOffset
> 0)
944 LPWSTR ResultReadString
= (LPWSTR
)(compdata
+ compstr
->dwResultReadStrOffset
);
946 rc
= compstr
->dwResultReadStrLen
* sizeof(WCHAR
);
948 memcpy(lpBuf
,ResultReadString
,rc
);
950 else if (dwIndex
== GCS_COMPSTR
&& compstr
->dwCompStrLen
> 0 &&
951 compstr
->dwCompStrOffset
> 0)
953 LPWSTR CompString
= (LPWSTR
)(compdata
+ compstr
->dwCompStrOffset
);
954 rc
= compstr
->dwCompStrLen
* sizeof(WCHAR
);
956 memcpy(lpBuf
,CompString
,rc
);
958 else if (dwIndex
== GCS_COMPATTR
&& compstr
->dwCompAttrLen
> 0 &&
959 compstr
->dwCompAttrOffset
> 0)
962 LPWSTR Compattr
= (LPWSTR
)(compdata
+ compstr
->dwCompAttrOffset
);
964 rc
= compstr
->dwCompAttrLen
;
966 memcpy(lpBuf
,Compattr
,rc
);
968 else if (dwIndex
== GCS_COMPCLAUSE
&& compstr
->dwCompClauseLen
> 0 &&
969 compstr
->dwCompClauseOffset
> 0)
971 LPWSTR Compclause
= (LPWSTR
)(compdata
+ compstr
->dwCompClauseOffset
);
973 rc
= compstr
->dwCompClauseLen
;
974 if (dwBufLen
>= compstr
->dwCompClauseLen
)
975 memcpy(lpBuf
,Compclause
,rc
);
977 else if (dwIndex
== GCS_COMPREADSTR
&& compstr
->dwCompReadStrLen
> 0 &&
978 compstr
->dwCompReadStrOffset
> 0)
980 LPWSTR CompReadString
= (LPWSTR
)(compdata
+ compstr
->dwCompReadStrOffset
);
982 rc
= compstr
->dwCompReadStrLen
* sizeof(WCHAR
);
985 memcpy(lpBuf
,CompReadString
,rc
);
987 else if (dwIndex
== GCS_CURSORPOS
)
989 TRACE("GSC_CURSORPOS\n");
990 rc
= compstr
->dwCursorPos
;
992 else if (dwIndex
== GCS_DELTASTART
)
994 TRACE("GCS_DELTASTART\n");
995 rc
= compstr
->dwDeltaStart
;
999 FIXME("Unhandled index 0x%x\n",dwIndex
);
1002 ImmUnlockIMCC(data
->IMC
.hCompStr
);
1007 /***********************************************************************
1008 * ImmGetCompositionWindow (IMM32.@)
1010 BOOL WINAPI
ImmGetCompositionWindow(HIMC hIMC
, LPCOMPOSITIONFORM lpCompForm
)
1012 InputContextData
*data
= (InputContextData
*)hIMC
;
1014 TRACE("(%p, %p)\n", hIMC
, lpCompForm
);
1019 *lpCompForm
= data
->IMC
.cfCompForm
;
1023 /***********************************************************************
1024 * ImmGetContext (IMM32.@)
1027 HIMC WINAPI
ImmGetContext(HWND hWnd
)
1029 TRACE("%p\n", hWnd
);
1034 root_context
->IMC
.hWnd
= hWnd
;
1035 return (HIMC
)root_context
;
1038 /***********************************************************************
1039 * ImmGetConversionListA (IMM32.@)
1041 DWORD WINAPI
ImmGetConversionListA(
1043 LPCSTR pSrc
, LPCANDIDATELIST lpDst
,
1044 DWORD dwBufLen
, UINT uFlag
)
1046 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1047 hKL
, hIMC
, debugstr_a(pSrc
), lpDst
, dwBufLen
, uFlag
1049 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1053 /***********************************************************************
1054 * ImmGetConversionListW (IMM32.@)
1056 DWORD WINAPI
ImmGetConversionListW(
1058 LPCWSTR pSrc
, LPCANDIDATELIST lpDst
,
1059 DWORD dwBufLen
, UINT uFlag
)
1061 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1062 hKL
, hIMC
, debugstr_w(pSrc
), lpDst
, dwBufLen
, uFlag
1064 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1068 /***********************************************************************
1069 * ImmGetConversionStatus (IMM32.@)
1071 BOOL WINAPI
ImmGetConversionStatus(
1072 HIMC hIMC
, LPDWORD lpfdwConversion
, LPDWORD lpfdwSentence
)
1074 TRACE("(%p, %p, %p): best guess\n", hIMC
, lpfdwConversion
, lpfdwSentence
);
1075 if (lpfdwConversion
)
1076 *lpfdwConversion
= IME_CMODE_NATIVE
;
1078 *lpfdwSentence
= IME_SMODE_NONE
;
1082 /***********************************************************************
1083 * ImmGetDefaultIMEWnd (IMM32.@)
1085 HWND WINAPI
ImmGetDefaultIMEWnd(HWND hWnd
)
1087 static int shown
= 0;
1090 FIXME("(%p - %p %p ): semi-stub\n", hWnd
,hwndDefault
, root_context
);
1094 if (hwndDefault
== NULL
)
1096 static const WCHAR the_name
[] = {'I','M','E','\0'};
1099 hwndDefault
= CreateWindowExW( WS_EX_TOOLWINDOW
, WC_IMECLASSNAME
,
1100 the_name
, WS_POPUP
, 0, 0, 1, 1, 0, 0,
1103 TRACE("Default created (%p)\n",hwndDefault
);
1109 /***********************************************************************
1110 * ImmGetDescriptionA (IMM32.@)
1112 UINT WINAPI
ImmGetDescriptionA(
1113 HKL hKL
, LPSTR lpszDescription
, UINT uBufLen
)
1118 TRACE("%p %p %d\n", hKL
, lpszDescription
, uBufLen
);
1120 /* find out how many characters in the unicode buffer */
1121 len
= ImmGetDescriptionW( hKL
, NULL
, 0 );
1123 /* allocate a buffer of that size */
1124 buf
= HeapAlloc( GetProcessHeap(), 0, (len
+ 1) * sizeof (WCHAR
) );
1128 /* fetch the unicode buffer */
1129 len
= ImmGetDescriptionW( hKL
, buf
, len
+ 1 );
1131 /* convert it back to ASCII */
1132 len
= WideCharToMultiByte( CP_ACP
, 0, buf
, len
+ 1,
1133 lpszDescription
, uBufLen
, NULL
, NULL
);
1135 HeapFree( GetProcessHeap(), 0, buf
);
1140 /***********************************************************************
1141 * ImmGetDescriptionW (IMM32.@)
1143 UINT WINAPI
ImmGetDescriptionW(HKL hKL
, LPWSTR lpszDescription
, UINT uBufLen
)
1145 static const WCHAR name
[] = { 'W','i','n','e',' ','X','I','M',0 };
1147 FIXME("(%p, %p, %d): semi stub\n", hKL
, lpszDescription
, uBufLen
);
1149 if (!uBufLen
) return lstrlenW( name
);
1150 lstrcpynW( lpszDescription
, name
, uBufLen
);
1151 return lstrlenW( lpszDescription
);
1154 /***********************************************************************
1155 * ImmGetGuideLineA (IMM32.@)
1157 DWORD WINAPI
ImmGetGuideLineA(
1158 HIMC hIMC
, DWORD dwIndex
, LPSTR lpBuf
, DWORD dwBufLen
)
1160 FIXME("(%p, %d, %s, %d): stub\n",
1161 hIMC
, dwIndex
, debugstr_a(lpBuf
), dwBufLen
1163 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1167 /***********************************************************************
1168 * ImmGetGuideLineW (IMM32.@)
1170 DWORD WINAPI
ImmGetGuideLineW(HIMC hIMC
, DWORD dwIndex
, LPWSTR lpBuf
, DWORD dwBufLen
)
1172 FIXME("(%p, %d, %s, %d): stub\n",
1173 hIMC
, dwIndex
, debugstr_w(lpBuf
), dwBufLen
1175 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1179 /***********************************************************************
1180 * ImmGetIMEFileNameA (IMM32.@)
1182 UINT WINAPI
ImmGetIMEFileNameA( HKL hKL
, LPSTR lpszFileName
, UINT uBufLen
)
1185 UINT wBufLen
= uBufLen
;
1188 if (uBufLen
&& lpszFileName
)
1189 bufW
= HeapAlloc(GetProcessHeap(),0,uBufLen
* sizeof(WCHAR
));
1190 else /* We need this to get the number of byte required */
1192 bufW
= HeapAlloc(GetProcessHeap(),0,MAX_PATH
* sizeof(WCHAR
));
1196 rc
= ImmGetIMEFileNameW(hKL
,bufW
,wBufLen
);
1200 if (uBufLen
&& lpszFileName
)
1201 rc
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, lpszFileName
,
1202 uBufLen
, NULL
, NULL
);
1203 else /* get the length */
1204 rc
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
,
1208 HeapFree(GetProcessHeap(),0,bufW
);
1212 /***********************************************************************
1213 * ImmGetIMEFileNameW (IMM32.@)
1215 UINT WINAPI
ImmGetIMEFileNameW(HKL hKL
, LPWSTR lpszFileName
, UINT uBufLen
)
1217 static const WCHAR szImeFileW
[] = {'I','m','e',' ','F','i','l','e',0};
1218 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};
1223 WCHAR regKey
[sizeof(fmt
)/sizeof(WCHAR
)+8];
1225 wsprintfW( regKey
, fmt
, (unsigned)hKL
);
1226 rc
= RegOpenKeyW( HKEY_LOCAL_MACHINE
, regKey
, &hkey
);
1227 if (rc
!= ERROR_SUCCESS
)
1234 rc
= RegGetValueW(hkey
, NULL
, szImeFileW
, RRF_RT_REG_SZ
, NULL
, NULL
, &length
);
1236 if (rc
!= ERROR_SUCCESS
)
1242 if (length
> uBufLen
* sizeof(WCHAR
) || !lpszFileName
)
1247 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1251 return length
/ sizeof(WCHAR
);
1254 RegGetValueW(hkey
, NULL
, szImeFileW
, RRF_RT_REG_SZ
, NULL
, lpszFileName
, &length
);
1258 return length
/ sizeof(WCHAR
);
1261 /***********************************************************************
1262 * ImmGetOpenStatus (IMM32.@)
1264 BOOL WINAPI
ImmGetOpenStatus(HIMC hIMC
)
1266 InputContextData
*data
= (InputContextData
*)hIMC
;
1270 FIXME("(%p): semi-stub\n", hIMC
);
1272 return data
->IMC
.fOpen
;
1275 /***********************************************************************
1276 * ImmGetProperty (IMM32.@)
1278 DWORD WINAPI
ImmGetProperty(HKL hKL
, DWORD fdwIndex
)
1281 TRACE("(%p, %d)\n", hKL
, fdwIndex
);
1286 TRACE("(%s)\n", "IGP_PROPERTY");
1287 rc
= IME_PROP_UNICODE
| IME_PROP_AT_CARET
;
1289 case IGP_CONVERSION
:
1290 FIXME("(%s)\n", "IGP_CONVERSION");
1291 rc
= IME_CMODE_NATIVE
;
1294 FIXME("%s)\n", "IGP_SENTENCE");
1295 rc
= IME_SMODE_AUTOMATIC
;
1297 case IGP_SETCOMPSTR
:
1298 TRACE("(%s)\n", "IGP_SETCOMPSTR");
1302 TRACE("(%s)\n", "IGP_SELECT");
1303 rc
= SELECT_CAP_CONVERSION
| SELECT_CAP_SENTENCE
;
1305 case IGP_GETIMEVERSION
:
1306 TRACE("(%s)\n", "IGP_GETIMEVERSION");
1310 TRACE("(%s)\n", "IGP_UI");
1319 /***********************************************************************
1320 * ImmGetRegisterWordStyleA (IMM32.@)
1322 UINT WINAPI
ImmGetRegisterWordStyleA(
1323 HKL hKL
, UINT nItem
, LPSTYLEBUFA lpStyleBuf
)
1325 FIXME("(%p, %d, %p): stub\n", hKL
, nItem
, lpStyleBuf
);
1326 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1330 /***********************************************************************
1331 * ImmGetRegisterWordStyleW (IMM32.@)
1333 UINT WINAPI
ImmGetRegisterWordStyleW(
1334 HKL hKL
, UINT nItem
, LPSTYLEBUFW lpStyleBuf
)
1336 FIXME("(%p, %d, %p): stub\n", hKL
, nItem
, lpStyleBuf
);
1337 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1341 /***********************************************************************
1342 * ImmGetStatusWindowPos (IMM32.@)
1344 BOOL WINAPI
ImmGetStatusWindowPos(HIMC hIMC
, LPPOINT lpptPos
)
1346 FIXME("(%p, %p): stub\n", hIMC
, lpptPos
);
1347 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1351 /***********************************************************************
1352 * ImmGetVirtualKey (IMM32.@)
1354 UINT WINAPI
ImmGetVirtualKey(HWND hWnd
)
1356 OSVERSIONINFOA version
;
1357 FIXME("(%p): stub\n", hWnd
);
1358 GetVersionExA( &version
);
1359 switch(version
.dwPlatformId
)
1361 case VER_PLATFORM_WIN32_WINDOWS
:
1362 return VK_PROCESSKEY
;
1363 case VER_PLATFORM_WIN32_NT
:
1366 FIXME("%d not supported\n",version
.dwPlatformId
);
1367 return VK_PROCESSKEY
;
1371 /***********************************************************************
1372 * ImmInstallIMEA (IMM32.@)
1374 HKL WINAPI
ImmInstallIMEA(
1375 LPCSTR lpszIMEFileName
, LPCSTR lpszLayoutText
)
1377 FIXME("(%s, %s): stub\n",
1378 debugstr_a(lpszIMEFileName
), debugstr_a(lpszLayoutText
)
1380 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1384 /***********************************************************************
1385 * ImmInstallIMEW (IMM32.@)
1387 HKL WINAPI
ImmInstallIMEW(
1388 LPCWSTR lpszIMEFileName
, LPCWSTR lpszLayoutText
)
1390 FIXME("(%s, %s): stub\n",
1391 debugstr_w(lpszIMEFileName
), debugstr_w(lpszLayoutText
)
1393 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1397 /***********************************************************************
1398 * ImmIsIME (IMM32.@)
1400 BOOL WINAPI
ImmIsIME(HKL hKL
)
1402 TRACE("(%p): semi-stub\n", hKL
);
1404 * FIXME: Dead key locales will return TRUE here when they should not
1405 * There is probably a more proper way to check this.
1407 return (root_context
!= NULL
);
1410 /***********************************************************************
1411 * ImmIsUIMessageA (IMM32.@)
1413 BOOL WINAPI
ImmIsUIMessageA(
1414 HWND hWndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1418 TRACE("(%p, %x, %ld, %ld)\n", hWndIME
, msg
, wParam
, lParam
);
1419 if ((msg
>= WM_IME_STARTCOMPOSITION
&& msg
<= WM_IME_KEYLAST
) ||
1420 (msg
>= WM_IME_SETCONTEXT
&& msg
<= WM_IME_KEYUP
) ||
1421 (msg
== WM_MSIME_SERVICE
) ||
1422 (msg
== WM_MSIME_RECONVERTOPTIONS
) ||
1423 (msg
== WM_MSIME_MOUSE
) ||
1424 (msg
== WM_MSIME_RECONVERTREQUEST
) ||
1425 (msg
== WM_MSIME_RECONVERT
) ||
1426 (msg
== WM_MSIME_QUERYPOSITION
) ||
1427 (msg
== WM_MSIME_DOCUMENTFEED
))
1431 ImmGetDefaultIMEWnd(NULL
);
1433 if (hWndIME
== NULL
)
1434 PostMessageA(hwndDefault
, msg
, wParam
, lParam
);
1441 /***********************************************************************
1442 * ImmIsUIMessageW (IMM32.@)
1444 BOOL WINAPI
ImmIsUIMessageW(
1445 HWND hWndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1448 TRACE("(%p, %d, %ld, %ld): stub\n", hWndIME
, msg
, wParam
, lParam
);
1449 if ((msg
>= WM_IME_STARTCOMPOSITION
&& msg
<= WM_IME_KEYLAST
) ||
1450 (msg
>= WM_IME_SETCONTEXT
&& msg
<= WM_IME_KEYUP
) ||
1451 (msg
== WM_MSIME_SERVICE
) ||
1452 (msg
== WM_MSIME_RECONVERTOPTIONS
) ||
1453 (msg
== WM_MSIME_MOUSE
) ||
1454 (msg
== WM_MSIME_RECONVERTREQUEST
) ||
1455 (msg
== WM_MSIME_RECONVERT
) ||
1456 (msg
== WM_MSIME_QUERYPOSITION
) ||
1457 (msg
== WM_MSIME_DOCUMENTFEED
))
1462 /***********************************************************************
1463 * ImmNotifyIME (IMM32.@)
1465 BOOL WINAPI
ImmNotifyIME(
1466 HIMC hIMC
, DWORD dwAction
, DWORD dwIndex
, DWORD dwValue
)
1470 TRACE("(%p, %d, %d, %d)\n",
1471 hIMC
, dwAction
, dwIndex
, dwValue
);
1478 case NI_CHANGECANDIDATELIST
:
1479 FIXME("%s\n","NI_CHANGECANDIDATELIST");
1481 case NI_CLOSECANDIDATE
:
1482 FIXME("%s\n","NI_CLOSECANDIDATE");
1484 case NI_COMPOSITIONSTR
:
1488 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
1491 LPCOMPOSITIONSTRING lpCompStr
;
1493 if (pX11DRV_ForceXIMReset
)
1494 pX11DRV_ForceXIMReset(root_context
->IMC
.hWnd
);
1496 lpCompStr
= ImmLockIMCC(root_context
->IMC
.hCompStr
);
1497 send
= (lpCompStr
->dwCompStrLen
!= 0);
1498 ImmUnlockIMCC(root_context
->IMC
.hCompStr
);
1500 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1501 root_context
->IMC
.hCompStr
= ImmCreateBlankCompStr();
1504 ImmInternalPostIMEMessage(WM_IME_COMPOSITION
, 0,
1510 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE");
1511 if (hIMC
!= (HIMC
)FROM_IME
&& pX11DRV_ForceXIMReset
)
1512 pX11DRV_ForceXIMReset(root_context
->IMC
.hWnd
);
1517 LPCOMPOSITIONSTRING cs
= NULL
;
1518 LPBYTE cdata
= NULL
;
1520 /* clear existing result */
1521 newCompStr
= updateResultStr(root_context
->IMC
.hCompStr
, NULL
, 0);
1522 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1523 root_context
->IMC
.hCompStr
= newCompStr
;
1525 if (root_context
->IMC
.hCompStr
)
1527 cdata
= ImmLockIMCC(root_context
->IMC
.hCompStr
);
1528 cs
= (LPCOMPOSITIONSTRING
)cdata
;
1529 cplen
= cs
->dwCompStrLen
;
1530 cpstr
= (LPWSTR
)&(cdata
[cs
->dwCompStrOffset
]);
1531 ImmUnlockIMCC(root_context
->IMC
.hCompStr
);
1535 WCHAR param
= cpstr
[0];
1536 newCompStr
= updateResultStr(root_context
->IMC
.hCompStr
, cpstr
, cplen
);
1537 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1538 root_context
->IMC
.hCompStr
= newCompStr
;
1539 newCompStr
= updateCompStr(root_context
->IMC
.hCompStr
, NULL
, 0);
1540 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1541 root_context
->IMC
.hCompStr
= newCompStr
;
1543 root_context
->bRead
= FALSE
;
1545 ImmInternalPostIMEMessage(WM_IME_COMPOSITION
, 0,
1548 ImmInternalPostIMEMessage(WM_IME_COMPOSITION
,
1550 GCS_RESULTSTR
|GCS_RESULTCLAUSE
);
1553 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION
, 0, 0);
1554 root_context
->bInComposition
= FALSE
;
1558 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_CONVERT");
1561 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_REVERT");
1564 ERR("%s - %s (%i)\n","NI_COMPOSITIONSTR","UNKNOWN",dwIndex
);
1568 case NI_IMEMENUSELECTED
:
1569 FIXME("%s\n", "NI_IMEMENUSELECTED");
1571 case NI_OPENCANDIDATE
:
1572 FIXME("%s\n", "NI_OPENCANDIDATE");
1574 case NI_SELECTCANDIDATESTR
:
1575 FIXME("%s\n", "NI_SELECTCANDIDATESTR");
1577 case NI_SETCANDIDATE_PAGESIZE
:
1578 FIXME("%s\n", "NI_SETCANDIDATE_PAGESIZE");
1580 case NI_SETCANDIDATE_PAGESTART
:
1581 FIXME("%s\n", "NI_SETCANDIDATE_PAGESTART");
1590 /***********************************************************************
1591 * ImmRegisterWordA (IMM32.@)
1593 BOOL WINAPI
ImmRegisterWordA(
1594 HKL hKL
, LPCSTR lpszReading
, DWORD dwStyle
, LPCSTR lpszRegister
)
1596 FIXME("(%p, %s, %d, %s): stub\n",
1597 hKL
, debugstr_a(lpszReading
), dwStyle
, debugstr_a(lpszRegister
)
1599 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1603 /***********************************************************************
1604 * ImmRegisterWordW (IMM32.@)
1606 BOOL WINAPI
ImmRegisterWordW(
1607 HKL hKL
, LPCWSTR lpszReading
, DWORD dwStyle
, LPCWSTR lpszRegister
)
1609 FIXME("(%p, %s, %d, %s): stub\n",
1610 hKL
, debugstr_w(lpszReading
), dwStyle
, debugstr_w(lpszRegister
)
1612 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1616 /***********************************************************************
1617 * ImmReleaseContext (IMM32.@)
1619 BOOL WINAPI
ImmReleaseContext(HWND hWnd
, HIMC hIMC
)
1621 static int shown
= 0;
1624 FIXME("(%p, %p): stub\n", hWnd
, hIMC
);
1630 /***********************************************************************
1631 * ImmSetCandidateWindow (IMM32.@)
1633 BOOL WINAPI
ImmSetCandidateWindow(
1634 HIMC hIMC
, LPCANDIDATEFORM lpCandidate
)
1636 FIXME("(%p, %p): stub\n", hIMC
, lpCandidate
);
1637 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1641 /***********************************************************************
1642 * ImmSetCompositionFontA (IMM32.@)
1644 BOOL WINAPI
ImmSetCompositionFontA(HIMC hIMC
, LPLOGFONTA lplf
)
1646 InputContextData
*data
= (InputContextData
*)hIMC
;
1647 TRACE("(%p, %p)\n", hIMC
, lplf
);
1652 memcpy(&data
->IMC
.lfFont
.W
,lplf
,sizeof(LOGFONTA
));
1653 MultiByteToWideChar(CP_ACP
, 0, lplf
->lfFaceName
, -1, data
->IMC
.lfFont
.W
.lfFaceName
,
1656 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT
, 0);
1660 DeleteObject(data
->textfont
);
1661 data
->textfont
= NULL
;
1664 data
->textfont
= CreateFontIndirectW(&data
->IMC
.lfFont
.W
);
1668 /***********************************************************************
1669 * ImmSetCompositionFontW (IMM32.@)
1671 BOOL WINAPI
ImmSetCompositionFontW(HIMC hIMC
, LPLOGFONTW lplf
)
1673 InputContextData
*data
= (InputContextData
*)hIMC
;
1674 TRACE("(%p, %p)\n", hIMC
, lplf
);
1679 data
->IMC
.lfFont
.W
= *lplf
;
1680 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT
, 0);
1684 DeleteObject(data
->textfont
);
1685 data
->textfont
= NULL
;
1687 data
->textfont
= CreateFontIndirectW(&data
->IMC
.lfFont
.W
);
1691 /***********************************************************************
1692 * ImmSetCompositionStringA (IMM32.@)
1694 BOOL WINAPI
ImmSetCompositionStringA(
1695 HIMC hIMC
, DWORD dwIndex
,
1696 LPCVOID lpComp
, DWORD dwCompLen
,
1697 LPCVOID lpRead
, DWORD dwReadLen
)
1701 WCHAR
*CompBuffer
= NULL
;
1702 WCHAR
*ReadBuffer
= NULL
;
1705 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1706 hIMC
, dwIndex
, lpComp
, dwCompLen
, lpRead
, dwReadLen
);
1708 comp_len
= MultiByteToWideChar(CP_ACP
, 0, lpComp
, dwCompLen
, NULL
, 0);
1711 CompBuffer
= HeapAlloc(GetProcessHeap(),0,comp_len
* sizeof(WCHAR
));
1712 MultiByteToWideChar(CP_ACP
, 0, lpComp
, dwCompLen
, CompBuffer
, comp_len
);
1715 read_len
= MultiByteToWideChar(CP_ACP
, 0, lpRead
, dwReadLen
, NULL
, 0);
1718 ReadBuffer
= HeapAlloc(GetProcessHeap(),0,read_len
* sizeof(WCHAR
));
1719 MultiByteToWideChar(CP_ACP
, 0, lpRead
, dwReadLen
, ReadBuffer
, read_len
);
1722 rc
= ImmSetCompositionStringW(hIMC
, dwIndex
, CompBuffer
, comp_len
,
1723 ReadBuffer
, read_len
);
1725 HeapFree(GetProcessHeap(), 0, CompBuffer
);
1726 HeapFree(GetProcessHeap(), 0, ReadBuffer
);
1731 /***********************************************************************
1732 * ImmSetCompositionStringW (IMM32.@)
1734 BOOL WINAPI
ImmSetCompositionStringW(
1735 HIMC hIMC
, DWORD dwIndex
,
1736 LPCVOID lpComp
, DWORD dwCompLen
,
1737 LPCVOID lpRead
, DWORD dwReadLen
)
1742 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1743 hIMC
, dwIndex
, lpComp
, dwCompLen
, lpRead
, dwReadLen
);
1746 if (hIMC
!= (HIMC
)FROM_IME
)
1747 FIXME("PROBLEM: This only sets the wine level string\n");
1751 * this sets the composition string in the imm32.dll level
1752 * of the composition buffer. we cannot manipulate the xim level
1753 * buffer, which means that once the xim level buffer changes again
1754 * any call to this function from the application will be lost
1757 if (lpRead
&& dwReadLen
)
1758 FIXME("Reading string unimplemented\n");
1761 * app operating this api to also receive the message from xim
1764 if (dwIndex
== SCS_SETSTR
)
1767 if (!root_context
->bInComposition
)
1769 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION
, 0, 0);
1770 root_context
->bInComposition
= TRUE
;
1773 flags
= GCS_COMPSTR
;
1775 if (dwCompLen
&& lpComp
)
1777 newCompStr
= updateCompStr(root_context
->IMC
.hCompStr
, (LPWSTR
)lpComp
, dwCompLen
/ sizeof(WCHAR
));
1778 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1779 root_context
->IMC
.hCompStr
= newCompStr
;
1781 wParam
= ((const WCHAR
*)lpComp
)[0];
1782 flags
|= GCS_COMPCLAUSE
| GCS_COMPATTR
| GCS_DELTASTART
;
1786 newCompStr
= updateCompStr(root_context
->IMC
.hCompStr
, NULL
, 0);
1787 ImmDestroyIMCC(root_context
->IMC
.hCompStr
);
1788 root_context
->IMC
.hCompStr
= newCompStr
;
1792 UpdateDataInDefaultIMEWindow(hwndDefault
,FALSE
);
1794 ImmInternalPostIMEMessage(WM_IME_COMPOSITION
, wParam
, flags
);
1799 /***********************************************************************
1800 * ImmSetCompositionWindow (IMM32.@)
1802 BOOL WINAPI
ImmSetCompositionWindow(
1803 HIMC hIMC
, LPCOMPOSITIONFORM lpCompForm
)
1805 BOOL reshow
= FALSE
;
1806 InputContextData
*data
= (InputContextData
*)hIMC
;
1808 TRACE("(%p, %p)\n", hIMC
, lpCompForm
);
1809 TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm
->dwStyle
,
1810 lpCompForm
->ptCurrentPos
.x
, lpCompForm
->ptCurrentPos
.y
, lpCompForm
->rcArea
.top
,
1811 lpCompForm
->rcArea
.left
, lpCompForm
->rcArea
.bottom
, lpCompForm
->rcArea
.right
);
1816 data
->IMC
.cfCompForm
= *lpCompForm
;
1818 if (IsWindowVisible(hwndDefault
))
1821 ShowWindow(hwndDefault
,SW_HIDE
);
1824 /* FIXME: this is a partial stub */
1827 ShowWindow(hwndDefault
,SW_SHOWNOACTIVATE
);
1829 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONWINDOW
, 0);
1833 /***********************************************************************
1834 * ImmSetConversionStatus (IMM32.@)
1836 BOOL WINAPI
ImmSetConversionStatus(
1837 HIMC hIMC
, DWORD fdwConversion
, DWORD fdwSentence
)
1839 static int shown
= 0;
1842 FIXME("(%p, %d, %d): stub\n",
1843 hIMC
, fdwConversion
, fdwSentence
1847 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1851 /***********************************************************************
1852 * ImmSetOpenStatus (IMM32.@)
1854 BOOL WINAPI
ImmSetOpenStatus(HIMC hIMC
, BOOL fOpen
)
1856 InputContextData
*data
= (InputContextData
*)hIMC
;
1858 TRACE("%p %d\n", hIMC
, fOpen
);
1860 if (hIMC
== (HIMC
)FROM_IME
)
1862 ImmInternalSetOpenStatus(fOpen
);
1863 ImmInternalSendIMENotify(IMN_SETOPENSTATUS
, 0);
1870 if (fOpen
!= data
->bInternalState
)
1872 if (fOpen
== FALSE
&& pX11DRV_ForceXIMReset
)
1873 pX11DRV_ForceXIMReset(data
->IMC
.hWnd
);
1876 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION
,0,0);
1878 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION
,0,0);
1880 ImmInternalSetOpenStatus(fOpen
);
1881 ImmInternalSetOpenStatus(!fOpen
);
1883 if (data
->IMC
.fOpen
== FALSE
)
1884 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION
,0,0);
1886 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION
,0,0);
1893 /***********************************************************************
1894 * ImmSetStatusWindowPos (IMM32.@)
1896 BOOL WINAPI
ImmSetStatusWindowPos(HIMC hIMC
, LPPOINT lpptPos
)
1898 FIXME("(%p, %p): stub\n", hIMC
, lpptPos
);
1899 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1903 /***********************************************************************
1904 * ImmSimulateHotKey (IMM32.@)
1906 BOOL WINAPI
ImmSimulateHotKey(HWND hWnd
, DWORD dwHotKeyID
)
1908 FIXME("(%p, %d): stub\n", hWnd
, dwHotKeyID
);
1909 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1913 /***********************************************************************
1914 * ImmUnregisterWordA (IMM32.@)
1916 BOOL WINAPI
ImmUnregisterWordA(
1917 HKL hKL
, LPCSTR lpszReading
, DWORD dwStyle
, LPCSTR lpszUnregister
)
1919 FIXME("(%p, %s, %d, %s): stub\n",
1920 hKL
, debugstr_a(lpszReading
), dwStyle
, debugstr_a(lpszUnregister
)
1922 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1926 /***********************************************************************
1927 * ImmUnregisterWordW (IMM32.@)
1929 BOOL WINAPI
ImmUnregisterWordW(
1930 HKL hKL
, LPCWSTR lpszReading
, DWORD dwStyle
, LPCWSTR lpszUnregister
)
1932 FIXME("(%p, %s, %d, %s): stub\n",
1933 hKL
, debugstr_w(lpszReading
), dwStyle
, debugstr_w(lpszUnregister
)
1935 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1939 /***********************************************************************
1940 * ImmGetImeMenuItemsA (IMM32.@)
1942 DWORD WINAPI
ImmGetImeMenuItemsA( HIMC hIMC
, DWORD dwFlags
, DWORD dwType
,
1943 LPIMEMENUITEMINFOA lpImeParentMenu
, LPIMEMENUITEMINFOA lpImeMenu
,
1946 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC
, dwFlags
, dwType
,
1947 lpImeParentMenu
, lpImeMenu
, dwSize
);
1951 /***********************************************************************
1952 * ImmGetImeMenuItemsW (IMM32.@)
1954 DWORD WINAPI
ImmGetImeMenuItemsW( HIMC hIMC
, DWORD dwFlags
, DWORD dwType
,
1955 LPIMEMENUITEMINFOW lpImeParentMenu
, LPIMEMENUITEMINFOW lpImeMenu
,
1958 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC
, dwFlags
, dwType
,
1959 lpImeParentMenu
, lpImeMenu
, dwSize
);
1963 /***********************************************************************
1964 * ImmLockIMC(IMM32.@)
1966 LPINPUTCONTEXT WINAPI
ImmLockIMC(HIMC hIMC
)
1968 InputContextData
*data
= (InputContextData
*)hIMC
;
1976 /***********************************************************************
1977 * ImmUnlockIMC(IMM32.@)
1979 BOOL WINAPI
ImmUnlockIMC(HIMC hIMC
)
1981 InputContextData
*data
= (InputContextData
*)hIMC
;
1983 return (data
->dwLock
!=0);
1986 /***********************************************************************
1987 * ImmGetIMCLockCount(IMM32.@)
1989 DWORD WINAPI
ImmGetIMCLockCount(HIMC hIMC
)
1991 InputContextData
*data
= (InputContextData
*)hIMC
;
1992 return data
->dwLock
;
1995 /***********************************************************************
1996 * ImmCreateIMCC(IMM32.@)
1998 HIMCC WINAPI
ImmCreateIMCC(DWORD size
)
2000 IMCCInternal
*internal
;
2001 int real_size
= size
+ sizeof(IMCCInternal
);
2003 internal
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, real_size
);
2004 if (internal
== NULL
)
2007 internal
->dwSize
= size
;
2008 return (HIMCC
)internal
;
2011 /***********************************************************************
2012 * ImmDestroyIMCC(IMM32.@)
2014 HIMCC WINAPI
ImmDestroyIMCC(HIMCC block
)
2016 HeapFree(GetProcessHeap(),0,block
);
2020 /***********************************************************************
2021 * ImmLockIMCC(IMM32.@)
2023 LPVOID WINAPI
ImmLockIMCC(HIMCC imcc
)
2025 IMCCInternal
*internal
;
2026 internal
= (IMCCInternal
*) imcc
;
2028 internal
->dwLock
++;
2029 return internal
+ 1;
2032 /***********************************************************************
2033 * ImmUnlockIMCC(IMM32.@)
2035 BOOL WINAPI
ImmUnlockIMCC(HIMCC imcc
)
2037 IMCCInternal
*internal
;
2038 internal
= (IMCCInternal
*) imcc
;
2040 internal
->dwLock
--;
2041 return (internal
->dwLock
!=0);
2044 /***********************************************************************
2045 * ImmGetIMCCLockCount(IMM32.@)
2047 DWORD WINAPI
ImmGetIMCCLockCount(HIMCC imcc
)
2049 IMCCInternal
*internal
;
2050 internal
= (IMCCInternal
*) imcc
;
2052 return internal
->dwLock
;
2055 /***********************************************************************
2056 * ImmReSizeIMCC(IMM32.@)
2058 HIMCC WINAPI
ImmReSizeIMCC(HIMCC imcc
, DWORD size
)
2060 IMCCInternal
*internal
,*newone
;
2061 int real_size
= size
+ sizeof(IMCCInternal
);
2063 internal
= (IMCCInternal
*) imcc
;
2065 newone
= HeapReAlloc(GetProcessHeap(), 0, internal
, real_size
);
2066 newone
->dwSize
= size
;
2071 /***********************************************************************
2072 * ImmGetIMCCSize(IMM32.@)
2074 DWORD WINAPI
ImmGetIMCCSize(HIMCC imcc
)
2076 IMCCInternal
*internal
;
2077 internal
= (IMCCInternal
*) imcc
;
2079 return internal
->dwSize
;
2082 /***********************************************************************
2083 * ImmGenerateMessage(IMM32.@)
2085 BOOL WINAPI
ImmGenerateMessage(HIMC hIMC
)
2087 InputContextData
*data
= (InputContextData
*)hIMC
;
2089 TRACE("%i messages queued\n",data
->IMC
.dwNumMsgBuf
);
2090 if (data
->IMC
.dwNumMsgBuf
> 0)
2092 LPTRANSMSG lpTransMsg
;
2095 lpTransMsg
= (LPTRANSMSG
)ImmLockIMCC(data
->IMC
.hMsgBuf
);
2096 for (i
= 0; i
< data
->IMC
.dwNumMsgBuf
; i
++)
2097 ImmInternalPostIMEMessage(lpTransMsg
[i
].message
, lpTransMsg
[i
].wParam
, lpTransMsg
[i
].lParam
);
2099 ImmUnlockIMCC(data
->IMC
.hMsgBuf
);
2101 data
->IMC
.dwNumMsgBuf
= 0;
2108 * Internal functions to help with IME window management
2110 static void PaintDefaultIMEWnd(HWND hwnd
)
2114 HDC hdc
= BeginPaint(hwnd
,&ps
);
2115 LPCOMPOSITIONSTRING compstr
;
2116 LPBYTE compdata
= NULL
;
2118 MONITORINFO mon_info
;
2121 GetClientRect(hwnd
,&rect
);
2122 FillRect(hdc
, &rect
, (HBRUSH
)(COLOR_WINDOW
+ 1));
2124 compdata
= ImmLockIMCC(root_context
->IMC
.hCompStr
);
2125 compstr
= (LPCOMPOSITIONSTRING
)compdata
;
2127 if (compstr
->dwCompStrLen
&& compstr
->dwCompStrOffset
)
2131 HFONT oldfont
= NULL
;
2134 CompString
= (LPWSTR
)(compdata
+ compstr
->dwCompStrOffset
);
2135 if (root_context
->textfont
)
2136 oldfont
= SelectObject(hdc
,root_context
->textfont
);
2139 GetTextExtentPoint32W(hdc
, CompString
, compstr
->dwCompStrLen
, &size
);
2145 * How this works based on tests on windows:
2146 * CFS_POINT: then we start our window at the point and grow it as large
2147 * as it needs to be for the string.
2148 * CFS_RECT: we still use the ptCurrentPos as a starting point and our
2149 * window is only as large as we need for the string, but we do not
2150 * grow such that our window exceeds the given rect. Wrapping if
2151 * needed and possible. If our ptCurrentPos is outside of our rect
2152 * then no window is displayed.
2153 * CFS_FORCE_POSITION: appears to behave just like CFS_POINT
2154 * maybe becase the default MSIME does not do any IME adjusting.
2156 if (root_context
->IMC
.cfCompForm
.dwStyle
!= CFS_DEFAULT
)
2158 POINT cpt
= root_context
->IMC
.cfCompForm
.ptCurrentPos
;
2159 ClientToScreen(root_context
->IMC
.hWnd
,&cpt
);
2162 rect
.right
= rect
.left
+ pt
.x
;
2163 rect
.bottom
= rect
.top
+ pt
.y
;
2164 monitor
= MonitorFromPoint(cpt
, MONITOR_DEFAULTTOPRIMARY
);
2166 else /* CFS_DEFAULT */
2168 /* Windows places the default IME window in the bottom left */
2169 HWND target
= root_context
->IMC
.hWnd
;
2170 if (!target
) target
= GetFocus();
2172 GetWindowRect(target
,&rect
);
2173 rect
.top
= rect
.bottom
;
2174 rect
.right
= rect
.left
+ pt
.x
+ 20;
2175 rect
.bottom
= rect
.top
+ pt
.y
+ 20;
2177 monitor
= MonitorFromWindow(target
, MONITOR_DEFAULTTOPRIMARY
);
2180 if (root_context
->IMC
.cfCompForm
.dwStyle
== CFS_RECT
)
2183 client
=root_context
->IMC
.cfCompForm
.rcArea
;
2184 MapWindowPoints( root_context
->IMC
.hWnd
, 0, (POINT
*)&client
, 2 );
2185 IntersectRect(&rect
,&rect
,&client
);
2186 /* TODO: Wrap the input if needed */
2189 if (root_context
->IMC
.cfCompForm
.dwStyle
== CFS_DEFAULT
)
2191 /* make sure we are on the desktop */
2192 mon_info
.cbSize
= sizeof(mon_info
);
2193 GetMonitorInfoW(monitor
, &mon_info
);
2195 if (rect
.bottom
> mon_info
.rcWork
.bottom
)
2197 int shift
= rect
.bottom
- mon_info
.rcWork
.bottom
;
2199 rect
.bottom
-= shift
;
2203 rect
.right
-= rect
.left
;
2206 if (rect
.right
> mon_info
.rcWork
.right
)
2208 int shift
= rect
.right
- mon_info
.rcWork
.right
;
2210 rect
.right
-= shift
;
2214 SetWindowPos(hwnd
, HWND_TOPMOST
, rect
.left
, rect
.top
, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
, SWP_NOACTIVATE
);
2216 TextOutW(hdc
, offX
,offY
, CompString
, compstr
->dwCompStrLen
);
2219 SelectObject(hdc
,oldfont
);
2222 ImmUnlockIMCC(root_context
->IMC
.hCompStr
);
2227 static void UpdateDataInDefaultIMEWindow(HWND hwnd
, BOOL showable
)
2229 LPCOMPOSITIONSTRING compstr
;
2231 if (root_context
->IMC
.hCompStr
)
2232 compstr
= ImmLockIMCC(root_context
->IMC
.hCompStr
);
2236 if (compstr
== NULL
|| compstr
->dwCompStrLen
== 0)
2237 ShowWindow(hwndDefault
,SW_HIDE
);
2239 ShowWindow(hwndDefault
,SW_SHOWNOACTIVATE
);
2241 RedrawWindow(hwnd
,NULL
,NULL
,RDW_ERASENOW
|RDW_INVALIDATE
);
2243 if (compstr
!= NULL
)
2244 ImmUnlockIMCC(root_context
->IMC
.hCompStr
);
2248 * The window proc for the default IME window
2250 static LRESULT WINAPI
IME_WindowProc(HWND hwnd
, UINT msg
, WPARAM wParam
,
2255 TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", msg
, (UINT
)wParam
,
2261 PaintDefaultIMEWnd(hwnd
);
2268 SetWindowTextA(hwnd
,"Wine Ime Active");
2273 SetFocus((HWND
)wParam
);
2275 FIXME("Received focus, should never have focus\n");
2277 case WM_IME_COMPOSITION
:
2278 TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
2279 "WM_IME_COMPOSITION", (UINT
)wParam
, (UINT
)lParam
,
2280 root_context
->bRead
);
2281 if (lParam
& GCS_RESULTSTR
)
2282 IMM_PostResult(root_context
);
2284 UpdateDataInDefaultIMEWindow(hwnd
,TRUE
);
2286 case WM_IME_STARTCOMPOSITION
:
2287 TRACE("IME message %s, 0x%x, 0x%x\n",
2288 "WM_IME_STARTCOMPOSITION", (UINT
)wParam
, (UINT
)lParam
);
2289 root_context
->IMC
.hWnd
= GetFocus();
2290 ShowWindow(hwndDefault
,SW_SHOWNOACTIVATE
);
2292 case WM_IME_ENDCOMPOSITION
:
2293 TRACE("IME message %s, 0x%x, 0x%x\n",
2294 "WM_IME_ENDCOMPOSITION", (UINT
)wParam
, (UINT
)lParam
);
2295 ShowWindow(hwndDefault
,SW_HIDE
);
2298 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
2299 (UINT
)wParam
, (UINT
)lParam
);
2301 case WM_IME_CONTROL
:
2302 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
2303 (UINT
)wParam
, (UINT
)lParam
);
2307 TRACE("!! IME NOTIFY\n");
2310 TRACE("Non-standard message 0x%x\n",msg
);
2312 /* check the MSIME messages */
2313 if (msg
== WM_MSIME_SERVICE
)
2315 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
2316 (UINT
)wParam
, (UINT
)lParam
);
2319 else if (msg
== WM_MSIME_RECONVERTOPTIONS
)
2321 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
2322 (UINT
)wParam
, (UINT
)lParam
);
2324 else if (msg
== WM_MSIME_MOUSE
)
2326 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
2327 (UINT
)wParam
, (UINT
)lParam
);
2329 else if (msg
== WM_MSIME_RECONVERTREQUEST
)
2331 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
2332 (UINT
)wParam
, (UINT
)lParam
);
2334 else if (msg
== WM_MSIME_RECONVERT
)
2336 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
2337 (UINT
)wParam
, (UINT
)lParam
);
2339 else if (msg
== WM_MSIME_QUERYPOSITION
)
2341 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
2342 (UINT
)wParam
, (UINT
)lParam
);
2344 else if (msg
== WM_MSIME_DOCUMENTFEED
)
2346 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
2347 (UINT
)wParam
, (UINT
)lParam
);
2349 /* DefWndProc if not an IME message */
2350 else if (!rc
&& !((msg
>= WM_IME_STARTCOMPOSITION
&& msg
<= WM_IME_KEYLAST
) ||
2351 (msg
>= WM_IME_SETCONTEXT
&& msg
<= WM_IME_KEYUP
)))
2352 rc
= DefWindowProcW(hwnd
,msg
,wParam
,lParam
);