ReactOS 0.4.16-dev-334-g4d9f67c
imm32.c
Go to the documentation of this file.
1/*
2 * Unit tests for imm32
3 *
4 * Copyright (c) 2008 Michael Jung
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdio.h>
22
23#include "wine/test.h"
24#include "winuser.h"
25#include "wingdi.h"
26#include "imm.h"
27#ifdef __REACTOS__
28#include "ddk/immdev.h"
29#else
30#include "ddk/imm.h"
31#endif
32
33static BOOL (WINAPI *pImmAssociateContextEx)(HWND,HIMC,DWORD);
34static BOOL (WINAPI *pImmIsUIMessageA)(HWND,UINT,WPARAM,LPARAM);
35static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t);
36
37/*
38 * msgspy - record and analyse message traces sent to a certain window
39 */
40typedef struct _msgs {
44
45static struct _msg_spy {
50 unsigned int i_msg;
52
53typedef struct
54{
56 union
57 {
61 } u;
63
64#ifndef __REACTOS__
65typedef struct _tagTRANSMSG {
70#endif
71
72static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t);
73
75{
76 if (HC_ACTION == nCode) {
77 MSG *msg = (MSG*)lParam;
78
79 if ((msg->hwnd == msg_spy.hwnd || msg_spy.hwnd == NULL) &&
80 (msg_spy.i_msg < ARRAY_SIZE(msg_spy.msgs)))
81 {
82 msg_spy.msgs[msg_spy.i_msg].msg.hwnd = msg->hwnd;
83 msg_spy.msgs[msg_spy.i_msg].msg.message = msg->message;
84 msg_spy.msgs[msg_spy.i_msg].msg.wParam = msg->wParam;
85 msg_spy.msgs[msg_spy.i_msg].msg.lParam = msg->lParam;
86 msg_spy.msgs[msg_spy.i_msg].post = TRUE;
87 msg_spy.i_msg++;
88 }
89 }
90
91 return CallNextHookEx(msg_spy.get_msg_hook, nCode, wParam, lParam);
92}
93
96{
97 if (HC_ACTION == nCode) {
98 CWPSTRUCT *cwp = (CWPSTRUCT*)lParam;
99
100 if (((cwp->hwnd == msg_spy.hwnd || msg_spy.hwnd == NULL)) &&
101 (msg_spy.i_msg < ARRAY_SIZE(msg_spy.msgs)))
102 {
103 memcpy(&msg_spy.msgs[msg_spy.i_msg].msg, cwp, sizeof(msg_spy.msgs[0].msg));
104 msg_spy.msgs[msg_spy.i_msg].post = FALSE;
105 msg_spy.i_msg++;
106 }
107 }
108
109 return CallNextHookEx(msg_spy.call_wnd_proc_hook, nCode, wParam, lParam);
110}
111
112static void msg_spy_pump_msg_queue(void) {
113 MSG msg;
114
115 while(PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
118 }
119
120 return;
121}
122
123static void msg_spy_flush_msgs(void) {
125 msg_spy.i_msg = 0;
126}
127
129 UINT i;
130
132
133 if (msg_spy.i_msg >= ARRAY_SIZE(msg_spy.msgs))
134 fprintf(stdout, "%s:%d: msg_spy: message buffer overflow!\n",
135 __FILE__, __LINE__);
136
137 for (i = *start; i < msg_spy.i_msg; i++)
138 if (msg_spy.msgs[i].msg.message == message)
139 {
140 *start = i+1;
141 return &msg_spy.msgs[i];
142 }
143
144 return NULL;
145}
146
148 UINT i = 0;
149
151}
152
153static void msg_spy_init(HWND hwnd) {
154 msg_spy.hwnd = hwnd;
155 msg_spy.get_msg_hook =
158 msg_spy.call_wnd_proc_hook =
161 msg_spy.i_msg = 0;
162
164}
165
166static void msg_spy_cleanup(void) {
167 if (msg_spy.get_msg_hook)
168 UnhookWindowsHookEx(msg_spy.get_msg_hook);
169 if (msg_spy.call_wnd_proc_hook)
170 UnhookWindowsHookEx(msg_spy.call_wnd_proc_hook);
171 memset(&msg_spy, 0, sizeof(msg_spy));
172}
173
174/*
175 * imm32 test cases - Issue some IMM commands on a dummy window and analyse the
176 * messages being sent to this window in response.
177 */
178static const char wndcls[] = "winetest_imm32_wndcls";
181static HWND hwnd;
182
183static HWND get_ime_window(void);
184
186{
187 HWND default_ime_wnd;
188 switch (msg)
189 {
191 return TRUE;
192 case WM_NCCREATE:
193 default_ime_wnd = get_ime_window();
194 switch(test_phase) {
195 case FIRST_WINDOW:
196 case IME_DISABLED:
197 ok(!default_ime_wnd, "expected no IME windows\n");
198 break;
199 case SECOND_WINDOW:
200 ok(default_ime_wnd != NULL, "expected IME window existence\n");
201 break;
202 default:
203 break; /* do nothing */
204 }
206 return FALSE;
207 return TRUE;
208 case WM_NCCALCSIZE:
209 default_ime_wnd = get_ime_window();
210 switch(test_phase) {
211 case FIRST_WINDOW:
212 case SECOND_WINDOW:
213 case CREATE_CANCEL:
214 ok(default_ime_wnd != NULL, "expected IME window existence\n");
215 break;
216 case IME_DISABLED:
217 ok(!default_ime_wnd, "expected no IME windows\n");
218 break;
219 default:
220 break; /* do nothing */
221 }
222 break;
223 case WM_CREATE:
224 default_ime_wnd = get_ime_window();
225 switch(test_phase) {
226 case FIRST_WINDOW:
227 case SECOND_WINDOW:
228 case CREATE_CANCEL:
229 ok(default_ime_wnd != NULL, "expected IME window existence\n");
230 break;
231 case IME_DISABLED:
232 ok(!default_ime_wnd, "expected no IME windows\n");
233 break;
234 default:
235 break; /* do nothing */
236 }
238 return -1;
239 return TRUE;
240 }
241
243}
244
245static BOOL init(void) {
246 WNDCLASSEXA wc;
247 HIMC imc;
248 HMODULE hmod,huser;
249
250 hmod = GetModuleHandleA("imm32.dll");
251 huser = GetModuleHandleA("user32");
252 pImmAssociateContextEx = (void*)GetProcAddress(hmod, "ImmAssociateContextEx");
253 pImmIsUIMessageA = (void*)GetProcAddress(hmod, "ImmIsUIMessageA");
254 pSendInput = (void*)GetProcAddress(huser, "SendInput");
255
256 wc.cbSize = sizeof(WNDCLASSEXA);
257 wc.style = 0;
258 wc.lpfnWndProc = wndProc;
259 wc.cbClsExtra = 0;
260 wc.cbWndExtra = 0;
264 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
265 wc.lpszMenuName = NULL;
268
269 if (!RegisterClassExA(&wc))
270 return FALSE;
271
272 hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
274 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
275 if (!hwnd)
276 return FALSE;
277
278 imc = ImmGetContext(hwnd);
279 if (!imc)
280 {
281 win_skip("IME support not implemented\n");
282 return FALSE;
283 }
285
288
290
291 return TRUE;
292}
293
294static void cleanup(void) {
296 if (hwnd)
299}
300
301static void test_ImmNotifyIME(void) {
302#ifdef __REACTOS__
303 static char string[] = "wine";
304#else
305 static const char string[] = "wine";
306#endif
307 char resstr[16] = "";
308 HIMC imc;
309 BOOL ret;
310
311 imc = ImmGetContext(hwnd);
313
315 ok(broken(!ret) ||
316 ret, /* Vista+ */
317 "Canceling an empty composition string should succeed.\n");
318 ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post "
319 "WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if "
320 "the composition string being canceled is empty.\n");
321
322 ImmSetCompositionStringA(imc, SCS_SETSTR, string, sizeof(string), NULL, 0);
324
327
328 /* behavior differs between win9x and NT */
329 ret = ImmGetCompositionStringA(imc, GCS_COMPSTR, resstr, sizeof(resstr));
330 ok(!ret, "After being cancelled the composition string is empty.\n");
331
333
335 ok(broken(!ret) ||
336 ret, /* Vista+ */
337 "Canceling an empty composition string should succeed.\n");
338 ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post "
339 "WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if "
340 "the composition string being canceled is empty.\n");
341
344
345 imc = ImmCreateContext();
347
348 SetLastError(0xdeadbeef);
350 ok (ret == 0, "Bad IME should return 0\n");
351 ret = GetLastError();
352 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
353 SetLastError(0xdeadbeef);
354 ret = ImmNotifyIME(0x00000000, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
355 ok (ret == 0, "NULL IME should return 0\n");
356 ret = GetLastError();
357 ok(ret == ERROR_SUCCESS, "wrong last error %08x!\n", ret);
358 SetLastError(0xdeadbeef);
360 ok (ret == 0, "Destroyed IME should return 0\n");
361 ret = GetLastError();
362 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
363
364}
365
366static struct {
373
375{
376 switch (msg)
377 {
378 case WM_IME_COMPOSITION:
379 if ((lParam & GCS_RESULTSTR) && !ime_composition_test.catch_result_str) {
380 HWND hwndIme;
381 WCHAR wstring[20];
382 HIMC imc;
383 LONG size;
384 LRESULT ret;
385
386 hwndIme = ImmGetDefaultIMEWnd(hWnd);
387 ok(hwndIme != NULL, "expected IME window existence\n");
388
389 ok(!ime_composition_test.catch_ime_char, "WM_IME_CHAR is sent\n");
391 hWnd, msg, wParam, lParam);
392 ok(ime_composition_test.catch_ime_char, "WM_IME_CHAR isn't sent\n");
393
394 ime_composition_test.catch_ime_char = FALSE;
395 SendMessageA(hwndIme, msg, wParam, lParam);
396 ok(!ime_composition_test.catch_ime_char, "WM_IME_CHAR is sent\n");
397
398 imc = ImmGetContext(hWnd);
400 wstring, sizeof(wstring));
401 ok(size > 0, "ImmGetCompositionString(GCS_RESULTSTR) is %d\n", size);
403
404 ime_composition_test.catch_result_str = TRUE;
405 return ret;
406 }
407 break;
408 case WM_IME_CHAR:
409 if (!ime_composition_test.catch_result_str)
410 ime_composition_test.catch_ime_char = TRUE;
411 break;
412 case WM_TIMER:
413 if (wParam == ime_composition_test.timer_id) {
415 char title[64];
416 int left = 20 - (GetTickCount() - ime_composition_test.start) / 1000;
417 wsprintfA(title, "%sLeft %d sec. - IME composition test",
418 ime_composition_test.catch_result_str ? "[*] " : "", left);
420 if (left <= 0)
422 else
423 SetTimer(hWnd, wParam, 100, NULL);
424 return TRUE;
425 }
426 break;
427 }
428 return CallWindowProcA(ime_composition_test.old_wnd_proc,
429 hWnd, msg, wParam, lParam);
430}
431
433{
434 HIMC imc;
435#ifdef __REACTOS__
436 static WCHAR string[] = {'w','i','n','e',0x65e5,0x672c,0x8a9e};
437#else
438 static const WCHAR string[] = {'w','i','n','e',0x65e5,0x672c,0x8a9e};
439#endif
440 char cstring[20];
441 WCHAR wstring[20];
442 LONG len;
443 LONG alen,wlen;
444 BOOL ret;
445 DWORD prop;
446
447 imc = ImmGetContext(hwnd);
448 ret = ImmSetCompositionStringW(imc, SCS_SETSTR, string, sizeof(string), NULL,0);
449 if (!ret) {
450 win_skip("Composition isn't supported\n");
452 return;
453 }
455
456 alen = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, 20);
457 wlen = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, 20);
458 /* windows machines without any IME installed just return 0 above */
459 if( alen && wlen)
460 {
462 ok(len*sizeof(WCHAR)==wlen,"GCS_COMPATTR(W) not returning correct count\n");
464 ok(len==alen,"GCS_COMPATTR(A) not returning correct count\n");
465
466 /* Get strings with exactly matching buffer sizes. */
467 memset(wstring, 0x1a, sizeof(wstring));
468 memset(cstring, 0x1a, sizeof(cstring));
469
470 len = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, alen);
471 ok(len == alen, "Unexpected length %d.\n", len);
472 ok(cstring[alen] == 0x1a, "Unexpected buffer contents.\n");
473
474 len = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, wlen);
475 ok(len == wlen, "Unexpected length %d.\n", len);
476 ok(wstring[wlen/sizeof(WCHAR)] == 0x1a1a, "Unexpected buffer contents.\n");
477
478 /* Get strings with exactly smaller buffer sizes. */
479 memset(wstring, 0x1a, sizeof(wstring));
480 memset(cstring, 0x1a, sizeof(cstring));
481
482 /* Returns 0 but still fills buffer. */
483 len = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, alen - 1);
484 ok(!len, "Unexpected length %d.\n", len);
485 ok(cstring[0] == 'w', "Unexpected buffer contents %s.\n", cstring);
486
487 len = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, wlen - 1);
488 ok(len == wlen - 1, "Unexpected length %d.\n", len);
489 ok(!memcmp(wstring, string, wlen - 1), "Unexpected buffer contents.\n");
490
491 /* Get the size of the required output buffer. */
492 memset(wstring, 0x1a, sizeof(wstring));
493 memset(cstring, 0x1a, sizeof(cstring));
494
495 len = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, 0);
496 ok(len == alen, "Unexpected length %d.\n", len);
497 ok(cstring[0] == 0x1a, "Unexpected buffer contents %s.\n", cstring);
498
499 len = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, 0);
500 ok(len == wlen, "Unexpected length %d.\n", len);
501 ok(wstring[0] == 0x1a1a, "Unexpected buffer contents.\n");
502 }
503 else
504 win_skip("Composition string isn't available\n");
505
507
508 /* Test composition results input by IMM API */
510 if (!(prop & SCS_CAP_COMPSTR)) {
511 /* Wine's IME doesn't support SCS_SETSTR in ImmSetCompositionString */
512 skip("This IME doesn't support SCS_SETSTR\n");
513 }
514 else {
515 ime_composition_test.old_wnd_proc =
518 imc = ImmGetContext(hwnd);
520
522 string, sizeof(string), NULL,0);
523 ok(ret, "ImmSetCompositionStringW failed\n");
525 wstring, sizeof(wstring));
526 if (wlen > 0) {
528 ok(ret, "ImmNotifyIME(CPS_COMPLETE) failed\n");
530 ok(ime_composition_test.catch_result_str,
531 "WM_IME_COMPOSITION(GCS_RESULTSTR) isn't sent\n");
532 }
533 else
534 win_skip("Composition string isn't available\n");
537 (LONG_PTR)ime_composition_test.old_wnd_proc);
539 }
540
541 /* Test composition results input by hand */
544 HWND hwndMain, hwndChild;
545 MSG msg;
546 const DWORD MY_TIMER = 0xcaffe;
547
549 "IME composition test",
551 CW_USEDEFAULT, CW_USEDEFAULT, 320, 160,
553 hwndChild = CreateWindowExA(0, "static",
554 "Input a DBCS character here using IME.",
556 0, 0, 320, 100, hwndMain, NULL,
558
559 ime_composition_test.old_wnd_proc =
562
563 SetFocus(hwndChild);
564
565 ime_composition_test.timer_id = MY_TIMER;
567 SetTimer(hwndChild, ime_composition_test.timer_id, 100, NULL);
568 while (GetMessageA(&msg, NULL, 0, 0)) {
571 if (!IsWindow(hwndMain))
572 break;
573 }
574 if (!ime_composition_test.catch_result_str)
575 skip("WM_IME_COMPOSITION(GCS_RESULTSTR) isn't tested\n");
577 }
578}
579
581{
582 HIMC imc;
583 BOOL ret;
584
585 SetLastError(0xdeadbeef);
586 imc = ImmGetContext(hwnd);
587 ok(imc != 0, "ImmGetContext() failed. Last error: %u\n", GetLastError());
588 if (!imc)
589 return;
590
592 ok(broken(!ret) ||
593 ret, /* Vista+ */
594 "ImmSetCompositionStringW() failed.\n");
595
597 NULL, 0, NULL, 0);
598 ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
599
601 NULL, 0, NULL, 0);
602 ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
603
605 NULL, 0, NULL, 0);
606 ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
607
609 NULL, 0, NULL, 0);
610 ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
611
613}
614
615static void test_ImmIME(void)
616{
617 HIMC imc;
618
619 imc = ImmGetContext(hwnd);
620 if (imc)
621 {
622 BOOL rc;
623#ifdef __REACTOS__
625#else
627#endif
628 ok (rc == 0, "ImmConfigureIMEA did not fail\n");
629#ifdef __REACTOS__
631#else
633#endif
634 ok (rc == 0, "ImmConfigureIMEW did not fail\n");
635 }
637}
638
640{
641 HIMC imc;
642 BOOL rc;
643
644 if (!pImmAssociateContextEx) return;
645
646 imc = ImmGetContext(hwnd);
647 if (imc)
648 {
649 HIMC retimc, newimc;
650
651 newimc = ImmCreateContext();
652 ok(newimc != imc, "handles should not be the same\n");
653 rc = pImmAssociateContextEx(NULL, NULL, 0);
654 ok(!rc, "ImmAssociateContextEx succeeded\n");
655 rc = pImmAssociateContextEx(hwnd, NULL, 0);
656 ok(rc, "ImmAssociateContextEx failed\n");
657 rc = pImmAssociateContextEx(NULL, imc, 0);
658 ok(!rc, "ImmAssociateContextEx succeeded\n");
659
660 rc = pImmAssociateContextEx(hwnd, imc, 0);
661 ok(rc, "ImmAssociateContextEx failed\n");
662 retimc = ImmGetContext(hwnd);
663 ok(retimc == imc, "handles should be the same\n");
664 ImmReleaseContext(hwnd,retimc);
665
666 rc = pImmAssociateContextEx(hwnd, newimc, 0);
667 ok(rc, "ImmAssociateContextEx failed\n");
668 retimc = ImmGetContext(hwnd);
669 ok(retimc == newimc, "handles should be the same\n");
670 ImmReleaseContext(hwnd,retimc);
671
672 rc = pImmAssociateContextEx(hwnd, NULL, IACE_DEFAULT);
673 ok(rc, "ImmAssociateContextEx failed\n");
674 }
676}
677
678typedef struct _igc_threadinfo {
684
685
687{
688 HIMC h1,h2;
689 HWND hwnd2;
691 CANDIDATEFORM cdf;
692 POINT pt;
693 MSG msg;
694
696 info->hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
698 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
699
700 h1 = ImmGetContext(hwnd);
701 ok(info->himc == h1, "hwnd context changed in new thread\n");
702 h2 = ImmGetContext(info->hwnd);
703 ok(h2 != h1, "new hwnd in new thread should have different context\n");
704 info->himc = h2;
706
707 hwnd2 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
709 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
710 h1 = ImmGetContext(hwnd2);
711
712 ok(h1 == h2, "Windows in same thread should have same default context\n");
713 ImmReleaseContext(hwnd2,h1);
714 ImmReleaseContext(info->hwnd,h2);
715 DestroyWindow(hwnd2);
716
717 /* priming for later tests */
720 info->u_himc = ImmCreateContext();
721 ImmSetOpenStatus(info->u_himc, TRUE);
722 cdf.dwIndex = 0;
724 cdf.ptCurrentPos.x = 0;
725 cdf.ptCurrentPos.y = 0;
726 ImmSetCandidateWindow(info->u_himc, &cdf);
727
728 SetEvent(info->event);
729
730 while(GetMessageW(&msg, 0, 0, 0))
731 {
734 }
735 return 1;
736}
737
738static void test_ImmThreads(void)
739{
740 HIMC himc, otherHimc, h1;
741 igc_threadinfo threadinfo;
744 BOOL rc;
745 LOGFONTA lf;
747 CANDIDATEFORM cdf;
748 DWORD status, sentence;
749 POINT pt;
750
751 himc = ImmGetContext(hwnd);
752 threadinfo.event = CreateEventA(NULL, TRUE, FALSE, NULL);
753 threadinfo.himc = himc;
756
757 otherHimc = ImmGetContext(threadinfo.hwnd);
758
759 ok(himc != otherHimc, "Windows from other threads should have different himc\n");
760 ok(otherHimc == threadinfo.himc, "Context from other thread should not change in main thread\n");
761
762 h1 = ImmAssociateContext(hwnd,otherHimc);
763 ok(h1 == NULL, "Should fail to be able to Associate a default context from a different thread\n");
764 h1 = ImmGetContext(hwnd);
765 ok(h1 == himc, "Context for window should remain unchanged\n");
767
768 h1 = ImmAssociateContext(hwnd, threadinfo.u_himc);
769 ok (h1 == NULL, "Should fail to associate a context from a different thread\n");
770 h1 = ImmGetContext(hwnd);
771 ok(h1 == himc, "Context for window should remain unchanged\n");
773
774 h1 = ImmAssociateContext(threadinfo.hwnd, threadinfo.u_himc);
775 ok (h1 == NULL, "Should fail to associate a context from a different thread into a window from that thread.\n");
776 h1 = ImmGetContext(threadinfo.hwnd);
777 ok(h1 == threadinfo.himc, "Context for window should remain unchanged\n");
778 ImmReleaseContext(threadinfo.hwnd,h1);
779
780 /* OpenStatus */
781 rc = ImmSetOpenStatus(himc, TRUE);
782 ok(rc != 0, "ImmSetOpenStatus failed\n");
783 rc = ImmGetOpenStatus(himc);
784 ok(rc != 0, "ImmGetOpenStatus failed\n");
785 rc = ImmSetOpenStatus(himc, FALSE);
786 ok(rc != 0, "ImmSetOpenStatus failed\n");
787 rc = ImmGetOpenStatus(himc);
788 ok(rc == 0, "ImmGetOpenStatus failed\n");
789
790 rc = ImmSetOpenStatus(otherHimc, TRUE);
791 ok(rc == 0, "ImmSetOpenStatus should fail\n");
792 rc = ImmSetOpenStatus(threadinfo.u_himc, TRUE);
793 ok(rc == 0, "ImmSetOpenStatus should fail\n");
794 rc = ImmGetOpenStatus(otherHimc);
795 ok(rc == 0, "ImmGetOpenStatus failed\n");
796 rc = ImmGetOpenStatus(threadinfo.u_himc);
797 ok (rc == 1 || broken(rc == 0), "ImmGetOpenStatus should return 1\n");
798 rc = ImmSetOpenStatus(otherHimc, FALSE);
799 ok(rc == 0, "ImmSetOpenStatus should fail\n");
800 rc = ImmGetOpenStatus(otherHimc);
801 ok(rc == 0, "ImmGetOpenStatus failed\n");
802
803 /* CompositionFont */
804 rc = ImmGetCompositionFontA(himc, &lf);
805 ok(rc != 0, "ImmGetCompositionFont failed\n");
806 rc = ImmSetCompositionFontA(himc, &lf);
807 ok(rc != 0, "ImmSetCompositionFont failed\n");
808
809 rc = ImmGetCompositionFontA(otherHimc, &lf);
810 ok(rc != 0 || broken(rc == 0), "ImmGetCompositionFont failed\n");
811 rc = ImmGetCompositionFontA(threadinfo.u_himc, &lf);
812 ok(rc != 0 || broken(rc == 0), "ImmGetCompositionFont user himc failed\n");
813 rc = ImmSetCompositionFontA(otherHimc, &lf);
814 ok(rc == 0, "ImmSetCompositionFont should fail\n");
815 rc = ImmSetCompositionFontA(threadinfo.u_himc, &lf);
816 ok(rc == 0, "ImmSetCompositionFont should fail\n");
817
818 /* CompositionWindow */
819 rc = ImmSetCompositionWindow(himc, &cf);
820 ok(rc != 0, "ImmSetCompositionWindow failed\n");
821 rc = ImmGetCompositionWindow(himc, &cf);
822 ok(rc != 0, "ImmGetCompositionWindow failed\n");
823
824 rc = ImmSetCompositionWindow(otherHimc, &cf);
825 ok(rc == 0, "ImmSetCompositionWindow should fail\n");
826 rc = ImmSetCompositionWindow(threadinfo.u_himc, &cf);
827 ok(rc == 0, "ImmSetCompositionWindow should fail\n");
828 rc = ImmGetCompositionWindow(otherHimc, &cf);
829 ok(rc != 0 || broken(rc == 0), "ImmGetCompositionWindow failed\n");
830 rc = ImmGetCompositionWindow(threadinfo.u_himc, &cf);
831 ok(rc != 0 || broken(rc == 0), "ImmGetCompositionWindow failed\n");
832
833 /* ConversionStatus */
834 rc = ImmGetConversionStatus(himc, &status, &sentence);
835 ok(rc != 0, "ImmGetConversionStatus failed\n");
836 rc = ImmSetConversionStatus(himc, status, sentence);
837 ok(rc != 0, "ImmSetConversionStatus failed\n");
838
839 rc = ImmGetConversionStatus(otherHimc, &status, &sentence);
840 ok(rc != 0 || broken(rc == 0), "ImmGetConversionStatus failed\n");
841 rc = ImmGetConversionStatus(threadinfo.u_himc, &status, &sentence);
842 ok(rc != 0 || broken(rc == 0), "ImmGetConversionStatus failed\n");
843 rc = ImmSetConversionStatus(otherHimc, status, sentence);
844 ok(rc == 0, "ImmSetConversionStatus should fail\n");
845 rc = ImmSetConversionStatus(threadinfo.u_himc, status, sentence);
846 ok(rc == 0, "ImmSetConversionStatus should fail\n");
847
848 /* StatusWindowPos */
849 rc = ImmSetStatusWindowPos(himc, &pt);
850 ok(rc != 0, "ImmSetStatusWindowPos failed\n");
851 rc = ImmGetStatusWindowPos(himc, &pt);
852 ok(rc != 0, "ImmGetStatusWindowPos failed\n");
853
854 rc = ImmSetStatusWindowPos(otherHimc, &pt);
855 ok(rc == 0, "ImmSetStatusWindowPos should fail\n");
856 rc = ImmSetStatusWindowPos(threadinfo.u_himc, &pt);
857 ok(rc == 0, "ImmSetStatusWindowPos should fail\n");
858 rc = ImmGetStatusWindowPos(otherHimc, &pt);
859 ok(rc != 0 || broken(rc == 0), "ImmGetStatusWindowPos failed\n");
860 rc = ImmGetStatusWindowPos(threadinfo.u_himc, &pt);
861 ok(rc != 0 || broken(rc == 0), "ImmGetStatusWindowPos failed\n");
862
863 h1 = ImmAssociateContext(threadinfo.hwnd, NULL);
864 ok (h1 == otherHimc, "ImmAssociateContext cross thread with NULL should work\n");
865 h1 = ImmGetContext(threadinfo.hwnd);
866 ok (h1 == NULL, "CrossThread window context should be NULL\n");
867 h1 = ImmAssociateContext(threadinfo.hwnd, h1);
868 ok (h1 == NULL, "Resetting cross thread context should fail\n");
869 h1 = ImmGetContext(threadinfo.hwnd);
870 ok (h1 == NULL, "CrossThread window context should still be NULL\n");
871
872 rc = ImmDestroyContext(threadinfo.u_himc);
873 ok (rc == 0, "ImmDestroyContext Cross Thread should fail\n");
874
875 /* Candidate Window */
876 rc = ImmGetCandidateWindow(himc, 0, &cdf);
877 ok (rc == 0, "ImmGetCandidateWindow should fail\n");
878 cdf.dwIndex = 0;
880 cdf.ptCurrentPos.x = 0;
881 cdf.ptCurrentPos.y = 0;
882 rc = ImmSetCandidateWindow(himc, &cdf);
883 ok (rc == 1, "ImmSetCandidateWindow should succeed\n");
884 rc = ImmGetCandidateWindow(himc, 0, &cdf);
885 ok (rc == 1, "ImmGetCandidateWindow should succeed\n");
886
887 rc = ImmGetCandidateWindow(otherHimc, 0, &cdf);
888 ok (rc == 0, "ImmGetCandidateWindow should fail\n");
889 rc = ImmSetCandidateWindow(otherHimc, &cdf);
890 ok (rc == 0, "ImmSetCandidateWindow should fail\n");
891 rc = ImmGetCandidateWindow(threadinfo.u_himc, 0, &cdf);
892 ok (rc == 1 || broken( rc == 0), "ImmGetCandidateWindow should succeed\n");
893 rc = ImmSetCandidateWindow(threadinfo.u_himc, &cdf);
894 ok (rc == 0, "ImmSetCandidateWindow should fail\n");
895
896 ImmReleaseContext(threadinfo.hwnd,otherHimc);
898
899 SendMessageA(threadinfo.hwnd, WM_CLOSE, 0, 0);
901 ok(rc == 1, "PostThreadMessage should succeed\n");
904
906 ok(himc == NULL, "Should not be able to get himc from other process window\n");
907}
908
909static void test_ImmIsUIMessage(void)
910{
911 struct test
912 {
913 UINT msg;
914 BOOL ret;
915 };
916
917 static const struct test tests[] =
918 {
919 { WM_MOUSEMOVE, FALSE },
920 { WM_IME_STARTCOMPOSITION, TRUE },
921 { WM_IME_ENDCOMPOSITION, TRUE },
922 { WM_IME_COMPOSITION, TRUE },
924 { WM_IME_NOTIFY, TRUE },
927 { WM_IME_SELECT, TRUE },
928 { WM_IME_CHAR, FALSE },
929 { 0x287 /* FIXME */, TRUE },
932 { WM_IME_KEYUP, FALSE },
933 { 0, FALSE } /* mark the end */
934 };
935
937 UINT WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
938 UINT WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
939 UINT WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
941 UINT WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
943
944 const struct test *test;
945 BOOL ret;
946
947 if (!pImmIsUIMessageA) return;
948
949 for (test = tests; test->msg; test++)
950 {
952 ret = pImmIsUIMessageA(NULL, test->msg, 0, 0);
953 ok(ret == test->ret, "ImmIsUIMessageA returned %x for %x\n", ret, test->msg);
954 ok(!msg_spy_find_msg(test->msg), "Windows does not send 0x%x for NULL hwnd\n", test->msg);
955
956 ret = pImmIsUIMessageA(hwnd, test->msg, 0, 0);
957 ok(ret == test->ret, "ImmIsUIMessageA returned %x for %x\n", ret, test->msg);
958 if (ret)
959 ok(msg_spy_find_msg(test->msg) != NULL, "Windows does send 0x%x\n", test->msg);
960 else
961 ok(!msg_spy_find_msg(test->msg), "Windows does not send 0x%x\n", test->msg);
962 }
963
964 ret = pImmIsUIMessageA(NULL, WM_MSIME_SERVICE, 0, 0);
965 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_SERVICE\n");
966 ret = pImmIsUIMessageA(NULL, WM_MSIME_RECONVERTOPTIONS, 0, 0);
967 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_RECONVERTOPTIONS\n");
968 ret = pImmIsUIMessageA(NULL, WM_MSIME_MOUSE, 0, 0);
969 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_MOUSE\n");
970 ret = pImmIsUIMessageA(NULL, WM_MSIME_RECONVERTREQUEST, 0, 0);
971 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_RECONVERTREQUEST\n");
972 ret = pImmIsUIMessageA(NULL, WM_MSIME_RECONVERT, 0, 0);
973 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_RECONVERT\n");
974 ret = pImmIsUIMessageA(NULL, WM_MSIME_QUERYPOSITION, 0, 0);
975 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_QUERYPOSITION\n");
976 ret = pImmIsUIMessageA(NULL, WM_MSIME_DOCUMENTFEED, 0, 0);
977 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_DOCUMENTFEED\n");
978}
979
980static void test_ImmGetContext(void)
981{
982 HIMC himc;
983 DWORD err;
984
985 SetLastError(0xdeadbeef);
986 himc = ImmGetContext((HWND)0xffffffff);
987 err = GetLastError();
988 ok(himc == NULL, "ImmGetContext succeeded\n");
989 ok(err == ERROR_INVALID_WINDOW_HANDLE, "got %u\n", err);
990
991 himc = ImmGetContext(hwnd);
992 ok(himc != NULL, "ImmGetContext failed\n");
993 ok(ImmReleaseContext(hwnd, himc), "ImmReleaseContext failed\n");
994}
995
996static void test_ImmGetDescription(void)
997{
998 HKL hkl;
999 WCHAR descW[100];
1000 CHAR descA[100];
1001 UINT ret, lret;
1002
1003 /* FIXME: invalid keyboard layouts should not pass */
1005 ok(!ret, "ImmGetDescriptionW failed, expected 0 received %d.\n", ret);
1007 ok(!ret, "ImmGetDescriptionA failed, expected 0 received %d.\n", ret);
1008
1009 /* load a language with valid IMM descriptions */
1011 ok(hkl != 0, "GetKeyboardLayout failed, expected != 0.\n");
1012
1014 if(!ret)
1015 {
1016 win_skip("ImmGetDescriptionW is not working for current loaded keyboard.\n");
1017 return;
1018 }
1019
1020 SetLastError(0xdeadcafe);
1021 ret = ImmGetDescriptionW(0, NULL, 100);
1022 ok (ret == 0, "ImmGetDescriptionW with 0 hkl should return 0\n");
1023 ret = GetLastError();
1024 ok (ret == 0xdeadcafe, "Last Error should remain unchanged\n");
1025
1026 ret = ImmGetDescriptionW(hkl, descW, 0);
1027 ok(ret, "ImmGetDescriptionW failed, expected != 0 received 0.\n");
1028
1029 lret = ImmGetDescriptionW(hkl, descW, ret + 1);
1030 ok(lret, "ImmGetDescriptionW failed, expected != 0 received 0.\n");
1031 ok(lret == ret, "ImmGetDescriptionW failed to return the correct amount of data. Expected %d, got %d.\n", ret, lret);
1032
1033 lret = ImmGetDescriptionA(hkl, descA, ret + 1);
1034 ok(lret, "ImmGetDescriptionA failed, expected != 0 received 0.\n");
1035 ok(lret == ret, "ImmGetDescriptionA failed to return the correct amount of data. Expected %d, got %d.\n", ret, lret);
1036
1037 ret /= 2; /* try to copy partially */
1038 lret = ImmGetDescriptionW(hkl, descW, ret + 1);
1039 ok(lret, "ImmGetDescriptionW failed, expected != 0 received 0.\n");
1040 ok(lret == ret, "ImmGetDescriptionW failed to return the correct amount of data. Expected %d, got %d.\n", ret, lret);
1041
1042 lret = ImmGetDescriptionA(hkl, descA, ret + 1);
1043 ok(!lret, "ImmGetDescriptionA should fail\n");
1044
1045 ret = ImmGetDescriptionW(hkl, descW, 1);
1046 ok(!ret, "ImmGetDescriptionW failed, expected 0 received %d.\n", ret);
1047
1049}
1050
1051static LRESULT (WINAPI *old_imm_wnd_proc)(HWND, UINT, WPARAM, LPARAM);
1053{
1054 ok(msg != WM_DESTROY, "got WM_DESTROY message\n");
1055 return old_imm_wnd_proc(hwnd, msg, wparam, lparam);
1056}
1057
1060{
1061 CreateWindowA("static", "static", WS_POPUP, 0, 0, 1, 1, NULL, NULL, NULL, NULL);
1062
1064 ok(thread_ime_wnd != 0, "ImmGetDefaultIMEWnd returned NULL\n");
1066 return 0;
1067}
1068
1069static void test_ImmDefaultHwnd(void)
1070{
1071 HIMC imc1, imc2, imc3;
1072 HWND def1, def3;
1073 HANDLE thread;
1074 HWND hwnd;
1075 char title[16];
1076 LONG style;
1077
1078 hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "Wine imm32.dll test",
1080 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1081
1083
1084 imc1 = ImmGetContext(hwnd);
1085 if (!imc1)
1086 {
1087 win_skip("IME support not implemented\n");
1088 return;
1089 }
1090
1091 def1 = ImmGetDefaultIMEWnd(hwnd);
1092
1093 GetWindowTextA(def1, title, sizeof(title));
1094 ok(!strcmp(title, "Default IME"), "got %s\n", title);
1096 ok(style == (WS_DISABLED | WS_POPUP | WS_CLIPSIBLINGS), "got %08x\n", style);
1098 ok(style == 0, "got %08x\n", style);
1099
1100 imc2 = ImmCreateContext();
1101 ImmSetOpenStatus(imc2, TRUE);
1102
1103 imc3 = ImmGetContext(hwnd);
1104 def3 = ImmGetDefaultIMEWnd(hwnd);
1105
1106 ok(def3 == def1, "Default IME window should not change\n");
1107 ok(imc1 == imc3, "IME context should not change\n");
1108 ImmSetOpenStatus(imc2, FALSE);
1109
1112 ok(thread_ime_wnd != def1, "thread_ime_wnd == def1\n");
1113 ok(!IsWindow(thread_ime_wnd), "thread_ime_wnd was not destroyed\n");
1115
1116 ImmReleaseContext(hwnd, imc1);
1117 ImmReleaseContext(hwnd, imc3);
1118 ImmDestroyContext(imc2);
1120}
1121
1123{
1124 static const WCHAR imeW[] = {'I','M','E',0};
1125 WCHAR class_nameW[16];
1126 HWND *ime_window = (HWND *)param;
1127 if (GetClassNameW(hWnd, class_nameW, ARRAY_SIZE(class_nameW)) && !lstrcmpW(class_nameW, imeW))
1128 {
1129 *ime_window = hWnd;
1130 return FALSE;
1131 }
1132 return TRUE;
1133}
1134
1136{
1137 HWND ime_window = NULL;
1139 return ime_window;
1140}
1141
1145};
1146
1148{
1149 struct testcase_ime_window *testcase = (struct testcase_ime_window *)arg;
1150 DWORD visible = testcase->visible ? WS_VISIBLE : 0;
1151 HWND hwnd1, hwnd2, default_ime_wnd, ime_wnd;
1152
1153 ok(!get_ime_window(), "Expected no IME windows\n");
1154 if (testcase->top_level_window) {
1156 hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1159 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1160 }
1161 else {
1162 hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "Wine imm32.dll test",
1163 WS_CHILD | visible,
1165 240, 24, hwnd, NULL, GetModuleHandleW(NULL), NULL);
1166 }
1167 ime_wnd = get_ime_window();
1168 ok(ime_wnd != NULL, "Expected IME window existence\n");
1169 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd1);
1170 ok(ime_wnd == default_ime_wnd, "Expected %p, got %p\n", ime_wnd, default_ime_wnd);
1171
1173 hwnd2 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1176 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1177 DestroyWindow(hwnd2);
1178 ok(IsWindow(ime_wnd) ||
1179 broken(!testcase->visible /* Vista */) ||
1180 broken(!testcase->top_level_window /* Vista */) ,
1181 "Expected IME window existence\n");
1182 DestroyWindow(hwnd1);
1183 ok(!IsWindow(ime_wnd), "Expected no IME windows\n");
1184 return 1;
1185}
1186
1188{
1189 struct testcase_ime_window *testcase = (struct testcase_ime_window *)arg;
1190 DWORD visible = testcase->visible ? WS_VISIBLE : 0;
1191 HWND hwnd1, hwnd2, default_ime_wnd, ime_wnd;
1192
1193 ok(!get_ime_window(), "Expected no IME windows\n");
1195 hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1198 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1199 ok(hwnd1 == NULL, "creation succeeded, got %p\n", hwnd1);
1200 ok(!get_ime_window(), "Expected no IME windows\n");
1201
1203 hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1206 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1207 ok(hwnd1 == NULL, "creation succeeded, got %p\n", hwnd1);
1208 ok(!get_ime_window(), "Expected no IME windows\n");
1209
1211 hwnd2 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1214 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1215 ime_wnd = get_ime_window();
1216 ok(ime_wnd != NULL, "Expected IME window existence\n");
1217 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd2);
1218 ok(ime_wnd == default_ime_wnd, "Expected %p, got %p\n", ime_wnd, default_ime_wnd);
1219
1220 DestroyWindow(hwnd2);
1221 ok(!IsWindow(ime_wnd), "Expected no IME windows\n");
1222 return 1;
1223}
1224
1226{
1227 HWND hWnd, default_ime_wnd;
1228
1229 ok(!get_ime_window(), "Expected no IME windows\n");
1232 hWnd = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1235 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1236 default_ime_wnd = ImmGetDefaultIMEWnd(hWnd);
1237 ok(!default_ime_wnd, "Expected no IME windows\n");
1239 return 1;
1240}
1241
1243{
1244 HWND hwnd1, hwnd2, default_ime_wnd;
1245
1247 hwnd1 = CreateWindowA(wndcls, "Wine imm32.dll test",
1251 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd1);
1252 ok(!IsWindow(default_ime_wnd), "Expected no IME windows, got %p\n", default_ime_wnd);
1253
1254 hwnd2 = CreateWindowA(wndcls, "Wine imm32.dll test",
1257 240, 120, hwnd1, NULL, GetModuleHandleW(NULL), NULL);
1258 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd2);
1259 ok(IsWindow(default_ime_wnd), "Expected IME window existence\n");
1260
1261 DestroyWindow(hwnd2);
1262 DestroyWindow(hwnd1);
1263
1264 hwnd1 = CreateWindowA(wndcls, "Wine imm32.dll test",
1267 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1268 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd1);
1269 ok(IsWindow(default_ime_wnd), "Expected IME window existence\n");
1270 SetParent(hwnd1, HWND_MESSAGE);
1271 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd1);
1272 ok(IsWindow(default_ime_wnd), "Expected IME window existence\n");
1273 DestroyWindow(hwnd1);
1274 return 1;
1275}
1276
1278{
1279 HANDLE thread;
1280 size_t i;
1281 struct testcase_ime_window testcases[] = {
1282 /* visible, top-level window */
1283 { TRUE, TRUE },
1284 { FALSE, TRUE },
1285 { TRUE, FALSE },
1286 { FALSE, FALSE }
1287 };
1288
1289 for (i = 0; i < ARRAY_SIZE(testcases); i++)
1290 {
1291 thread = CreateThread(NULL, 0, test_default_ime_window_cb, &testcases[i], 0, NULL);
1292 ok(thread != NULL, "CreateThread failed with error %u\n", GetLastError());
1294 {
1295 MSG msg;
1296 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
1297 {
1300 }
1301 }
1303
1304 if (testcases[i].top_level_window)
1305 {
1307 ok(thread != NULL, "CreateThread failed with error %u\n", GetLastError());
1310 }
1311 }
1312
1316
1320
1322}
1323
1325{
1326 HIMC imc;
1327 DWORD count, ret, i;
1328 INPUTCONTEXT *ic;
1329
1330 imc = ImmCreateContext();
1331 ImmDestroyContext(imc);
1332 SetLastError(0xdeadbeef);
1333 count = ImmGetIMCLockCount((HIMC)0xdeadcafe);
1334 ok(count == 0, "Invalid IMC should return 0\n");
1335 ret = GetLastError();
1336 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1337 SetLastError(0xdeadbeef);
1338 count = ImmGetIMCLockCount(0x00000000);
1339 ok(count == 0, "NULL IMC should return 0\n");
1340 ret = GetLastError();
1341 ok(ret == 0xdeadbeef, "Last Error should remain unchanged: %08x\n",ret);
1343 ok(count == 0, "Destroyed IMC should return 0\n");
1344 ret = GetLastError();
1345 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1346
1347 imc = ImmCreateContext();
1349 ok(count == 0, "expect 0, returned %d\n", count);
1350 ic = ImmLockIMC(imc);
1351 ok(ic != NULL, "ImmLockIMC failed!\n");
1353 ok(count == 1, "expect 1, returned %d\n", count);
1354 ret = ImmUnlockIMC(imc);
1355 ok(ret == TRUE, "expect TRUE, ret %d\n", ret);
1357 ok(count == 0, "expect 0, returned %d\n", count);
1358 ret = ImmUnlockIMC(imc);
1359 ok(ret == TRUE, "expect TRUE, ret %d\n", ret);
1361 ok(count == 0, "expect 0, returned %d\n", count);
1362
1363 for (i = 0; i < GMEM_LOCKCOUNT * 2; i++)
1364 {
1365 ic = ImmLockIMC(imc);
1366 ok(ic != NULL, "ImmLockIMC failed!\n");
1367 }
1369 todo_wine ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count);
1370
1371 for (i = 0; i < GMEM_LOCKCOUNT - 1; i++)
1372 ImmUnlockIMC(imc);
1374 todo_wine ok(count == 1, "expect 1, returned %d\n", count);
1375 ImmUnlockIMC(imc);
1377 todo_wine ok(count == 0, "expect 0, returned %d\n", count);
1378
1379 ImmDestroyContext(imc);
1380}
1381
1383{
1384 HIMCC imcc;
1385 DWORD count, g_count, i;
1386 BOOL ret;
1387 VOID *p;
1388
1389 imcc = ImmCreateIMCC(sizeof(CANDIDATEINFO));
1390 count = ImmGetIMCCLockCount(imcc);
1391 ok(count == 0, "expect 0, returned %d\n", count);
1392 ImmLockIMCC(imcc);
1393 count = ImmGetIMCCLockCount(imcc);
1394 ok(count == 1, "expect 1, returned %d\n", count);
1395 ret = ImmUnlockIMCC(imcc);
1396 ok(ret == FALSE, "expect FALSE, ret %d\n", ret);
1397 count = ImmGetIMCCLockCount(imcc);
1398 ok(count == 0, "expect 0, returned %d\n", count);
1399 ret = ImmUnlockIMCC(imcc);
1400 ok(ret == FALSE, "expect FALSE, ret %d\n", ret);
1401 count = ImmGetIMCCLockCount(imcc);
1402 ok(count == 0, "expect 0, returned %d\n", count);
1403
1404 p = ImmLockIMCC(imcc);
1405 ok(GlobalHandle(p) == imcc, "expect %p, returned %p\n", imcc, GlobalHandle(p));
1406
1407 for (i = 0; i < GMEM_LOCKCOUNT * 2; i++)
1408 {
1409 ImmLockIMCC(imcc);
1410 count = ImmGetIMCCLockCount(imcc);
1411 g_count = GlobalFlags(imcc) & GMEM_LOCKCOUNT;
1412 ok(count == g_count, "count %d, g_count %d\n", count, g_count);
1413 }
1414 count = ImmGetIMCCLockCount(imcc);
1415 ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count);
1416
1417 for (i = 0; i < GMEM_LOCKCOUNT - 1; i++)
1418 GlobalUnlock(imcc);
1419 count = ImmGetIMCCLockCount(imcc);
1420 ok(count == 1, "expect 1, returned %d\n", count);
1421 GlobalUnlock(imcc);
1422 count = ImmGetIMCCLockCount(imcc);
1423 ok(count == 0, "expect 0, returned %d\n", count);
1424
1425 ImmDestroyIMCC(imcc);
1426}
1427
1428static void test_ImmDestroyContext(void)
1429{
1430 HIMC imc;
1431 DWORD ret, count;
1432 INPUTCONTEXT *ic;
1433
1434 imc = ImmCreateContext();
1436 ok(count == 0, "expect 0, returned %d\n", count);
1437 ic = ImmLockIMC(imc);
1438 ok(ic != NULL, "ImmLockIMC failed!\n");
1440 ok(count == 1, "expect 1, returned %d\n", count);
1441 ret = ImmDestroyContext(imc);
1442 ok(ret == TRUE, "Destroy a locked IMC should success!\n");
1443 ic = ImmLockIMC(imc);
1444 ok(ic == NULL, "Lock a destroyed IMC should fail!\n");
1445 ret = ImmUnlockIMC(imc);
1446 ok(ret == FALSE, "Unlock a destroyed IMC should fail!\n");
1448 ok(count == 0, "Get lock count of a destroyed IMC should return 0!\n");
1449 SetLastError(0xdeadbeef);
1450 ret = ImmDestroyContext(imc);
1451 ok(ret == FALSE, "Destroy a destroyed IMC should fail!\n");
1452 ret = GetLastError();
1453 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1454}
1455
1456static void test_ImmDestroyIMCC(void)
1457{
1458 HIMCC imcc;
1459 DWORD ret, count, size;
1460 VOID *p;
1461
1462 imcc = ImmCreateIMCC(sizeof(CANDIDATEINFO));
1463 count = ImmGetIMCCLockCount(imcc);
1464 ok(count == 0, "expect 0, returned %d\n", count);
1465 p = ImmLockIMCC(imcc);
1466 ok(p != NULL, "ImmLockIMCC failed!\n");
1467 count = ImmGetIMCCLockCount(imcc);
1468 ok(count == 1, "expect 1, returned %d\n", count);
1469 size = ImmGetIMCCSize(imcc);
1470 ok(size == sizeof(CANDIDATEINFO), "returned %d\n", size);
1471 p = ImmDestroyIMCC(imcc);
1472 ok(p == NULL, "Destroy a locked IMCC should success!\n");
1473 p = ImmLockIMCC(imcc);
1474 ok(p == NULL, "Lock a destroyed IMCC should fail!\n");
1475 ret = ImmUnlockIMCC(imcc);
1476 ok(ret == FALSE, "Unlock a destroyed IMCC should return FALSE!\n");
1477 count = ImmGetIMCCLockCount(imcc);
1478 ok(count == 0, "Get lock count of a destroyed IMCC should return 0!\n");
1479 size = ImmGetIMCCSize(imcc);
1480 ok(size == 0, "Get size of a destroyed IMCC should return 0!\n");
1481 SetLastError(0xdeadbeef);
1482 p = ImmDestroyIMCC(imcc);
1483 ok(p != NULL, "returned NULL\n");
1484 ret = GetLastError();
1485 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1486}
1487
1488static void test_ImmMessages(void)
1489{
1491 imm_msgs *msg;
1492 HWND defwnd;
1493 HIMC imc;
1494 UINT idx = 0;
1495
1496 LPINPUTCONTEXT lpIMC;
1497 LPTRANSMSG lpTransMsg;
1498
1499 HWND hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "Wine imm32.dll test",
1501 240, 120, NULL, NULL, GetModuleHandleA(NULL), NULL);
1502
1504 defwnd = ImmGetDefaultIMEWnd(hwnd);
1505 imc = ImmGetContext(hwnd);
1506
1507 ImmSetOpenStatus(imc, TRUE);
1510 do
1511 {
1513 if (msg) ok(!msg->post, "Message should not be posted\n");
1514 } while (msg);
1516
1517 lpIMC = ImmLockIMC(imc);
1518 lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) * sizeof(TRANSMSG));
1519 lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf);
1520 lpTransMsg += lpIMC->dwNumMsgBuf;
1521 lpTransMsg->message = WM_IME_STARTCOMPOSITION;
1522 lpTransMsg->wParam = 0;
1523 lpTransMsg->lParam = 0;
1524 ImmUnlockIMCC(lpIMC->hMsgBuf);
1525 lpIMC->dwNumMsgBuf++;
1526 ImmUnlockIMC(imc);
1527 ImmGenerateMessage(imc);
1528 idx = 0;
1529 do
1530 {
1531 msg = msg_spy_find_next_msg(WM_IME_STARTCOMPOSITION, &idx);
1532 if (msg) ok(!msg->post, "Message should not be posted\n");
1533 } while (msg);
1535
1536 lpIMC = ImmLockIMC(imc);
1537 lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) * sizeof(TRANSMSG));
1538 lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf);
1539 lpTransMsg += lpIMC->dwNumMsgBuf;
1540 lpTransMsg->message = WM_IME_COMPOSITION;
1541 lpTransMsg->wParam = 0;
1542 lpTransMsg->lParam = 0;
1543 ImmUnlockIMCC(lpIMC->hMsgBuf);
1544 lpIMC->dwNumMsgBuf++;
1545 ImmUnlockIMC(imc);
1546 ImmGenerateMessage(imc);
1547 idx = 0;
1548 do
1549 {
1550 msg = msg_spy_find_next_msg(WM_IME_COMPOSITION, &idx);
1551 if (msg) ok(!msg->post, "Message should not be posted\n");
1552 } while (msg);
1554
1555 lpIMC = ImmLockIMC(imc);
1556 lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) * sizeof(TRANSMSG));
1557 lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf);
1558 lpTransMsg += lpIMC->dwNumMsgBuf;
1559 lpTransMsg->message = WM_IME_ENDCOMPOSITION;
1560 lpTransMsg->wParam = 0;
1561 lpTransMsg->lParam = 0;
1562 ImmUnlockIMCC(lpIMC->hMsgBuf);
1563 lpIMC->dwNumMsgBuf++;
1564 ImmUnlockIMC(imc);
1565 ImmGenerateMessage(imc);
1566 idx = 0;
1567 do
1568 {
1569 msg = msg_spy_find_next_msg(WM_IME_ENDCOMPOSITION, &idx);
1570 if (msg) ok(!msg->post, "Message should not be posted\n");
1571 } while (msg);
1573
1574 ImmSetOpenStatus(imc, FALSE);
1575 ImmReleaseContext(hwnd, imc);
1577}
1578
1580 LPARAM lParam )
1581{
1582 return DefWindowProcW(hWnd, msg, wParam, lParam);
1583}
1584
1585static void test_ime_processkey(void)
1586{
1587 WCHAR classNameW[] = {'P','r','o','c','e','s','s', 'K','e','y','T','e','s','t','C','l','a','s','s',0};
1588 WCHAR windowNameW[] = {'P','r','o','c','e','s','s', 'K','e','y',0};
1589
1590 MSG msg;
1591 WNDCLASSW wclass;
1593 TEST_INPUT inputs[2];
1594 HIMC imc;
1595 INT rc;
1596 HWND hWndTest;
1597
1598 wclass.lpszClassName = classNameW;
1599 wclass.style = CS_HREDRAW | CS_VREDRAW;
1601 wclass.hInstance = hInstance;
1602 wclass.hIcon = LoadIconW(0, (LPCWSTR)IDI_APPLICATION);
1604 wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1605 wclass.lpszMenuName = 0;
1606 wclass.cbClsExtra = 0;
1607 wclass.cbWndExtra = 0;
1608 if(!RegisterClassW(&wclass)){
1609 win_skip("Failed to register window.\n");
1610 return;
1611 }
1612
1613 /* create the test window that will receive the keystrokes */
1614 hWndTest = CreateWindowW(wclass.lpszClassName, windowNameW,
1615 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100,
1616 NULL, NULL, hInstance, NULL);
1617
1622
1623 imc = ImmGetContext(hWndTest);
1624 if (!imc)
1625 {
1626 win_skip("IME not supported\n");
1628 return;
1629 }
1630
1631 rc = ImmSetOpenStatus(imc, TRUE);
1632 if (rc != TRUE)
1633 {
1634 win_skip("Unable to open IME\n");
1637 return;
1638 }
1639
1640 /* flush pending messages */
1641 while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageW(&msg);
1642
1644
1645 /* init input data that never changes */
1646 inputs[1].type = inputs[0].type = INPUT_KEYBOARD;
1647 inputs[1].u.ki.dwExtraInfo = inputs[0].u.ki.dwExtraInfo = 0;
1648 inputs[1].u.ki.time = inputs[0].u.ki.time = 0;
1649
1650 /* Pressing a key */
1651 inputs[0].u.ki.wVk = 0x41;
1652 inputs[0].u.ki.wScan = 0x1e;
1653 inputs[0].u.ki.dwFlags = 0x0;
1654
1655 pSendInput(1, (INPUT*)inputs, sizeof(INPUT));
1656
1657 while(PeekMessageW(&msg, hWndTest, 0, 0, PM_NOREMOVE)) {
1658 if(msg.message != WM_KEYDOWN)
1660 else
1661 {
1662 ok(msg.wParam != VK_PROCESSKEY,"Incorrect ProcessKey Found\n");
1664 if(msg.wParam == VK_PROCESSKEY)
1665 trace("ProcessKey was correctly found\n");
1666 }
1669 }
1670
1671 inputs[0].u.ki.wVk = 0x41;
1672 inputs[0].u.ki.wScan = 0x1e;
1673 inputs[0].u.ki.dwFlags = KEYEVENTF_KEYUP;
1674
1675 pSendInput(1, (INPUT*)inputs, sizeof(INPUT));
1676
1677 while(PeekMessageW(&msg, hWndTest, 0, 0, PM_NOREMOVE)) {
1678 if(msg.message != WM_KEYUP)
1680 else
1681 {
1682 ok(msg.wParam != VK_PROCESSKEY,"Incorrect ProcessKey Found\n");
1684 ok(msg.wParam != VK_PROCESSKEY,"ProcessKey should still not be Found\n");
1685 }
1688 }
1689
1691 ImmSetOpenStatus(imc, FALSE);
1693}
1694
1695static void test_InvalidIMC(void)
1696{
1697 HIMC imc_destroy;
1698 HIMC imc_null = 0x00000000;
1699 HIMC imc_bad = (HIMC)0xdeadcafe;
1700
1701 HIMC imc1, imc2, oldimc;
1702 DWORD ret;
1703 DWORD count;
1704 CHAR buffer[1000];
1705 INPUTCONTEXT *ic;
1706 LOGFONTA lf;
1707
1708 memset(&lf, 0, sizeof(lf));
1709
1710 imc_destroy = ImmCreateContext();
1711 ret = ImmDestroyContext(imc_destroy);
1712 ok(ret == TRUE, "Destroy an IMC should success!\n");
1713
1714 /* Test associating destroyed imc */
1715 imc1 = ImmGetContext(hwnd);
1716 SetLastError(0xdeadbeef);
1717 oldimc = ImmAssociateContext(hwnd, imc_destroy);
1718 ok(!oldimc, "Associating to a destroyed imc should fail!\n");
1719 ret = GetLastError();
1720 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1721 imc2 = ImmGetContext(hwnd);
1722 ok(imc1 == imc2, "imc should not changed! imc1 %p, imc2 %p\n", imc1, imc2);
1723
1724 /* Test associating NULL imc, which is different from an invalid imc */
1725 oldimc = ImmAssociateContext(hwnd, imc_null);
1726 ok(oldimc != NULL, "Associating to NULL imc should success!\n");
1727 imc2 = ImmGetContext(hwnd);
1728 ok(!imc2, "expect NULL, returned %p\n", imc2);
1729 oldimc = ImmAssociateContext(hwnd, imc1);
1730 ok(!oldimc, "expect NULL, returned %p\n", oldimc);
1731 imc2 = ImmGetContext(hwnd);
1732 ok(imc2 == imc1, "imc should not changed! imc2 %p, imc1 %p\n", imc2, imc1);
1733
1734 /* Test associating invalid imc */
1735 imc1 = ImmGetContext(hwnd);
1736 SetLastError(0xdeadbeef);
1737 oldimc = ImmAssociateContext(hwnd, imc_bad);
1738 ok(!oldimc, "Associating to a destroyed imc should fail!\n");
1739 ret = GetLastError();
1740 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1741 imc2 = ImmGetContext(hwnd);
1742 ok(imc1 == imc2, "imc should not changed! imc1 %p, imc2 %p\n", imc1, imc2);
1743
1744
1745 /* Test ImmGetCandidateListA */
1746 SetLastError(0xdeadbeef);
1747 ret = ImmGetCandidateListA(imc_bad, 0, NULL, 0);
1748 ok(ret == 0, "Bad IME should return 0\n");
1749 ret = GetLastError();
1750 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1751 SetLastError(0xdeadbeef);
1752 ret = ImmGetCandidateListA(imc_null, 0, NULL, 0);
1753 ok(ret == 0, "NULL IME should return 0\n");
1754 ret = GetLastError();
1755 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1756 SetLastError(0xdeadbeef);
1757 ret = ImmGetCandidateListA(imc_destroy, 0, NULL, 0);
1758 ok(ret == 0, "Destroyed IME should return 0\n");
1759 ret = GetLastError();
1760 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1761
1762 /* Test ImmGetCandidateListCountA*/
1763 SetLastError(0xdeadbeef);
1765 ok(ret == 0, "Bad IME should return 0\n");
1766 ret = GetLastError();
1767 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1768 SetLastError(0xdeadbeef);
1769 ret = ImmGetCandidateListCountA(imc_null,&count);
1770 ok(ret == 0, "NULL IME should return 0\n");
1771 ret = GetLastError();
1772 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1773 SetLastError(0xdeadbeef);
1774 ret = ImmGetCandidateListCountA(imc_destroy,&count);
1775 ok(ret == 0, "Destroyed IME should return 0\n");
1776 ret = GetLastError();
1777 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1778
1779 /* Test ImmGetCandidateWindow */
1780 SetLastError(0xdeadbeef);
1782 ok(ret == 0, "Bad IME should return 0\n");
1783 ret = GetLastError();
1784 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1785 SetLastError(0xdeadbeef);
1787 ok(ret == 0, "NULL IME should return 0\n");
1788 ret = GetLastError();
1789 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1790 SetLastError(0xdeadbeef);
1791 ret = ImmGetCandidateWindow(imc_destroy, 0, (LPCANDIDATEFORM)buffer);
1792 ok(ret == 0, "Destroyed IME should return 0\n");
1793 ret = GetLastError();
1794 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1795
1796 /* Test ImmGetCompositionFontA */
1797 SetLastError(0xdeadbeef);
1799 ok(ret == 0, "Bad IME should return 0\n");
1800 ret = GetLastError();
1801 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1802 SetLastError(0xdeadbeef);
1804 ok(ret == 0, "NULL IME should return 0\n");
1805 ret = GetLastError();
1806 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1807 SetLastError(0xdeadbeef);
1809 ok(ret == 0, "Destroyed IME should return 0\n");
1810 ret = GetLastError();
1811 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1812
1813 /* Test ImmGetCompositionWindow */
1814 SetLastError(0xdeadbeef);
1816 ok(ret == 0, "Bad IME should return 0\n");
1817 ret = GetLastError();
1818 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1819 SetLastError(0xdeadbeef);
1821 ok(ret == 0, "NULL IME should return 0\n");
1822 ret = GetLastError();
1823 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1824 SetLastError(0xdeadbeef);
1826 ok(ret == 0, "Destroyed IME should return 0\n");
1827 ret = GetLastError();
1828 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1829
1830 /* Test ImmGetCompositionStringA */
1831 SetLastError(0xdeadbeef);
1833 ok(ret == 0, "Bad IME should return 0\n");
1834 ret = GetLastError();
1835 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1836 SetLastError(0xdeadbeef);
1838 ok(ret == 0, "NULL IME should return 0\n");
1839 ret = GetLastError();
1840 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1841 SetLastError(0xdeadbeef);
1842 ret = ImmGetCompositionStringA(imc_destroy, GCS_COMPSTR, NULL, 0);
1843 ok(ret == 0, "Destroyed IME should return 0\n");
1844 ret = GetLastError();
1845 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1846
1847 /* Test ImmSetOpenStatus */
1848 SetLastError(0xdeadbeef);
1849 ret = ImmSetOpenStatus(imc_bad, 1);
1850 ok(ret == 0, "Bad IME should return 0\n");
1851 ret = GetLastError();
1852 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1853 SetLastError(0xdeadbeef);
1854 ret = ImmSetOpenStatus(imc_null, 1);
1855 ok(ret == 0, "NULL IME should return 0\n");
1856 ret = GetLastError();
1857 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1858 SetLastError(0xdeadbeef);
1859 ret = ImmSetOpenStatus(imc_destroy, 1);
1860 ok(ret == 0, "Destroyed IME should return 0\n");
1861 ret = GetLastError();
1862 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1863
1864 /* Test ImmGetOpenStatus */
1865 SetLastError(0xdeadbeef);
1866 ret = ImmGetOpenStatus(imc_bad);
1867 ok(ret == 0, "Bad IME should return 0\n");
1868 ret = GetLastError();
1869 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1870 SetLastError(0xdeadbeef);
1871 ret = ImmGetOpenStatus(imc_null);
1872 ok(ret == 0, "NULL IME should return 0\n");
1873 ret = GetLastError();
1874 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1875 SetLastError(0xdeadbeef);
1876 ret = ImmGetOpenStatus(imc_destroy);
1877 ok(ret == 0, "Destroyed IME should return 0\n");
1878 ret = GetLastError();
1879 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1880
1881 /* Test ImmGetStatusWindowPos */
1882 SetLastError(0xdeadbeef);
1883 ret = ImmGetStatusWindowPos(imc_bad, NULL);
1884 ok(ret == 0, "Bad IME should return 0\n");
1885 ret = GetLastError();
1886 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1887 SetLastError(0xdeadbeef);
1888 ret = ImmGetStatusWindowPos(imc_null, NULL);
1889 ok(ret == 0, "NULL IME should return 0\n");
1890 ret = GetLastError();
1891 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1892 SetLastError(0xdeadbeef);
1893 ret = ImmGetStatusWindowPos(imc_destroy, NULL);
1894 ok(ret == 0, "Destroyed IME should return 0\n");
1895 ret = GetLastError();
1896 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1897
1898 /* Test ImmRequestMessageA */
1899 SetLastError(0xdeadbeef);
1900 ret = ImmRequestMessageA(imc_bad, WM_CHAR, 0);
1901 ok(ret == 0, "Bad IME should return 0\n");
1902 ret = GetLastError();
1903 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1904 SetLastError(0xdeadbeef);
1905 ret = ImmRequestMessageA(imc_null, WM_CHAR, 0);
1906 ok(ret == 0, "NULL IME should return 0\n");
1907 ret = GetLastError();
1908 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1909 SetLastError(0xdeadbeef);
1910 ret = ImmRequestMessageA(imc_destroy, WM_CHAR, 0);
1911 ok(ret == 0, "Destroyed IME should return 0\n");
1912 ret = GetLastError();
1913 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1914
1915 /* Test ImmSetCompositionFontA */
1916 SetLastError(0xdeadbeef);
1917 ret = ImmSetCompositionFontA(imc_bad, &lf);
1918 ok(ret == 0, "Bad IME should return 0\n");
1919 ret = GetLastError();
1920 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1921 SetLastError(0xdeadbeef);
1922 ret = ImmSetCompositionFontA(imc_null, &lf);
1923 ok(ret == 0, "NULL IME should return 0\n");
1924 ret = GetLastError();
1925 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1926 SetLastError(0xdeadbeef);
1927 ret = ImmSetCompositionFontA(imc_destroy, &lf);
1928 ok(ret == 0, "Destroyed IME should return 0\n");
1929 ret = GetLastError();
1930 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1931
1932 /* Test ImmSetCompositionWindow */
1933 SetLastError(0xdeadbeef);
1934 ret = ImmSetCompositionWindow(imc_bad, NULL);
1935 ok(ret == 0, "Bad IME should return 0\n");
1936 ret = GetLastError();
1937 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1938 SetLastError(0xdeadbeef);
1939 ret = ImmSetCompositionWindow(imc_null, NULL);
1940 ok(ret == 0, "NULL IME should return 0\n");
1941 ret = GetLastError();
1942 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1943 SetLastError(0xdeadbeef);
1944 ret = ImmSetCompositionWindow(imc_destroy, NULL);
1945 ok(ret == 0, "Destroyed IME should return 0\n");
1946 ret = GetLastError();
1947 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1948
1949 /* Test ImmSetConversionStatus */
1950 SetLastError(0xdeadbeef);
1951 ret = ImmSetConversionStatus(imc_bad, 0, 0);
1952 ok(ret == 0, "Bad IME should return 0\n");
1953 ret = GetLastError();
1954 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1955 SetLastError(0xdeadbeef);
1956 ret = ImmSetConversionStatus(imc_null, 0, 0);
1957 ok(ret == 0, "NULL IME should return 0\n");
1958 ret = GetLastError();
1959 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1960 SetLastError(0xdeadbeef);
1961 ret = ImmSetConversionStatus(imc_destroy, 0, 0);
1962 ok(ret == 0, "Destroyed IME should return 0\n");
1963 ret = GetLastError();
1964 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1965
1966 /* Test ImmSetStatusWindowPos */
1967 SetLastError(0xdeadbeef);
1968 ret = ImmSetStatusWindowPos(imc_bad, 0);
1969 ok(ret == 0, "Bad IME should return 0\n");
1970 ret = GetLastError();
1971 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1972 SetLastError(0xdeadbeef);
1973 ret = ImmSetStatusWindowPos(imc_null, 0);
1974 ok(ret == 0, "NULL IME should return 0\n");
1975 ret = GetLastError();
1976 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1977 SetLastError(0xdeadbeef);
1978 ret = ImmSetStatusWindowPos(imc_destroy, 0);
1979 ok(ret == 0, "Destroyed IME should return 0\n");
1980 ret = GetLastError();
1981 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1982
1983 /* Test ImmGetImeMenuItemsA */
1984 SetLastError(0xdeadbeef);
1985 ret = ImmGetImeMenuItemsA(imc_bad, 0, 0, NULL, NULL, 0);
1986 ok(ret == 0, "Bad IME should return 0\n");
1987 ret = GetLastError();
1988 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1989 SetLastError(0xdeadbeef);
1990 ret = ImmGetImeMenuItemsA(imc_null, 0, 0, NULL, NULL, 0);
1991 ok(ret == 0, "NULL IME should return 0\n");
1992 ret = GetLastError();
1993 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1994 SetLastError(0xdeadbeef);
1995 ret = ImmGetImeMenuItemsA(imc_destroy, 0, 0, NULL, NULL, 0);
1996 ok(ret == 0, "Destroyed IME should return 0\n");
1997 ret = GetLastError();
1998 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1999
2000 /* Test ImmLockIMC */
2001 SetLastError(0xdeadbeef);
2002 ic = ImmLockIMC(imc_bad);
2003 ok(ic == 0, "Bad IME should return 0\n");
2004 ret = GetLastError();
2005 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2006 SetLastError(0xdeadbeef);
2007 ic = ImmLockIMC(imc_null);
2008 ok(ic == 0, "NULL IME should return 0\n");
2009 ret = GetLastError();
2010 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
2011 SetLastError(0xdeadbeef);
2012 ic = ImmLockIMC(imc_destroy);
2013 ok(ic == 0, "Destroyed IME should return 0\n");
2014 ret = GetLastError();
2015 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2016
2017 /* Test ImmUnlockIMC */
2018 SetLastError(0xdeadbeef);
2019 ret = ImmUnlockIMC(imc_bad);
2020 ok(ret == 0, "Bad IME should return 0\n");
2021 ret = GetLastError();
2022 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2023 SetLastError(0xdeadbeef);
2024 ret = ImmUnlockIMC(imc_null);
2025 ok(ret == 0, "NULL IME should return 0\n");
2026 ret = GetLastError();
2027 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
2028 SetLastError(0xdeadbeef);
2029 ret = ImmUnlockIMC(imc_destroy);
2030 ok(ret == 0, "Destroyed IME should return 0\n");
2031 ret = GetLastError();
2032 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2033
2034 /* Test ImmGenerateMessage */
2035 SetLastError(0xdeadbeef);
2036 ret = ImmGenerateMessage(imc_bad);
2037 ok(ret == 0, "Bad IME should return 0\n");
2038 ret = GetLastError();
2039 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2040 SetLastError(0xdeadbeef);
2041 ret = ImmGenerateMessage(imc_null);
2042 ok(ret == 0, "NULL IME should return 0\n");
2043 ret = GetLastError();
2044 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2045 SetLastError(0xdeadbeef);
2046 ret = ImmGenerateMessage(imc_destroy);
2047 ok(ret == 0, "Destroyed IME should return 0\n");
2048 ret = GetLastError();
2049 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2050}
2051
2053 if (init())
2054 {
2058 test_ImmIME();
2072 /* Reinitialize the hooks to capture all windows */
2076 if (pSendInput)
2078 else win_skip("SendInput is not available\n");
2079 }
2080 cleanup();
2081}
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
Arabic default style
Definition: afstyles.h:94
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define ARRAY_SIZE(A)
Definition: main.h:20
static HANDLE thread
Definition: service.c:33
DWORD WINAPI ImmGetCandidateListCountA(HIMC hIMC, LPDWORD lpdwListCount)
Definition: candidate.c:351
BOOL WINAPI ImmSetCandidateWindow(HIMC hIMC, LPCANDIDATEFORM lpCandidate)
Definition: candidate.c:410
BOOL WINAPI ImmGetCandidateWindow(HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate)
Definition: candidate.c:377
DWORD WINAPI ImmGetCandidateListA(HIMC hIMC, DWORD dwIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen)
Definition: candidate.c:343
HINSTANCE hInstance
Definition: charmap.c:19
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
LONG WINAPI ImmGetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
Definition: compstr.c:899
BOOL WINAPI ImmSetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD dwCompLen, LPVOID lpRead, DWORD dwReadLen)
Definition: compstr.c:943
LONG WINAPI ImmGetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
Definition: compstr.c:856
BOOL WINAPI ImmSetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD dwCompLen, LPVOID lpRead, DWORD dwReadLen)
Definition: compstr.c:955
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD HIMCC
Definition: dimm.idl:76
DWORD HIMC
Definition: dimm.idl:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
#define CloseHandle
Definition: compat.h:739
#define SetLastError(x)
Definition: compat.h:752
HANDLE HWND
Definition: compat.h:19
#define GetProcAddress(x, y)
Definition: compat.h:753
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CALLBACK
Definition: compat.h:35
BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
Definition: ime.c:1559
BOOL WINAPI ImmConfigureIMEA(HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
Definition: ime.c:2000
BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
Definition: ime.c:1615
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
Definition: ime.c:890
BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
Definition: ime.c:1688
UINT WINAPI ImmGetDescriptionA(HKL hKL, LPSTR lpszDescription, UINT uBufLen)
Definition: ime.c:1082
BOOL WINAPI ImmDisableIME(DWORD dwThreadId)
Definition: ime.c:1074
BOOL WINAPI ImmConfigureIMEW(HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
Definition: ime.c:2055
BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
Definition: ime.c:1443
BOOL WINAPI ImmSetConversionStatus(HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
Definition: ime.c:1941
BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
Definition: ime.c:1531
BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
Definition: ime.c:1509
UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
Definition: ime.c:1112
DWORD WINAPI ImmGetImeMenuItemsA(HIMC hIMC, DWORD dwFlags, DWORD dwType, LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu, DWORD dwSize)
Definition: ime.c:2111
BOOL WINAPI ImmNotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD_PTR dwValue)
Definition: ime.c:907
DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
Definition: ime.c:1221
BOOL WINAPI ImmGetConversionStatus(HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
Definition: ime.c:1912
BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
Definition: ime.c:1466
BOOL WINAPI ImmSetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
Definition: ime.c:1583
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
Definition: imm.c:1067
HIMC WINAPI ImmCreateContext(void)
Definition: imm.c:591
HIMC WINAPI ImmGetContext(HWND hWnd)
Definition: imm.c:1045
BOOL WINAPI ImmDestroyContext(HIMC hIMC)
Definition: imm.c:916
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
Definition: imm.c:1086
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
Definition: imm.c:1058
HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
Definition: imm.c:492
BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
Definition: utils.c:1208
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
Definition: utils.c:1246
DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
Definition: utils.c:1218
HIMCC WINAPI ImmCreateIMCC(DWORD size)
Definition: utils.c:1178
DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
Definition: utils.c:1236
HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
Definition: utils.c:1226
LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
Definition: utils.c:1198
HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
Definition: utils.c:1188
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
#define pt(x, y)
Definition: drawing.c:79
r parent
Definition: btrfs.c:3010
#define INFINITE
Definition: serial.h:102
DWORD dwThreadId
Definition: fdebug.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLint left
Definition: glext.h:7726
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
HGLOBAL NTAPI GlobalHandle(LPCVOID pMem)
Definition: heapmem.c:705
UINT NTAPI GlobalFlags(HGLOBAL hMem)
Definition: heapmem.c:520
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
static void test_ImmGetContext(void)
Definition: imm32.c:980
static void msg_spy_cleanup(void)
Definition: imm32.c:166
static void test_ImmIsUIMessage(void)
Definition: imm32.c:909
static LRESULT CALLBACK call_wnd_proc_filter(int nCode, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:94
static void test_InvalidIMC(void)
Definition: imm32.c:1695
BOOL catch_result_str
Definition: imm32.c:368
static HWND get_ime_window(void)
Definition: imm32.c:1135
static void test_ImmNotifyIME(void)
Definition: imm32.c:301
static void test_ImmDestroyIMCC(void)
Definition: imm32.c:1456
struct _tagTRANSMSG * LPTRANSMSG
static DWORD WINAPI test_ImmGetDefaultIMEWnd_thread(void *arg)
Definition: imm32.c:1059
static void test_ImmAssociateContextEx(void)
Definition: imm32.c:639
static DWORD WINAPI test_default_ime_with_message_only_window_cb(void *arg)
Definition: imm32.c:1242
static HWND thread_ime_wnd
Definition: imm32.c:1058
static void msg_spy_pump_msg_queue(void)
Definition: imm32.c:112
DWORD timer_id
Definition: imm32.c:371
static void msg_spy_init(HWND hwnd)
Definition: imm32.c:153
static LRESULT WINAPI imm_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: imm32.c:1052
static LRESULT CALLBACK processkey_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:1579
static LPARAM
Definition: imm32.c:34
struct _tagTRANSMSG TRANSMSG
static imm_msgs * msg_spy_find_msg(UINT message)
Definition: imm32.c:147
static void test_ImmThreads(void)
Definition: imm32.c:738
WNDPROC old_wnd_proc
Definition: imm32.c:367
static void test_ImmGetDescription(void)
Definition: imm32.c:996
static BOOL init(void)
Definition: imm32.c:245
static void cleanup(void)
Definition: imm32.c:294
static DWORD WINAPI test_default_ime_window_cb(void *arg)
Definition: imm32.c:1147
static INPUT size_t
Definition: imm32.c:35
static void test_ImmGetIMCCLockCount(void)
Definition: imm32.c:1382
@ CREATE_CANCEL
Definition: imm32.c:180
@ SECOND_WINDOW
Definition: imm32.c:179
@ FIRST_WINDOW
Definition: imm32.c:179
@ NCCREATE_CANCEL
Definition: imm32.c:180
@ PHASE_UNKNOWN
Definition: imm32.c:179
@ IME_DISABLED
Definition: imm32.c:180
static DWORD WINAPI test_default_ime_disabled_cb(void *arg)
Definition: imm32.c:1225
static void test_ImmIME(void)
Definition: imm32.c:615
static WPARAM
Definition: imm32.c:34
static void test_ImmMessages(void)
Definition: imm32.c:1488
static BOOL CALLBACK is_ime_window_proc(HWND hWnd, LPARAM param)
Definition: imm32.c:1122
static DWORD WINAPI ImmGetContextThreadFunc(LPVOID lpParam)
Definition: imm32.c:686
static LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:185
static DWORD
Definition: imm32.c:33
static void test_ImmDefaultHwnd(void)
Definition: imm32.c:1069
static imm_msgs * msg_spy_find_next_msg(UINT message, UINT *start)
Definition: imm32.c:128
static HWND hwnd
Definition: imm32.c:181
static LRESULT CALLBACK get_msg_filter(int nCode, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:74
static struct @1671 ime_composition_test
static enum @1670 test_phase
struct _igc_threadinfo igc_threadinfo
static void test_ImmGetCompositionString(void)
Definition: imm32.c:432
static void test_ImmDestroyContext(void)
Definition: imm32.c:1428
DWORD start
Definition: imm32.c:370
static void test_ime_processkey(void)
Definition: imm32.c:1585
static HIMC
Definition: imm32.c:33
static void test_default_ime_window_creation(void)
Definition: imm32.c:1277
static const char wndcls[]
Definition: imm32.c:178
static struct _msg_spy msg_spy
static void test_ImmSetCompositionString(void)
Definition: imm32.c:580
static DWORD WINAPI test_default_ime_window_cancel_cb(void *arg)
Definition: imm32.c:1187
struct _msgs imm_msgs
static void msg_spy_flush_msgs(void)
Definition: imm32.c:123
static LRESULT WINAPI test_ime_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:374
BOOL catch_ime_char
Definition: imm32.c:369
static void test_ImmGetIMCLockCount(void)
Definition: imm32.c:1324
static UINT
Definition: imm32.c:34
#define CPS_CANCEL
Definition: imm.h:181
#define SCS_CHANGECLAUSE
Definition: imm.h:310
#define SCS_CAP_COMPSTR
Definition: imm.h:259
#define GCS_COMPATTR
Definition: imm.h:228
#define IME_CONFIG_REGISTERWORD
Definition: imm.h:406
#define GCS_RESULTSTR
Definition: imm.h:234
#define CFS_CANDIDATEPOS
Definition: imm.h:327
#define CPS_COMPLETE
Definition: imm.h:178
#define IGP_SETCOMPSTR
Definition: imm.h:304
#define SCS_SETSTR
Definition: imm.h:308
#define IMC_GETCANDIDATEPOS
Definition: imm.h:148
#define GCS_COMPSTR
Definition: imm.h:227
#define SCS_CHANGEATTR
Definition: imm.h:309
#define NI_COMPOSITIONSTR
Definition: immdev.h:403
#define stdout
Definition: stdio.h:99
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
Definition: keymsg.c:840
LRESULT WINAPI ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam)
Definition: keymsg.c:1114
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static struct test_info tests[]
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
#define todo_wine
Definition: custom.c:89
static HWND hWndTest
Definition: input.c:63
HKL hkl
Definition: msctf.idl:650
UINT_PTR HKL
Definition: msctf.idl:143
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
#define BOOL
Definition: nt_native.h:43
#define LRESULT
Definition: ole.h:14
#define WS_CHILD
Definition: pedump.c:617
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define WS_POPUP
Definition: pedump.c:616
#define WS_VISIBLE
Definition: pedump.c:620
long LONG
Definition: pedump.c:60
#define WS_DISABLED
Definition: pedump.c:621
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
static char title[]
Definition: ps.c:92
#define err(...)
#define test
Definition: rosglue.h:37
#define win_skip
Definition: test.h:163
int winetest_interactive
#define memset(x, y, z)
Definition: compat.h:39
HWND hwndMain
Definition: solitaire.cpp:13
DWORD dwIndex
Definition: dimm.idl:79
DWORD dwStyle
Definition: dimm.idl:80
POINT ptCurrentPos
Definition: dimm.idl:81
MOUSEINPUT mi
Definition: imm32.c:58
DWORD type
Definition: imm32.c:55
HARDWAREINPUT hi
Definition: imm32.c:60
union TEST_INPUT::@1672 u
KEYBDINPUT ki
Definition: imm32.c:59
int cbClsExtra
Definition: winuser.h:3207
HINSTANCE hInstance
Definition: winuser.h:3209
HCURSOR hCursor
Definition: winuser.h:3211
LPCSTR lpszMenuName
Definition: winuser.h:3213
HICON hIconSm
Definition: winuser.h:3215
UINT style
Definition: winuser.h:3205
int cbWndExtra
Definition: winuser.h:3208
UINT cbSize
Definition: winuser.h:3204
WNDPROC lpfnWndProc
Definition: winuser.h:3206
LPCSTR lpszClassName
Definition: winuser.h:3214
HICON hIcon
Definition: winuser.h:3210
HBRUSH hbrBackground
Definition: winuser.h:3212
LPCWSTR lpszClassName
Definition: winuser.h:3188
LPCWSTR lpszMenuName
Definition: winuser.h:3187
HBRUSH hbrBackground
Definition: winuser.h:3186
HICON hIcon
Definition: winuser.h:3184
HINSTANCE hInstance
Definition: winuser.h:3183
int cbClsExtra
Definition: winuser.h:3181
UINT style
Definition: winuser.h:3179
WNDPROC lpfnWndProc
Definition: winuser.h:3180
int cbWndExtra
Definition: winuser.h:3182
HCURSOR hCursor
Definition: winuser.h:3185
HIMC u_himc
Definition: imm32.c:682
HANDLE event
Definition: imm32.c:680
Definition: imm32.c:45
unsigned int i_msg
Definition: imm32.c:50
HWND hwnd
Definition: imm32.c:46
imm_msgs msgs[64]
Definition: imm32.c:49
HHOOK call_wnd_proc_hook
Definition: imm32.c:48
HHOOK get_msg_hook
Definition: imm32.c:47
Definition: imm32.c:40
CWPSTRUCT msg
Definition: imm32.c:41
BOOL post
Definition: imm32.c:42
HIMCC hMsgBuf
Definition: immdev.h:146
DWORD dwNumMsgBuf
Definition: immdev.h:145
LPARAM lParam
Definition: imm32.c:68
WPARAM wParam
Definition: imm32.c:67
UINT message
Definition: imm32.c:66
Definition: tftpd.h:60
Definition: ps.c:97
DWORD dwFlags
Definition: winable.h:49
WORD wVk
Definition: winable.h:47
WORD wScan
Definition: winable.h:48
ULONG_PTR dwExtraInfo
Definition: winable.h:51
DWORD time
Definition: winable.h:50
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
BOOL top_level_window
Definition: imm32.c:1144
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define GWLP_WNDPROC
Definition: treelist.c:66
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT
Definition: typedefs.h:58
UINT WM_MSIME_RECONVERTREQUEST
Definition: ui.cpp:16
UINT WM_MSIME_DOCUMENTFEED
Definition: ui.cpp:18
UINT WM_MSIME_RECONVERT
Definition: ui.cpp:17
UINT WM_MSIME_SERVICE
Definition: ui.cpp:14
UINT WM_MSIME_MOUSE
Definition: ui.cpp:22
UINT WM_MSIME_QUERYPOSITION
Definition: ui.cpp:19
int ret
int WINAPI GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
Definition: window.c:1302
#define INPUT_KEYBOARD
Definition: winable.h:10
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GMEM_LOCKCOUNT
Definition: winbase.h:335
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define WAIT_OBJECT_0
Definition: winbase.h:432
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_WINDOW_HANDLE
Definition: winerror.h:881
#define SW_SHOWNORMAL
Definition: winuser.h:773
#define HWND_MESSAGE
Definition: winuser.h:1213
#define CS_VREDRAW
Definition: winuser.h:658
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define SetWindowLongPtrA
Definition: winuser.h:5357
#define WM_IME_KEYUP
Definition: winuser.h:1842
BOOL WINAPI IsWindow(_In_opt_ HWND)
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define WM_IME_REQUEST
Definition: winuser.h:1839
#define WM_CLOSE
Definition: winuser.h:1624
UINT WINAPI RegisterWindowMessageA(_In_ LPCSTR)
BOOL WINAPI SetWindowTextA(_In_ HWND, _In_opt_ LPCSTR)
BOOL WINAPI UnloadKeyboardLayout(_In_ HKL)
#define WM_QUIT
Definition: winuser.h:1626
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define WM_KEYUP
Definition: winuser.h:1719
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define COLOR_WINDOW
Definition: winuser.h:921
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
#define HWND_TOPMOST
Definition: winuser.h:1211
#define WM_IME_NOTIFY
Definition: winuser.h:1833
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define WM_IME_KEYDOWN
Definition: winuser.h:1841
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4318
#define WM_CREATE
Definition: winuser.h:1611
HHOOK WINAPI SetWindowsHookExW(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
HWND WINAPI SetParent(_In_ HWND, _In_opt_ HWND)
#define SWP_NOMOVE
Definition: winuser.h:1247
#define CS_HREDRAW
Definition: winuser.h:653
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define IDC_ARROW
Definition: winuser.h:687
#define HC_ACTION
Definition: winuser.h:48
#define VK_PROCESSKEY
Definition: winuser.h:2330
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define QS_ALLINPUT
Definition: winuser.h:906
#define SWP_NOSIZE
Definition: winuser.h:1248
#define WM_MOUSEMOVE
Definition: winuser.h:1778
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2157
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
int WINAPIV wsprintfA(_Out_ LPSTR, _In_ _Printf_format_string_ LPCSTR,...)
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define WM_NCCREATE
Definition: winuser.h:1686
#define IDI_APPLICATION
Definition: winuser.h:704
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
#define WM_IME_SETCONTEXT
Definition: winuser.h:1832
#define WM_IME_CHAR
Definition: winuser.h:1837
ATOM WINAPI RegisterClassExA(_In_ CONST WNDCLASSEXA *)
HWND WINAPI SetFocus(_In_opt_ HWND)
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define WM_TIMER
Definition: winuser.h:1745
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2112
#define PM_REMOVE
Definition: winuser.h:1199
BOOL WINAPI UpdateWindow(_In_ HWND)
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4319
#define WM_IME_COMPOSITIONFULL
Definition: winuser.h:1835
#define WM_CHAR
Definition: winuser.h:1720
#define CW_USEDEFAULT
Definition: winuser.h:225
#define WH_GETMESSAGE
Definition: winuser.h:33
HWND WINAPI GetParent(_In_ HWND)
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
int WINAPI GetClassNameW(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPWSTR lpClassName, _In_ int nMaxCount)
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define WM_IME_CONTROL
Definition: winuser.h:1834
struct _WNDCLASSEXA WNDCLASSEXA
#define SW_SHOW
Definition: winuser.h:778
#define WM_IME_SELECT
Definition: winuser.h:1836
#define WM_DESTROY
Definition: winuser.h:1612
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define WM_KEYDOWN
Definition: winuser.h:1718
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2909
BOOL WINAPI PostThreadMessageA(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI EnumThreadWindows(_In_ DWORD, _In_ WNDENUMPROC, _In_ LPARAM)
#define SetWindowLongPtrW
Definition: winuser.h:5358
#define WM_NCCALCSIZE
Definition: winuser.h:1688
#define GWL_STYLE
Definition: winuser.h:855
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI DestroyWindow(_In_ HWND)
#define PM_NOREMOVE
Definition: winuser.h:1198
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2127
#define KEYEVENTF_KEYUP
Definition: winuser.h:1105
LRESULT WINAPI CallWindowProcA(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2142
#define WH_CALLWNDPROC
Definition: winuser.h:34
#define GWL_EXSTYLE
Definition: winuser.h:854
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175