ReactOS 0.4.15-dev-6656-gbbb33a6
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
64typedef struct _tagTRANSMSG {
69
70static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t);
71
73{
74 if (HC_ACTION == nCode) {
75 MSG *msg = (MSG*)lParam;
76
77 if ((msg->hwnd == msg_spy.hwnd || msg_spy.hwnd == NULL) &&
78 (msg_spy.i_msg < ARRAY_SIZE(msg_spy.msgs)))
79 {
80 msg_spy.msgs[msg_spy.i_msg].msg.hwnd = msg->hwnd;
81 msg_spy.msgs[msg_spy.i_msg].msg.message = msg->message;
82 msg_spy.msgs[msg_spy.i_msg].msg.wParam = msg->wParam;
83 msg_spy.msgs[msg_spy.i_msg].msg.lParam = msg->lParam;
84 msg_spy.msgs[msg_spy.i_msg].post = TRUE;
85 msg_spy.i_msg++;
86 }
87 }
88
89 return CallNextHookEx(msg_spy.get_msg_hook, nCode, wParam, lParam);
90}
91
94{
95 if (HC_ACTION == nCode) {
96 CWPSTRUCT *cwp = (CWPSTRUCT*)lParam;
97
98 if (((cwp->hwnd == msg_spy.hwnd || msg_spy.hwnd == NULL)) &&
99 (msg_spy.i_msg < ARRAY_SIZE(msg_spy.msgs)))
100 {
101 memcpy(&msg_spy.msgs[msg_spy.i_msg].msg, cwp, sizeof(msg_spy.msgs[0].msg));
102 msg_spy.msgs[msg_spy.i_msg].post = FALSE;
103 msg_spy.i_msg++;
104 }
105 }
106
107 return CallNextHookEx(msg_spy.call_wnd_proc_hook, nCode, wParam, lParam);
108}
109
110static void msg_spy_pump_msg_queue(void) {
111 MSG msg;
112
113 while(PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
116 }
117
118 return;
119}
120
121static void msg_spy_flush_msgs(void) {
123 msg_spy.i_msg = 0;
124}
125
127 UINT i;
128
130
131 if (msg_spy.i_msg >= ARRAY_SIZE(msg_spy.msgs))
132 fprintf(stdout, "%s:%d: msg_spy: message buffer overflow!\n",
133 __FILE__, __LINE__);
134
135 for (i = *start; i < msg_spy.i_msg; i++)
136 if (msg_spy.msgs[i].msg.message == message)
137 {
138 *start = i+1;
139 return &msg_spy.msgs[i];
140 }
141
142 return NULL;
143}
144
146 UINT i = 0;
147
149}
150
151static void msg_spy_init(HWND hwnd) {
152 msg_spy.hwnd = hwnd;
153 msg_spy.get_msg_hook =
156 msg_spy.call_wnd_proc_hook =
159 msg_spy.i_msg = 0;
160
162}
163
164static void msg_spy_cleanup(void) {
165 if (msg_spy.get_msg_hook)
166 UnhookWindowsHookEx(msg_spy.get_msg_hook);
167 if (msg_spy.call_wnd_proc_hook)
168 UnhookWindowsHookEx(msg_spy.call_wnd_proc_hook);
169 memset(&msg_spy, 0, sizeof(msg_spy));
170}
171
172/*
173 * imm32 test cases - Issue some IMM commands on a dummy window and analyse the
174 * messages being sent to this window in response.
175 */
176static const char wndcls[] = "winetest_imm32_wndcls";
179static HWND hwnd;
180
181static HWND get_ime_window(void);
182
184{
185 HWND default_ime_wnd;
186 switch (msg)
187 {
189 return TRUE;
190 case WM_NCCREATE:
191 default_ime_wnd = get_ime_window();
192 switch(test_phase) {
193 case FIRST_WINDOW:
194 case IME_DISABLED:
195 ok(!default_ime_wnd, "expected no IME windows\n");
196 break;
197 case SECOND_WINDOW:
198 ok(default_ime_wnd != NULL, "expected IME window existence\n");
199 break;
200 default:
201 break; /* do nothing */
202 }
204 return FALSE;
205 return TRUE;
206 case WM_NCCALCSIZE:
207 default_ime_wnd = get_ime_window();
208 switch(test_phase) {
209 case FIRST_WINDOW:
210 case SECOND_WINDOW:
211 case CREATE_CANCEL:
212 ok(default_ime_wnd != NULL, "expected IME window existence\n");
213 break;
214 case IME_DISABLED:
215 ok(!default_ime_wnd, "expected no IME windows\n");
216 break;
217 default:
218 break; /* do nothing */
219 }
220 break;
221 case WM_CREATE:
222 default_ime_wnd = get_ime_window();
223 switch(test_phase) {
224 case FIRST_WINDOW:
225 case SECOND_WINDOW:
226 case CREATE_CANCEL:
227 ok(default_ime_wnd != NULL, "expected IME window existence\n");
228 break;
229 case IME_DISABLED:
230 ok(!default_ime_wnd, "expected no IME windows\n");
231 break;
232 default:
233 break; /* do nothing */
234 }
236 return -1;
237 return TRUE;
238 }
239
241}
242
243static BOOL init(void) {
244 WNDCLASSEXA wc;
245 HIMC imc;
246 HMODULE hmod,huser;
247
248 hmod = GetModuleHandleA("imm32.dll");
249 huser = GetModuleHandleA("user32");
250 pImmAssociateContextEx = (void*)GetProcAddress(hmod, "ImmAssociateContextEx");
251 pImmIsUIMessageA = (void*)GetProcAddress(hmod, "ImmIsUIMessageA");
252 pSendInput = (void*)GetProcAddress(huser, "SendInput");
253
254 wc.cbSize = sizeof(WNDCLASSEXA);
255 wc.style = 0;
256 wc.lpfnWndProc = wndProc;
257 wc.cbClsExtra = 0;
258 wc.cbWndExtra = 0;
262 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
263 wc.lpszMenuName = NULL;
266
267 if (!RegisterClassExA(&wc))
268 return FALSE;
269
270 hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
272 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
273 if (!hwnd)
274 return FALSE;
275
276 imc = ImmGetContext(hwnd);
277 if (!imc)
278 {
279 win_skip("IME support not implemented\n");
280 return FALSE;
281 }
283
286
288
289 return TRUE;
290}
291
292static void cleanup(void) {
294 if (hwnd)
297}
298
299static void test_ImmNotifyIME(void) {
300#ifdef __REACTOS__
301 static char string[] = "wine";
302#else
303 static const char string[] = "wine";
304#endif
305 char resstr[16] = "";
306 HIMC imc;
307 BOOL ret;
308
309 imc = ImmGetContext(hwnd);
311
313 ok(broken(!ret) ||
314 ret, /* Vista+ */
315 "Canceling an empty composition string should succeed.\n");
316 ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post "
317 "WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if "
318 "the composition string being canceled is empty.\n");
319
320 ImmSetCompositionStringA(imc, SCS_SETSTR, string, sizeof(string), NULL, 0);
322
325
326 /* behavior differs between win9x and NT */
327 ret = ImmGetCompositionStringA(imc, GCS_COMPSTR, resstr, sizeof(resstr));
328 ok(!ret, "After being cancelled the composition string is empty.\n");
329
331
333 ok(broken(!ret) ||
334 ret, /* Vista+ */
335 "Canceling an empty composition string should succeed.\n");
336 ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post "
337 "WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if "
338 "the composition string being canceled is empty.\n");
339
342
343 imc = ImmCreateContext();
345
346 SetLastError(0xdeadbeef);
348 ok (ret == 0, "Bad IME should return 0\n");
349 ret = GetLastError();
350 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
351 SetLastError(0xdeadbeef);
352 ret = ImmNotifyIME(0x00000000, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
353 ok (ret == 0, "NULL IME should return 0\n");
354 ret = GetLastError();
355 ok(ret == ERROR_SUCCESS, "wrong last error %08x!\n", ret);
356 SetLastError(0xdeadbeef);
358 ok (ret == 0, "Destroyed IME should return 0\n");
359 ret = GetLastError();
360 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
361
362}
363
364static struct {
371
373{
374 switch (msg)
375 {
376 case WM_IME_COMPOSITION:
377 if ((lParam & GCS_RESULTSTR) && !ime_composition_test.catch_result_str) {
378 HWND hwndIme;
379 WCHAR wstring[20];
380 HIMC imc;
381 LONG size;
382 LRESULT ret;
383
384 hwndIme = ImmGetDefaultIMEWnd(hWnd);
385 ok(hwndIme != NULL, "expected IME window existence\n");
386
387 ok(!ime_composition_test.catch_ime_char, "WM_IME_CHAR is sent\n");
389 hWnd, msg, wParam, lParam);
390 ok(ime_composition_test.catch_ime_char, "WM_IME_CHAR isn't sent\n");
391
392 ime_composition_test.catch_ime_char = FALSE;
393 SendMessageA(hwndIme, msg, wParam, lParam);
394 ok(!ime_composition_test.catch_ime_char, "WM_IME_CHAR is sent\n");
395
396 imc = ImmGetContext(hWnd);
398 wstring, sizeof(wstring));
399 ok(size > 0, "ImmGetCompositionString(GCS_RESULTSTR) is %d\n", size);
401
402 ime_composition_test.catch_result_str = TRUE;
403 return ret;
404 }
405 break;
406 case WM_IME_CHAR:
407 if (!ime_composition_test.catch_result_str)
408 ime_composition_test.catch_ime_char = TRUE;
409 break;
410 case WM_TIMER:
411 if (wParam == ime_composition_test.timer_id) {
413 char title[64];
414 int left = 20 - (GetTickCount() - ime_composition_test.start) / 1000;
415 wsprintfA(title, "%sLeft %d sec. - IME composition test",
416 ime_composition_test.catch_result_str ? "[*] " : "", left);
418 if (left <= 0)
420 else
421 SetTimer(hWnd, wParam, 100, NULL);
422 return TRUE;
423 }
424 break;
425 }
426 return CallWindowProcA(ime_composition_test.old_wnd_proc,
427 hWnd, msg, wParam, lParam);
428}
429
431{
432 HIMC imc;
433#ifdef __REACTOS__
434 static WCHAR string[] = {'w','i','n','e',0x65e5,0x672c,0x8a9e};
435#else
436 static const WCHAR string[] = {'w','i','n','e',0x65e5,0x672c,0x8a9e};
437#endif
438 char cstring[20];
439 WCHAR wstring[20];
440 LONG len;
441 LONG alen,wlen;
442 BOOL ret;
443 DWORD prop;
444
445 imc = ImmGetContext(hwnd);
446 ret = ImmSetCompositionStringW(imc, SCS_SETSTR, string, sizeof(string), NULL,0);
447 if (!ret) {
448 win_skip("Composition isn't supported\n");
450 return;
451 }
453
454 alen = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, 20);
455 wlen = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, 20);
456 /* windows machines without any IME installed just return 0 above */
457 if( alen && wlen)
458 {
460 ok(len*sizeof(WCHAR)==wlen,"GCS_COMPATTR(W) not returning correct count\n");
462 ok(len==alen,"GCS_COMPATTR(A) not returning correct count\n");
463
464 /* Get strings with exactly matching buffer sizes. */
465 memset(wstring, 0x1a, sizeof(wstring));
466 memset(cstring, 0x1a, sizeof(cstring));
467
468 len = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, alen);
469 ok(len == alen, "Unexpected length %d.\n", len);
470 ok(cstring[alen] == 0x1a, "Unexpected buffer contents.\n");
471
472 len = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, wlen);
473 ok(len == wlen, "Unexpected length %d.\n", len);
474 ok(wstring[wlen/sizeof(WCHAR)] == 0x1a1a, "Unexpected buffer contents.\n");
475
476 /* Get strings with exactly smaller buffer sizes. */
477 memset(wstring, 0x1a, sizeof(wstring));
478 memset(cstring, 0x1a, sizeof(cstring));
479
480 /* Returns 0 but still fills buffer. */
481 len = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, alen - 1);
482 ok(!len, "Unexpected length %d.\n", len);
483 ok(cstring[0] == 'w', "Unexpected buffer contents %s.\n", cstring);
484
485 len = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, wlen - 1);
486 ok(len == wlen - 1, "Unexpected length %d.\n", len);
487 ok(!memcmp(wstring, string, wlen - 1), "Unexpected buffer contents.\n");
488
489 /* Get the size of the required output buffer. */
490 memset(wstring, 0x1a, sizeof(wstring));
491 memset(cstring, 0x1a, sizeof(cstring));
492
493 len = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, 0);
494 ok(len == alen, "Unexpected length %d.\n", len);
495 ok(cstring[0] == 0x1a, "Unexpected buffer contents %s.\n", cstring);
496
497 len = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, 0);
498 ok(len == wlen, "Unexpected length %d.\n", len);
499 ok(wstring[0] == 0x1a1a, "Unexpected buffer contents.\n");
500 }
501 else
502 win_skip("Composition string isn't available\n");
503
505
506 /* Test composition results input by IMM API */
508 if (!(prop & SCS_CAP_COMPSTR)) {
509 /* Wine's IME doesn't support SCS_SETSTR in ImmSetCompositionString */
510 skip("This IME doesn't support SCS_SETSTR\n");
511 }
512 else {
513 ime_composition_test.old_wnd_proc =
516 imc = ImmGetContext(hwnd);
518
520 string, sizeof(string), NULL,0);
521 ok(ret, "ImmSetCompositionStringW failed\n");
523 wstring, sizeof(wstring));
524 if (wlen > 0) {
526 ok(ret, "ImmNotifyIME(CPS_COMPLETE) failed\n");
528 ok(ime_composition_test.catch_result_str,
529 "WM_IME_COMPOSITION(GCS_RESULTSTR) isn't sent\n");
530 }
531 else
532 win_skip("Composition string isn't available\n");
535 (LONG_PTR)ime_composition_test.old_wnd_proc);
537 }
538
539 /* Test composition results input by hand */
542 HWND hwndMain, hwndChild;
543 MSG msg;
544 const DWORD MY_TIMER = 0xcaffe;
545
547 "IME composition test",
549 CW_USEDEFAULT, CW_USEDEFAULT, 320, 160,
551 hwndChild = CreateWindowExA(0, "static",
552 "Input a DBCS character here using IME.",
554 0, 0, 320, 100, hwndMain, NULL,
556
557 ime_composition_test.old_wnd_proc =
560
561 SetFocus(hwndChild);
562
563 ime_composition_test.timer_id = MY_TIMER;
565 SetTimer(hwndChild, ime_composition_test.timer_id, 100, NULL);
566 while (GetMessageA(&msg, NULL, 0, 0)) {
569 if (!IsWindow(hwndMain))
570 break;
571 }
572 if (!ime_composition_test.catch_result_str)
573 skip("WM_IME_COMPOSITION(GCS_RESULTSTR) isn't tested\n");
575 }
576}
577
579{
580 HIMC imc;
581 BOOL ret;
582
583 SetLastError(0xdeadbeef);
584 imc = ImmGetContext(hwnd);
585 ok(imc != 0, "ImmGetContext() failed. Last error: %u\n", GetLastError());
586 if (!imc)
587 return;
588
590 ok(broken(!ret) ||
591 ret, /* Vista+ */
592 "ImmSetCompositionStringW() failed.\n");
593
595 NULL, 0, NULL, 0);
596 ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
597
599 NULL, 0, NULL, 0);
600 ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
601
603 NULL, 0, NULL, 0);
604 ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
605
607 NULL, 0, NULL, 0);
608 ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
609
611}
612
613static void test_ImmIME(void)
614{
615 HIMC imc;
616
617 imc = ImmGetContext(hwnd);
618 if (imc)
619 {
620 BOOL rc;
621#ifdef __REACTOS__
623#else
625#endif
626 ok (rc == 0, "ImmConfigureIMEA did not fail\n");
627#ifdef __REACTOS__
629#else
631#endif
632 ok (rc == 0, "ImmConfigureIMEW did not fail\n");
633 }
635}
636
638{
639 HIMC imc;
640 BOOL rc;
641
642 if (!pImmAssociateContextEx) return;
643
644 imc = ImmGetContext(hwnd);
645 if (imc)
646 {
647 HIMC retimc, newimc;
648
649 newimc = ImmCreateContext();
650 ok(newimc != imc, "handles should not be the same\n");
651 rc = pImmAssociateContextEx(NULL, NULL, 0);
652 ok(!rc, "ImmAssociateContextEx succeeded\n");
653 rc = pImmAssociateContextEx(hwnd, NULL, 0);
654 ok(rc, "ImmAssociateContextEx failed\n");
655 rc = pImmAssociateContextEx(NULL, imc, 0);
656 ok(!rc, "ImmAssociateContextEx succeeded\n");
657
658 rc = pImmAssociateContextEx(hwnd, imc, 0);
659 ok(rc, "ImmAssociateContextEx failed\n");
660 retimc = ImmGetContext(hwnd);
661 ok(retimc == imc, "handles should be the same\n");
662 ImmReleaseContext(hwnd,retimc);
663
664 rc = pImmAssociateContextEx(hwnd, newimc, 0);
665 ok(rc, "ImmAssociateContextEx failed\n");
666 retimc = ImmGetContext(hwnd);
667 ok(retimc == newimc, "handles should be the same\n");
668 ImmReleaseContext(hwnd,retimc);
669
670 rc = pImmAssociateContextEx(hwnd, NULL, IACE_DEFAULT);
671 ok(rc, "ImmAssociateContextEx failed\n");
672 }
674}
675
676typedef struct _igc_threadinfo {
682
683
685{
686 HIMC h1,h2;
687 HWND hwnd2;
689 CANDIDATEFORM cdf;
690 POINT pt;
691 MSG msg;
692
694 info->hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
696 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
697
698 h1 = ImmGetContext(hwnd);
699 ok(info->himc == h1, "hwnd context changed in new thread\n");
700 h2 = ImmGetContext(info->hwnd);
701 ok(h2 != h1, "new hwnd in new thread should have different context\n");
702 info->himc = h2;
704
705 hwnd2 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
707 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
708 h1 = ImmGetContext(hwnd2);
709
710 ok(h1 == h2, "Windows in same thread should have same default context\n");
711 ImmReleaseContext(hwnd2,h1);
712 ImmReleaseContext(info->hwnd,h2);
713 DestroyWindow(hwnd2);
714
715 /* priming for later tests */
718 info->u_himc = ImmCreateContext();
719 ImmSetOpenStatus(info->u_himc, TRUE);
720 cdf.dwIndex = 0;
722 cdf.ptCurrentPos.x = 0;
723 cdf.ptCurrentPos.y = 0;
724 ImmSetCandidateWindow(info->u_himc, &cdf);
725
726 SetEvent(info->event);
727
728 while(GetMessageW(&msg, 0, 0, 0))
729 {
732 }
733 return 1;
734}
735
736static void test_ImmThreads(void)
737{
738 HIMC himc, otherHimc, h1;
739 igc_threadinfo threadinfo;
742 BOOL rc;
743 LOGFONTA lf;
745 CANDIDATEFORM cdf;
746 DWORD status, sentence;
747 POINT pt;
748
749 himc = ImmGetContext(hwnd);
750 threadinfo.event = CreateEventA(NULL, TRUE, FALSE, NULL);
751 threadinfo.himc = himc;
754
755 otherHimc = ImmGetContext(threadinfo.hwnd);
756
757 ok(himc != otherHimc, "Windows from other threads should have different himc\n");
758 ok(otherHimc == threadinfo.himc, "Context from other thread should not change in main thread\n");
759
760 h1 = ImmAssociateContext(hwnd,otherHimc);
761 ok(h1 == NULL, "Should fail to be able to Associate a default context from a different thread\n");
762 h1 = ImmGetContext(hwnd);
763 ok(h1 == himc, "Context for window should remain unchanged\n");
765
766 h1 = ImmAssociateContext(hwnd, threadinfo.u_himc);
767 ok (h1 == NULL, "Should fail to associate a context from a different thread\n");
768 h1 = ImmGetContext(hwnd);
769 ok(h1 == himc, "Context for window should remain unchanged\n");
771
772 h1 = ImmAssociateContext(threadinfo.hwnd, threadinfo.u_himc);
773 ok (h1 == NULL, "Should fail to associate a context from a different thread into a window from that thread.\n");
774 h1 = ImmGetContext(threadinfo.hwnd);
775 ok(h1 == threadinfo.himc, "Context for window should remain unchanged\n");
776 ImmReleaseContext(threadinfo.hwnd,h1);
777
778 /* OpenStatus */
779 rc = ImmSetOpenStatus(himc, TRUE);
780 ok(rc != 0, "ImmSetOpenStatus failed\n");
781 rc = ImmGetOpenStatus(himc);
782 ok(rc != 0, "ImmGetOpenStatus failed\n");
783 rc = ImmSetOpenStatus(himc, FALSE);
784 ok(rc != 0, "ImmSetOpenStatus failed\n");
785 rc = ImmGetOpenStatus(himc);
786 ok(rc == 0, "ImmGetOpenStatus failed\n");
787
788 rc = ImmSetOpenStatus(otherHimc, TRUE);
789 ok(rc == 0, "ImmSetOpenStatus should fail\n");
790 rc = ImmSetOpenStatus(threadinfo.u_himc, TRUE);
791 ok(rc == 0, "ImmSetOpenStatus should fail\n");
792 rc = ImmGetOpenStatus(otherHimc);
793 ok(rc == 0, "ImmGetOpenStatus failed\n");
794 rc = ImmGetOpenStatus(threadinfo.u_himc);
795 ok (rc == 1 || broken(rc == 0), "ImmGetOpenStatus should return 1\n");
796 rc = ImmSetOpenStatus(otherHimc, FALSE);
797 ok(rc == 0, "ImmSetOpenStatus should fail\n");
798 rc = ImmGetOpenStatus(otherHimc);
799 ok(rc == 0, "ImmGetOpenStatus failed\n");
800
801 /* CompositionFont */
802 rc = ImmGetCompositionFontA(himc, &lf);
803 ok(rc != 0, "ImmGetCompositionFont failed\n");
804 rc = ImmSetCompositionFontA(himc, &lf);
805 ok(rc != 0, "ImmSetCompositionFont failed\n");
806
807 rc = ImmGetCompositionFontA(otherHimc, &lf);
808 ok(rc != 0 || broken(rc == 0), "ImmGetCompositionFont failed\n");
809 rc = ImmGetCompositionFontA(threadinfo.u_himc, &lf);
810 ok(rc != 0 || broken(rc == 0), "ImmGetCompositionFont user himc failed\n");
811 rc = ImmSetCompositionFontA(otherHimc, &lf);
812 ok(rc == 0, "ImmSetCompositionFont should fail\n");
813 rc = ImmSetCompositionFontA(threadinfo.u_himc, &lf);
814 ok(rc == 0, "ImmSetCompositionFont should fail\n");
815
816 /* CompositionWindow */
817 rc = ImmSetCompositionWindow(himc, &cf);
818 ok(rc != 0, "ImmSetCompositionWindow failed\n");
819 rc = ImmGetCompositionWindow(himc, &cf);
820 ok(rc != 0, "ImmGetCompositionWindow failed\n");
821
822 rc = ImmSetCompositionWindow(otherHimc, &cf);
823 ok(rc == 0, "ImmSetCompositionWindow should fail\n");
824 rc = ImmSetCompositionWindow(threadinfo.u_himc, &cf);
825 ok(rc == 0, "ImmSetCompositionWindow should fail\n");
826 rc = ImmGetCompositionWindow(otherHimc, &cf);
827 ok(rc != 0 || broken(rc == 0), "ImmGetCompositionWindow failed\n");
828 rc = ImmGetCompositionWindow(threadinfo.u_himc, &cf);
829 ok(rc != 0 || broken(rc == 0), "ImmGetCompositionWindow failed\n");
830
831 /* ConversionStatus */
832 rc = ImmGetConversionStatus(himc, &status, &sentence);
833 ok(rc != 0, "ImmGetConversionStatus failed\n");
834 rc = ImmSetConversionStatus(himc, status, sentence);
835 ok(rc != 0, "ImmSetConversionStatus failed\n");
836
837 rc = ImmGetConversionStatus(otherHimc, &status, &sentence);
838 ok(rc != 0 || broken(rc == 0), "ImmGetConversionStatus failed\n");
839 rc = ImmGetConversionStatus(threadinfo.u_himc, &status, &sentence);
840 ok(rc != 0 || broken(rc == 0), "ImmGetConversionStatus failed\n");
841 rc = ImmSetConversionStatus(otherHimc, status, sentence);
842 ok(rc == 0, "ImmSetConversionStatus should fail\n");
843 rc = ImmSetConversionStatus(threadinfo.u_himc, status, sentence);
844 ok(rc == 0, "ImmSetConversionStatus should fail\n");
845
846 /* StatusWindowPos */
847 rc = ImmSetStatusWindowPos(himc, &pt);
848 ok(rc != 0, "ImmSetStatusWindowPos failed\n");
849 rc = ImmGetStatusWindowPos(himc, &pt);
850 ok(rc != 0, "ImmGetStatusWindowPos failed\n");
851
852 rc = ImmSetStatusWindowPos(otherHimc, &pt);
853 ok(rc == 0, "ImmSetStatusWindowPos should fail\n");
854 rc = ImmSetStatusWindowPos(threadinfo.u_himc, &pt);
855 ok(rc == 0, "ImmSetStatusWindowPos should fail\n");
856 rc = ImmGetStatusWindowPos(otherHimc, &pt);
857 ok(rc != 0 || broken(rc == 0), "ImmGetStatusWindowPos failed\n");
858 rc = ImmGetStatusWindowPos(threadinfo.u_himc, &pt);
859 ok(rc != 0 || broken(rc == 0), "ImmGetStatusWindowPos failed\n");
860
861 h1 = ImmAssociateContext(threadinfo.hwnd, NULL);
862 ok (h1 == otherHimc, "ImmAssociateContext cross thread with NULL should work\n");
863 h1 = ImmGetContext(threadinfo.hwnd);
864 ok (h1 == NULL, "CrossThread window context should be NULL\n");
865 h1 = ImmAssociateContext(threadinfo.hwnd, h1);
866 ok (h1 == NULL, "Resetting cross thread context should fail\n");
867 h1 = ImmGetContext(threadinfo.hwnd);
868 ok (h1 == NULL, "CrossThread window context should still be NULL\n");
869
870 rc = ImmDestroyContext(threadinfo.u_himc);
871 ok (rc == 0, "ImmDestroyContext Cross Thread should fail\n");
872
873 /* Candidate Window */
874 rc = ImmGetCandidateWindow(himc, 0, &cdf);
875 ok (rc == 0, "ImmGetCandidateWindow should fail\n");
876 cdf.dwIndex = 0;
878 cdf.ptCurrentPos.x = 0;
879 cdf.ptCurrentPos.y = 0;
880 rc = ImmSetCandidateWindow(himc, &cdf);
881 ok (rc == 1, "ImmSetCandidateWindow should succeed\n");
882 rc = ImmGetCandidateWindow(himc, 0, &cdf);
883 ok (rc == 1, "ImmGetCandidateWindow should succeed\n");
884
885 rc = ImmGetCandidateWindow(otherHimc, 0, &cdf);
886 ok (rc == 0, "ImmGetCandidateWindow should fail\n");
887 rc = ImmSetCandidateWindow(otherHimc, &cdf);
888 ok (rc == 0, "ImmSetCandidateWindow should fail\n");
889 rc = ImmGetCandidateWindow(threadinfo.u_himc, 0, &cdf);
890 ok (rc == 1 || broken( rc == 0), "ImmGetCandidateWindow should succeed\n");
891 rc = ImmSetCandidateWindow(threadinfo.u_himc, &cdf);
892 ok (rc == 0, "ImmSetCandidateWindow should fail\n");
893
894 ImmReleaseContext(threadinfo.hwnd,otherHimc);
896
897 SendMessageA(threadinfo.hwnd, WM_CLOSE, 0, 0);
899 ok(rc == 1, "PostThreadMessage should succeed\n");
902
904 ok(himc == NULL, "Should not be able to get himc from other process window\n");
905}
906
907static void test_ImmIsUIMessage(void)
908{
909 struct test
910 {
911 UINT msg;
912 BOOL ret;
913 };
914
915 static const struct test tests[] =
916 {
917 { WM_MOUSEMOVE, FALSE },
918 { WM_IME_STARTCOMPOSITION, TRUE },
919 { WM_IME_ENDCOMPOSITION, TRUE },
920 { WM_IME_COMPOSITION, TRUE },
922 { WM_IME_NOTIFY, TRUE },
925 { WM_IME_SELECT, TRUE },
926 { WM_IME_CHAR, FALSE },
927 { 0x287 /* FIXME */, TRUE },
930 { WM_IME_KEYUP, FALSE },
931 { 0, FALSE } /* mark the end */
932 };
933
934 UINT WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
935 UINT WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
936 UINT WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
937 UINT WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
938 UINT WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
939 UINT WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
940 UINT WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
941
942 const struct test *test;
943 BOOL ret;
944
945 if (!pImmIsUIMessageA) return;
946
947 for (test = tests; test->msg; test++)
948 {
950 ret = pImmIsUIMessageA(NULL, test->msg, 0, 0);
951 ok(ret == test->ret, "ImmIsUIMessageA returned %x for %x\n", ret, test->msg);
952 ok(!msg_spy_find_msg(test->msg), "Windows does not send 0x%x for NULL hwnd\n", test->msg);
953
954 ret = pImmIsUIMessageA(hwnd, test->msg, 0, 0);
955 ok(ret == test->ret, "ImmIsUIMessageA returned %x for %x\n", ret, test->msg);
956 if (ret)
957 ok(msg_spy_find_msg(test->msg) != NULL, "Windows does send 0x%x\n", test->msg);
958 else
959 ok(!msg_spy_find_msg(test->msg), "Windows does not send 0x%x\n", test->msg);
960 }
961
962 ret = pImmIsUIMessageA(NULL, WM_MSIME_SERVICE, 0, 0);
963 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_SERVICE\n");
964 ret = pImmIsUIMessageA(NULL, WM_MSIME_RECONVERTOPTIONS, 0, 0);
965 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_RECONVERTOPTIONS\n");
966 ret = pImmIsUIMessageA(NULL, WM_MSIME_MOUSE, 0, 0);
967 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_MOUSE\n");
968 ret = pImmIsUIMessageA(NULL, WM_MSIME_RECONVERTREQUEST, 0, 0);
969 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_RECONVERTREQUEST\n");
970 ret = pImmIsUIMessageA(NULL, WM_MSIME_RECONVERT, 0, 0);
971 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_RECONVERT\n");
972 ret = pImmIsUIMessageA(NULL, WM_MSIME_QUERYPOSITION, 0, 0);
973 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_QUERYPOSITION\n");
974 ret = pImmIsUIMessageA(NULL, WM_MSIME_DOCUMENTFEED, 0, 0);
975 ok(!ret, "ImmIsUIMessageA returned TRUE for WM_MSIME_DOCUMENTFEED\n");
976}
977
978static void test_ImmGetContext(void)
979{
980 HIMC himc;
981 DWORD err;
982
983 SetLastError(0xdeadbeef);
984 himc = ImmGetContext((HWND)0xffffffff);
985 err = GetLastError();
986 ok(himc == NULL, "ImmGetContext succeeded\n");
987 ok(err == ERROR_INVALID_WINDOW_HANDLE, "got %u\n", err);
988
989 himc = ImmGetContext(hwnd);
990 ok(himc != NULL, "ImmGetContext failed\n");
991 ok(ImmReleaseContext(hwnd, himc), "ImmReleaseContext failed\n");
992}
993
994static void test_ImmGetDescription(void)
995{
996 HKL hkl;
997 WCHAR descW[100];
998 CHAR descA[100];
999 UINT ret, lret;
1000
1001 /* FIXME: invalid keyboard layouts should not pass */
1003 ok(!ret, "ImmGetDescriptionW failed, expected 0 received %d.\n", ret);
1005 ok(!ret, "ImmGetDescriptionA failed, expected 0 received %d.\n", ret);
1006
1007 /* load a language with valid IMM descriptions */
1009 ok(hkl != 0, "GetKeyboardLayout failed, expected != 0.\n");
1010
1012 if(!ret)
1013 {
1014 win_skip("ImmGetDescriptionW is not working for current loaded keyboard.\n");
1015 return;
1016 }
1017
1018 SetLastError(0xdeadcafe);
1019 ret = ImmGetDescriptionW(0, NULL, 100);
1020 ok (ret == 0, "ImmGetDescriptionW with 0 hkl should return 0\n");
1021 ret = GetLastError();
1022 ok (ret == 0xdeadcafe, "Last Error should remain unchanged\n");
1023
1024 ret = ImmGetDescriptionW(hkl, descW, 0);
1025 ok(ret, "ImmGetDescriptionW failed, expected != 0 received 0.\n");
1026
1027 lret = ImmGetDescriptionW(hkl, descW, ret + 1);
1028 ok(lret, "ImmGetDescriptionW failed, expected != 0 received 0.\n");
1029 ok(lret == ret, "ImmGetDescriptionW failed to return the correct amount of data. Expected %d, got %d.\n", ret, lret);
1030
1031 lret = ImmGetDescriptionA(hkl, descA, ret + 1);
1032 ok(lret, "ImmGetDescriptionA failed, expected != 0 received 0.\n");
1033 ok(lret == ret, "ImmGetDescriptionA failed to return the correct amount of data. Expected %d, got %d.\n", ret, lret);
1034
1035 ret /= 2; /* try to copy partially */
1036 lret = ImmGetDescriptionW(hkl, descW, ret + 1);
1037 ok(lret, "ImmGetDescriptionW failed, expected != 0 received 0.\n");
1038 ok(lret == ret, "ImmGetDescriptionW failed to return the correct amount of data. Expected %d, got %d.\n", ret, lret);
1039
1040 lret = ImmGetDescriptionA(hkl, descA, ret + 1);
1041 ok(!lret, "ImmGetDescriptionA should fail\n");
1042
1043 ret = ImmGetDescriptionW(hkl, descW, 1);
1044 ok(!ret, "ImmGetDescriptionW failed, expected 0 received %d.\n", ret);
1045
1047}
1048
1049static LRESULT (WINAPI *old_imm_wnd_proc)(HWND, UINT, WPARAM, LPARAM);
1051{
1052 ok(msg != WM_DESTROY, "got WM_DESTROY message\n");
1053 return old_imm_wnd_proc(hwnd, msg, wparam, lparam);
1054}
1055
1058{
1059 CreateWindowA("static", "static", WS_POPUP, 0, 0, 1, 1, NULL, NULL, NULL, NULL);
1060
1062 ok(thread_ime_wnd != 0, "ImmGetDefaultIMEWnd returned NULL\n");
1064 return 0;
1065}
1066
1067static void test_ImmDefaultHwnd(void)
1068{
1069 HIMC imc1, imc2, imc3;
1070 HWND def1, def3;
1071 HANDLE thread;
1072 HWND hwnd;
1073 char title[16];
1074 LONG style;
1075
1076 hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "Wine imm32.dll test",
1078 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1079
1081
1082 imc1 = ImmGetContext(hwnd);
1083 if (!imc1)
1084 {
1085 win_skip("IME support not implemented\n");
1086 return;
1087 }
1088
1089 def1 = ImmGetDefaultIMEWnd(hwnd);
1090
1091 GetWindowTextA(def1, title, sizeof(title));
1092 ok(!strcmp(title, "Default IME"), "got %s\n", title);
1094 ok(style == (WS_DISABLED | WS_POPUP | WS_CLIPSIBLINGS), "got %08x\n", style);
1096 ok(style == 0, "got %08x\n", style);
1097
1098 imc2 = ImmCreateContext();
1099 ImmSetOpenStatus(imc2, TRUE);
1100
1101 imc3 = ImmGetContext(hwnd);
1102 def3 = ImmGetDefaultIMEWnd(hwnd);
1103
1104 ok(def3 == def1, "Default IME window should not change\n");
1105 ok(imc1 == imc3, "IME context should not change\n");
1106 ImmSetOpenStatus(imc2, FALSE);
1107
1110 ok(thread_ime_wnd != def1, "thread_ime_wnd == def1\n");
1111 ok(!IsWindow(thread_ime_wnd), "thread_ime_wnd was not destroyed\n");
1113
1114 ImmReleaseContext(hwnd, imc1);
1115 ImmReleaseContext(hwnd, imc3);
1116 ImmDestroyContext(imc2);
1118}
1119
1121{
1122 static const WCHAR imeW[] = {'I','M','E',0};
1123 WCHAR class_nameW[16];
1124 HWND *ime_window = (HWND *)param;
1125 if (GetClassNameW(hWnd, class_nameW, ARRAY_SIZE(class_nameW)) && !lstrcmpW(class_nameW, imeW))
1126 {
1127 *ime_window = hWnd;
1128 return FALSE;
1129 }
1130 return TRUE;
1131}
1132
1134{
1135 HWND ime_window = NULL;
1137 return ime_window;
1138}
1139
1143};
1144
1146{
1147 struct testcase_ime_window *testcase = (struct testcase_ime_window *)arg;
1148 DWORD visible = testcase->visible ? WS_VISIBLE : 0;
1149 HWND hwnd1, hwnd2, default_ime_wnd, ime_wnd;
1150
1151 ok(!get_ime_window(), "Expected no IME windows\n");
1152 if (testcase->top_level_window) {
1154 hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1157 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1158 }
1159 else {
1160 hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "Wine imm32.dll test",
1161 WS_CHILD | visible,
1163 240, 24, hwnd, NULL, GetModuleHandleW(NULL), NULL);
1164 }
1165 ime_wnd = get_ime_window();
1166 ok(ime_wnd != NULL, "Expected IME window existence\n");
1167 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd1);
1168 ok(ime_wnd == default_ime_wnd, "Expected %p, got %p\n", ime_wnd, default_ime_wnd);
1169
1171 hwnd2 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1174 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1175 DestroyWindow(hwnd2);
1176 ok(IsWindow(ime_wnd) ||
1177 broken(!testcase->visible /* Vista */) ||
1178 broken(!testcase->top_level_window /* Vista */) ,
1179 "Expected IME window existence\n");
1180 DestroyWindow(hwnd1);
1181 ok(!IsWindow(ime_wnd), "Expected no IME windows\n");
1182 return 1;
1183}
1184
1186{
1187 struct testcase_ime_window *testcase = (struct testcase_ime_window *)arg;
1188 DWORD visible = testcase->visible ? WS_VISIBLE : 0;
1189 HWND hwnd1, hwnd2, default_ime_wnd, ime_wnd;
1190
1191 ok(!get_ime_window(), "Expected no IME windows\n");
1193 hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1196 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1197 ok(hwnd1 == NULL, "creation succeeded, got %p\n", hwnd1);
1198 ok(!get_ime_window(), "Expected no IME windows\n");
1199
1201 hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1204 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1205 ok(hwnd1 == NULL, "creation succeeded, got %p\n", hwnd1);
1206 ok(!get_ime_window(), "Expected no IME windows\n");
1207
1209 hwnd2 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1212 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1213 ime_wnd = get_ime_window();
1214 ok(ime_wnd != NULL, "Expected IME window existence\n");
1215 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd2);
1216 ok(ime_wnd == default_ime_wnd, "Expected %p, got %p\n", ime_wnd, default_ime_wnd);
1217
1218 DestroyWindow(hwnd2);
1219 ok(!IsWindow(ime_wnd), "Expected no IME windows\n");
1220 return 1;
1221}
1222
1224{
1225 HWND hWnd, default_ime_wnd;
1226
1227 ok(!get_ime_window(), "Expected no IME windows\n");
1230 hWnd = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
1233 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1234 default_ime_wnd = ImmGetDefaultIMEWnd(hWnd);
1235 ok(!default_ime_wnd, "Expected no IME windows\n");
1237 return 1;
1238}
1239
1241{
1242 HWND hwnd1, hwnd2, default_ime_wnd;
1243
1245 hwnd1 = CreateWindowA(wndcls, "Wine imm32.dll test",
1249 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd1);
1250 ok(!IsWindow(default_ime_wnd), "Expected no IME windows, got %p\n", default_ime_wnd);
1251
1252 hwnd2 = CreateWindowA(wndcls, "Wine imm32.dll test",
1255 240, 120, hwnd1, NULL, GetModuleHandleW(NULL), NULL);
1256 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd2);
1257 ok(IsWindow(default_ime_wnd), "Expected IME window existence\n");
1258
1259 DestroyWindow(hwnd2);
1260 DestroyWindow(hwnd1);
1261
1262 hwnd1 = CreateWindowA(wndcls, "Wine imm32.dll test",
1265 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
1266 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd1);
1267 ok(IsWindow(default_ime_wnd), "Expected IME window existence\n");
1268 SetParent(hwnd1, HWND_MESSAGE);
1269 default_ime_wnd = ImmGetDefaultIMEWnd(hwnd1);
1270 ok(IsWindow(default_ime_wnd), "Expected IME window existence\n");
1271 DestroyWindow(hwnd1);
1272 return 1;
1273}
1274
1276{
1277 HANDLE thread;
1278 size_t i;
1279 struct testcase_ime_window testcases[] = {
1280 /* visible, top-level window */
1281 { TRUE, TRUE },
1282 { FALSE, TRUE },
1283 { TRUE, FALSE },
1284 { FALSE, FALSE }
1285 };
1286
1287 for (i = 0; i < ARRAY_SIZE(testcases); i++)
1288 {
1289 thread = CreateThread(NULL, 0, test_default_ime_window_cb, &testcases[i], 0, NULL);
1290 ok(thread != NULL, "CreateThread failed with error %u\n", GetLastError());
1292 {
1293 MSG msg;
1294 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
1295 {
1298 }
1299 }
1301
1302 if (testcases[i].top_level_window)
1303 {
1305 ok(thread != NULL, "CreateThread failed with error %u\n", GetLastError());
1308 }
1309 }
1310
1314
1318
1320}
1321
1323{
1324 HIMC imc;
1325 DWORD count, ret, i;
1326 INPUTCONTEXT *ic;
1327
1328 imc = ImmCreateContext();
1329 ImmDestroyContext(imc);
1330 SetLastError(0xdeadbeef);
1331 count = ImmGetIMCLockCount((HIMC)0xdeadcafe);
1332 ok(count == 0, "Invalid IMC should return 0\n");
1333 ret = GetLastError();
1334 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1335 SetLastError(0xdeadbeef);
1336 count = ImmGetIMCLockCount(0x00000000);
1337 ok(count == 0, "NULL IMC should return 0\n");
1338 ret = GetLastError();
1339 ok(ret == 0xdeadbeef, "Last Error should remain unchanged: %08x\n",ret);
1341 ok(count == 0, "Destroyed IMC should return 0\n");
1342 ret = GetLastError();
1343 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1344
1345 imc = ImmCreateContext();
1347 ok(count == 0, "expect 0, returned %d\n", count);
1348 ic = ImmLockIMC(imc);
1349 ok(ic != NULL, "ImmLockIMC failed!\n");
1351 ok(count == 1, "expect 1, returned %d\n", count);
1352 ret = ImmUnlockIMC(imc);
1353 ok(ret == TRUE, "expect TRUE, ret %d\n", ret);
1355 ok(count == 0, "expect 0, returned %d\n", count);
1356 ret = ImmUnlockIMC(imc);
1357 ok(ret == TRUE, "expect TRUE, ret %d\n", ret);
1359 ok(count == 0, "expect 0, returned %d\n", count);
1360
1361 for (i = 0; i < GMEM_LOCKCOUNT * 2; i++)
1362 {
1363 ic = ImmLockIMC(imc);
1364 ok(ic != NULL, "ImmLockIMC failed!\n");
1365 }
1367 todo_wine ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count);
1368
1369 for (i = 0; i < GMEM_LOCKCOUNT - 1; i++)
1370 ImmUnlockIMC(imc);
1372 todo_wine ok(count == 1, "expect 1, returned %d\n", count);
1373 ImmUnlockIMC(imc);
1375 todo_wine ok(count == 0, "expect 0, returned %d\n", count);
1376
1377 ImmDestroyContext(imc);
1378}
1379
1381{
1382 HIMCC imcc;
1383 DWORD count, g_count, i;
1384 BOOL ret;
1385 VOID *p;
1386
1387 imcc = ImmCreateIMCC(sizeof(CANDIDATEINFO));
1388 count = ImmGetIMCCLockCount(imcc);
1389 ok(count == 0, "expect 0, returned %d\n", count);
1390 ImmLockIMCC(imcc);
1391 count = ImmGetIMCCLockCount(imcc);
1392 ok(count == 1, "expect 1, returned %d\n", count);
1393 ret = ImmUnlockIMCC(imcc);
1394 ok(ret == FALSE, "expect FALSE, ret %d\n", ret);
1395 count = ImmGetIMCCLockCount(imcc);
1396 ok(count == 0, "expect 0, returned %d\n", count);
1397 ret = ImmUnlockIMCC(imcc);
1398 ok(ret == FALSE, "expect FALSE, ret %d\n", ret);
1399 count = ImmGetIMCCLockCount(imcc);
1400 ok(count == 0, "expect 0, returned %d\n", count);
1401
1402 p = ImmLockIMCC(imcc);
1403 ok(GlobalHandle(p) == imcc, "expect %p, returned %p\n", imcc, GlobalHandle(p));
1404
1405 for (i = 0; i < GMEM_LOCKCOUNT * 2; i++)
1406 {
1407 ImmLockIMCC(imcc);
1408 count = ImmGetIMCCLockCount(imcc);
1409 g_count = GlobalFlags(imcc) & GMEM_LOCKCOUNT;
1410 ok(count == g_count, "count %d, g_count %d\n", count, g_count);
1411 }
1412 count = ImmGetIMCCLockCount(imcc);
1413 ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count);
1414
1415 for (i = 0; i < GMEM_LOCKCOUNT - 1; i++)
1416 GlobalUnlock(imcc);
1417 count = ImmGetIMCCLockCount(imcc);
1418 ok(count == 1, "expect 1, returned %d\n", count);
1419 GlobalUnlock(imcc);
1420 count = ImmGetIMCCLockCount(imcc);
1421 ok(count == 0, "expect 0, returned %d\n", count);
1422
1423 ImmDestroyIMCC(imcc);
1424}
1425
1426static void test_ImmDestroyContext(void)
1427{
1428 HIMC imc;
1429 DWORD ret, count;
1430 INPUTCONTEXT *ic;
1431
1432 imc = ImmCreateContext();
1434 ok(count == 0, "expect 0, returned %d\n", count);
1435 ic = ImmLockIMC(imc);
1436 ok(ic != NULL, "ImmLockIMC failed!\n");
1438 ok(count == 1, "expect 1, returned %d\n", count);
1439 ret = ImmDestroyContext(imc);
1440 ok(ret == TRUE, "Destroy a locked IMC should success!\n");
1441 ic = ImmLockIMC(imc);
1442 ok(ic == NULL, "Lock a destroyed IMC should fail!\n");
1443 ret = ImmUnlockIMC(imc);
1444 ok(ret == FALSE, "Unlock a destroyed IMC should fail!\n");
1446 ok(count == 0, "Get lock count of a destroyed IMC should return 0!\n");
1447 SetLastError(0xdeadbeef);
1448 ret = ImmDestroyContext(imc);
1449 ok(ret == FALSE, "Destroy a destroyed IMC should fail!\n");
1450 ret = GetLastError();
1451 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1452}
1453
1454static void test_ImmDestroyIMCC(void)
1455{
1456 HIMCC imcc;
1457 DWORD ret, count, size;
1458 VOID *p;
1459
1460 imcc = ImmCreateIMCC(sizeof(CANDIDATEINFO));
1461 count = ImmGetIMCCLockCount(imcc);
1462 ok(count == 0, "expect 0, returned %d\n", count);
1463 p = ImmLockIMCC(imcc);
1464 ok(p != NULL, "ImmLockIMCC failed!\n");
1465 count = ImmGetIMCCLockCount(imcc);
1466 ok(count == 1, "expect 1, returned %d\n", count);
1467 size = ImmGetIMCCSize(imcc);
1468 ok(size == sizeof(CANDIDATEINFO), "returned %d\n", size);
1469 p = ImmDestroyIMCC(imcc);
1470 ok(p == NULL, "Destroy a locked IMCC should success!\n");
1471 p = ImmLockIMCC(imcc);
1472 ok(p == NULL, "Lock a destroyed IMCC should fail!\n");
1473 ret = ImmUnlockIMCC(imcc);
1474 ok(ret == FALSE, "Unlock a destroyed IMCC should return FALSE!\n");
1475 count = ImmGetIMCCLockCount(imcc);
1476 ok(count == 0, "Get lock count of a destroyed IMCC should return 0!\n");
1477 size = ImmGetIMCCSize(imcc);
1478 ok(size == 0, "Get size of a destroyed IMCC should return 0!\n");
1479 SetLastError(0xdeadbeef);
1480 p = ImmDestroyIMCC(imcc);
1481 ok(p != NULL, "returned NULL\n");
1482 ret = GetLastError();
1483 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1484}
1485
1486static void test_ImmMessages(void)
1487{
1489 imm_msgs *msg;
1490 HWND defwnd;
1491 HIMC imc;
1492 UINT idx = 0;
1493
1494 LPINPUTCONTEXT lpIMC;
1495 LPTRANSMSG lpTransMsg;
1496
1497 HWND hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "Wine imm32.dll test",
1499 240, 120, NULL, NULL, GetModuleHandleA(NULL), NULL);
1500
1502 defwnd = ImmGetDefaultIMEWnd(hwnd);
1503 imc = ImmGetContext(hwnd);
1504
1505 ImmSetOpenStatus(imc, TRUE);
1508 do
1509 {
1511 if (msg) ok(!msg->post, "Message should not be posted\n");
1512 } while (msg);
1514
1515 lpIMC = ImmLockIMC(imc);
1516 lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) * sizeof(TRANSMSG));
1517 lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf);
1518 lpTransMsg += lpIMC->dwNumMsgBuf;
1519 lpTransMsg->message = WM_IME_STARTCOMPOSITION;
1520 lpTransMsg->wParam = 0;
1521 lpTransMsg->lParam = 0;
1522 ImmUnlockIMCC(lpIMC->hMsgBuf);
1523 lpIMC->dwNumMsgBuf++;
1524 ImmUnlockIMC(imc);
1525 ImmGenerateMessage(imc);
1526 idx = 0;
1527 do
1528 {
1529 msg = msg_spy_find_next_msg(WM_IME_STARTCOMPOSITION, &idx);
1530 if (msg) ok(!msg->post, "Message should not be posted\n");
1531 } while (msg);
1533
1534 lpIMC = ImmLockIMC(imc);
1535 lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) * sizeof(TRANSMSG));
1536 lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf);
1537 lpTransMsg += lpIMC->dwNumMsgBuf;
1538 lpTransMsg->message = WM_IME_COMPOSITION;
1539 lpTransMsg->wParam = 0;
1540 lpTransMsg->lParam = 0;
1541 ImmUnlockIMCC(lpIMC->hMsgBuf);
1542 lpIMC->dwNumMsgBuf++;
1543 ImmUnlockIMC(imc);
1544 ImmGenerateMessage(imc);
1545 idx = 0;
1546 do
1547 {
1548 msg = msg_spy_find_next_msg(WM_IME_COMPOSITION, &idx);
1549 if (msg) ok(!msg->post, "Message should not be posted\n");
1550 } while (msg);
1552
1553 lpIMC = ImmLockIMC(imc);
1554 lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) * sizeof(TRANSMSG));
1555 lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf);
1556 lpTransMsg += lpIMC->dwNumMsgBuf;
1557 lpTransMsg->message = WM_IME_ENDCOMPOSITION;
1558 lpTransMsg->wParam = 0;
1559 lpTransMsg->lParam = 0;
1560 ImmUnlockIMCC(lpIMC->hMsgBuf);
1561 lpIMC->dwNumMsgBuf++;
1562 ImmUnlockIMC(imc);
1563 ImmGenerateMessage(imc);
1564 idx = 0;
1565 do
1566 {
1567 msg = msg_spy_find_next_msg(WM_IME_ENDCOMPOSITION, &idx);
1568 if (msg) ok(!msg->post, "Message should not be posted\n");
1569 } while (msg);
1571
1572 ImmSetOpenStatus(imc, FALSE);
1573 ImmReleaseContext(hwnd, imc);
1575}
1576
1578 LPARAM lParam )
1579{
1580 return DefWindowProcW(hWnd, msg, wParam, lParam);
1581}
1582
1583static void test_ime_processkey(void)
1584{
1585 WCHAR classNameW[] = {'P','r','o','c','e','s','s', 'K','e','y','T','e','s','t','C','l','a','s','s',0};
1586 WCHAR windowNameW[] = {'P','r','o','c','e','s','s', 'K','e','y',0};
1587
1588 MSG msg;
1589 WNDCLASSW wclass;
1591 TEST_INPUT inputs[2];
1592 HIMC imc;
1593 INT rc;
1594 HWND hWndTest;
1595
1596 wclass.lpszClassName = classNameW;
1597 wclass.style = CS_HREDRAW | CS_VREDRAW;
1599 wclass.hInstance = hInstance;
1600 wclass.hIcon = LoadIconW(0, (LPCWSTR)IDI_APPLICATION);
1602 wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1603 wclass.lpszMenuName = 0;
1604 wclass.cbClsExtra = 0;
1605 wclass.cbWndExtra = 0;
1606 if(!RegisterClassW(&wclass)){
1607 win_skip("Failed to register window.\n");
1608 return;
1609 }
1610
1611 /* create the test window that will receive the keystrokes */
1612 hWndTest = CreateWindowW(wclass.lpszClassName, windowNameW,
1613 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100,
1614 NULL, NULL, hInstance, NULL);
1615
1620
1621 imc = ImmGetContext(hWndTest);
1622 if (!imc)
1623 {
1624 win_skip("IME not supported\n");
1626 return;
1627 }
1628
1629 rc = ImmSetOpenStatus(imc, TRUE);
1630 if (rc != TRUE)
1631 {
1632 win_skip("Unable to open IME\n");
1635 return;
1636 }
1637
1638 /* flush pending messages */
1639 while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageW(&msg);
1640
1642
1643 /* init input data that never changes */
1644 inputs[1].type = inputs[0].type = INPUT_KEYBOARD;
1645 inputs[1].u.ki.dwExtraInfo = inputs[0].u.ki.dwExtraInfo = 0;
1646 inputs[1].u.ki.time = inputs[0].u.ki.time = 0;
1647
1648 /* Pressing a key */
1649 inputs[0].u.ki.wVk = 0x41;
1650 inputs[0].u.ki.wScan = 0x1e;
1651 inputs[0].u.ki.dwFlags = 0x0;
1652
1653 pSendInput(1, (INPUT*)inputs, sizeof(INPUT));
1654
1655 while(PeekMessageW(&msg, hWndTest, 0, 0, PM_NOREMOVE)) {
1656 if(msg.message != WM_KEYDOWN)
1658 else
1659 {
1660 ok(msg.wParam != VK_PROCESSKEY,"Incorrect ProcessKey Found\n");
1662 if(msg.wParam == VK_PROCESSKEY)
1663 trace("ProcessKey was correctly found\n");
1664 }
1667 }
1668
1669 inputs[0].u.ki.wVk = 0x41;
1670 inputs[0].u.ki.wScan = 0x1e;
1671 inputs[0].u.ki.dwFlags = KEYEVENTF_KEYUP;
1672
1673 pSendInput(1, (INPUT*)inputs, sizeof(INPUT));
1674
1675 while(PeekMessageW(&msg, hWndTest, 0, 0, PM_NOREMOVE)) {
1676 if(msg.message != WM_KEYUP)
1678 else
1679 {
1680 ok(msg.wParam != VK_PROCESSKEY,"Incorrect ProcessKey Found\n");
1682 ok(msg.wParam != VK_PROCESSKEY,"ProcessKey should still not be Found\n");
1683 }
1686 }
1687
1689 ImmSetOpenStatus(imc, FALSE);
1691}
1692
1693static void test_InvalidIMC(void)
1694{
1695 HIMC imc_destroy;
1696 HIMC imc_null = 0x00000000;
1697 HIMC imc_bad = (HIMC)0xdeadcafe;
1698
1699 HIMC imc1, imc2, oldimc;
1700 DWORD ret;
1701 DWORD count;
1702 CHAR buffer[1000];
1703 INPUTCONTEXT *ic;
1704 LOGFONTA lf;
1705
1706 memset(&lf, 0, sizeof(lf));
1707
1708 imc_destroy = ImmCreateContext();
1709 ret = ImmDestroyContext(imc_destroy);
1710 ok(ret == TRUE, "Destroy an IMC should success!\n");
1711
1712 /* Test associating destroyed imc */
1713 imc1 = ImmGetContext(hwnd);
1714 SetLastError(0xdeadbeef);
1715 oldimc = ImmAssociateContext(hwnd, imc_destroy);
1716 ok(!oldimc, "Associating to a destroyed imc should fail!\n");
1717 ret = GetLastError();
1718 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1719 imc2 = ImmGetContext(hwnd);
1720 ok(imc1 == imc2, "imc should not changed! imc1 %p, imc2 %p\n", imc1, imc2);
1721
1722 /* Test associating NULL imc, which is different from an invalid imc */
1723 oldimc = ImmAssociateContext(hwnd, imc_null);
1724 ok(oldimc != NULL, "Associating to NULL imc should success!\n");
1725 imc2 = ImmGetContext(hwnd);
1726 ok(!imc2, "expect NULL, returned %p\n", imc2);
1727 oldimc = ImmAssociateContext(hwnd, imc1);
1728 ok(!oldimc, "expect NULL, returned %p\n", oldimc);
1729 imc2 = ImmGetContext(hwnd);
1730 ok(imc2 == imc1, "imc should not changed! imc2 %p, imc1 %p\n", imc2, imc1);
1731
1732 /* Test associating invalid imc */
1733 imc1 = ImmGetContext(hwnd);
1734 SetLastError(0xdeadbeef);
1735 oldimc = ImmAssociateContext(hwnd, imc_bad);
1736 ok(!oldimc, "Associating to a destroyed imc should fail!\n");
1737 ret = GetLastError();
1738 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1739 imc2 = ImmGetContext(hwnd);
1740 ok(imc1 == imc2, "imc should not changed! imc1 %p, imc2 %p\n", imc1, imc2);
1741
1742
1743 /* Test ImmGetCandidateListA */
1744 SetLastError(0xdeadbeef);
1745 ret = ImmGetCandidateListA(imc_bad, 0, NULL, 0);
1746 ok(ret == 0, "Bad IME should return 0\n");
1747 ret = GetLastError();
1748 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1749 SetLastError(0xdeadbeef);
1750 ret = ImmGetCandidateListA(imc_null, 0, NULL, 0);
1751 ok(ret == 0, "NULL IME should return 0\n");
1752 ret = GetLastError();
1753 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1754 SetLastError(0xdeadbeef);
1755 ret = ImmGetCandidateListA(imc_destroy, 0, NULL, 0);
1756 ok(ret == 0, "Destroyed IME should return 0\n");
1757 ret = GetLastError();
1758 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1759
1760 /* Test ImmGetCandidateListCountA*/
1761 SetLastError(0xdeadbeef);
1763 ok(ret == 0, "Bad IME should return 0\n");
1764 ret = GetLastError();
1765 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1766 SetLastError(0xdeadbeef);
1767 ret = ImmGetCandidateListCountA(imc_null,&count);
1768 ok(ret == 0, "NULL IME should return 0\n");
1769 ret = GetLastError();
1770 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1771 SetLastError(0xdeadbeef);
1772 ret = ImmGetCandidateListCountA(imc_destroy,&count);
1773 ok(ret == 0, "Destroyed IME should return 0\n");
1774 ret = GetLastError();
1775 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1776
1777 /* Test ImmGetCandidateWindow */
1778 SetLastError(0xdeadbeef);
1780 ok(ret == 0, "Bad IME should return 0\n");
1781 ret = GetLastError();
1782 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1783 SetLastError(0xdeadbeef);
1785 ok(ret == 0, "NULL IME should return 0\n");
1786 ret = GetLastError();
1787 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1788 SetLastError(0xdeadbeef);
1789 ret = ImmGetCandidateWindow(imc_destroy, 0, (LPCANDIDATEFORM)buffer);
1790 ok(ret == 0, "Destroyed IME should return 0\n");
1791 ret = GetLastError();
1792 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1793
1794 /* Test ImmGetCompositionFontA */
1795 SetLastError(0xdeadbeef);
1797 ok(ret == 0, "Bad IME should return 0\n");
1798 ret = GetLastError();
1799 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1800 SetLastError(0xdeadbeef);
1802 ok(ret == 0, "NULL IME should return 0\n");
1803 ret = GetLastError();
1804 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1805 SetLastError(0xdeadbeef);
1807 ok(ret == 0, "Destroyed IME should return 0\n");
1808 ret = GetLastError();
1809 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1810
1811 /* Test ImmGetCompositionWindow */
1812 SetLastError(0xdeadbeef);
1814 ok(ret == 0, "Bad IME should return 0\n");
1815 ret = GetLastError();
1816 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1817 SetLastError(0xdeadbeef);
1819 ok(ret == 0, "NULL IME should return 0\n");
1820 ret = GetLastError();
1821 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1822 SetLastError(0xdeadbeef);
1824 ok(ret == 0, "Destroyed IME should return 0\n");
1825 ret = GetLastError();
1826 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1827
1828 /* Test ImmGetCompositionStringA */
1829 SetLastError(0xdeadbeef);
1831 ok(ret == 0, "Bad IME should return 0\n");
1832 ret = GetLastError();
1833 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1834 SetLastError(0xdeadbeef);
1836 ok(ret == 0, "NULL IME should return 0\n");
1837 ret = GetLastError();
1838 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1839 SetLastError(0xdeadbeef);
1840 ret = ImmGetCompositionStringA(imc_destroy, GCS_COMPSTR, NULL, 0);
1841 ok(ret == 0, "Destroyed IME should return 0\n");
1842 ret = GetLastError();
1843 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1844
1845 /* Test ImmSetOpenStatus */
1846 SetLastError(0xdeadbeef);
1847 ret = ImmSetOpenStatus(imc_bad, 1);
1848 ok(ret == 0, "Bad IME should return 0\n");
1849 ret = GetLastError();
1850 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1851 SetLastError(0xdeadbeef);
1852 ret = ImmSetOpenStatus(imc_null, 1);
1853 ok(ret == 0, "NULL IME should return 0\n");
1854 ret = GetLastError();
1855 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1856 SetLastError(0xdeadbeef);
1857 ret = ImmSetOpenStatus(imc_destroy, 1);
1858 ok(ret == 0, "Destroyed IME should return 0\n");
1859 ret = GetLastError();
1860 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1861
1862 /* Test ImmGetOpenStatus */
1863 SetLastError(0xdeadbeef);
1864 ret = ImmGetOpenStatus(imc_bad);
1865 ok(ret == 0, "Bad IME should return 0\n");
1866 ret = GetLastError();
1867 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1868 SetLastError(0xdeadbeef);
1869 ret = ImmGetOpenStatus(imc_null);
1870 ok(ret == 0, "NULL IME should return 0\n");
1871 ret = GetLastError();
1872 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1873 SetLastError(0xdeadbeef);
1874 ret = ImmGetOpenStatus(imc_destroy);
1875 ok(ret == 0, "Destroyed IME should return 0\n");
1876 ret = GetLastError();
1877 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1878
1879 /* Test ImmGetStatusWindowPos */
1880 SetLastError(0xdeadbeef);
1881 ret = ImmGetStatusWindowPos(imc_bad, NULL);
1882 ok(ret == 0, "Bad IME should return 0\n");
1883 ret = GetLastError();
1884 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1885 SetLastError(0xdeadbeef);
1886 ret = ImmGetStatusWindowPos(imc_null, NULL);
1887 ok(ret == 0, "NULL IME should return 0\n");
1888 ret = GetLastError();
1889 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
1890 SetLastError(0xdeadbeef);
1891 ret = ImmGetStatusWindowPos(imc_destroy, NULL);
1892 ok(ret == 0, "Destroyed IME should return 0\n");
1893 ret = GetLastError();
1894 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1895
1896 /* Test ImmRequestMessageA */
1897 SetLastError(0xdeadbeef);
1898 ret = ImmRequestMessageA(imc_bad, WM_CHAR, 0);
1899 ok(ret == 0, "Bad IME should return 0\n");
1900 ret = GetLastError();
1901 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1902 SetLastError(0xdeadbeef);
1903 ret = ImmRequestMessageA(imc_null, WM_CHAR, 0);
1904 ok(ret == 0, "NULL IME should return 0\n");
1905 ret = GetLastError();
1906 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1907 SetLastError(0xdeadbeef);
1908 ret = ImmRequestMessageA(imc_destroy, WM_CHAR, 0);
1909 ok(ret == 0, "Destroyed IME should return 0\n");
1910 ret = GetLastError();
1911 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1912
1913 /* Test ImmSetCompositionFontA */
1914 SetLastError(0xdeadbeef);
1915 ret = ImmSetCompositionFontA(imc_bad, &lf);
1916 ok(ret == 0, "Bad IME should return 0\n");
1917 ret = GetLastError();
1918 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1919 SetLastError(0xdeadbeef);
1920 ret = ImmSetCompositionFontA(imc_null, &lf);
1921 ok(ret == 0, "NULL IME should return 0\n");
1922 ret = GetLastError();
1923 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1924 SetLastError(0xdeadbeef);
1925 ret = ImmSetCompositionFontA(imc_destroy, &lf);
1926 ok(ret == 0, "Destroyed IME should return 0\n");
1927 ret = GetLastError();
1928 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1929
1930 /* Test ImmSetCompositionWindow */
1931 SetLastError(0xdeadbeef);
1932 ret = ImmSetCompositionWindow(imc_bad, NULL);
1933 ok(ret == 0, "Bad IME should return 0\n");
1934 ret = GetLastError();
1935 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1936 SetLastError(0xdeadbeef);
1937 ret = ImmSetCompositionWindow(imc_null, NULL);
1938 ok(ret == 0, "NULL IME should return 0\n");
1939 ret = GetLastError();
1940 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1941 SetLastError(0xdeadbeef);
1942 ret = ImmSetCompositionWindow(imc_destroy, NULL);
1943 ok(ret == 0, "Destroyed IME should return 0\n");
1944 ret = GetLastError();
1945 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1946
1947 /* Test ImmSetConversionStatus */
1948 SetLastError(0xdeadbeef);
1949 ret = ImmSetConversionStatus(imc_bad, 0, 0);
1950 ok(ret == 0, "Bad IME should return 0\n");
1951 ret = GetLastError();
1952 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1953 SetLastError(0xdeadbeef);
1954 ret = ImmSetConversionStatus(imc_null, 0, 0);
1955 ok(ret == 0, "NULL IME should return 0\n");
1956 ret = GetLastError();
1957 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1958 SetLastError(0xdeadbeef);
1959 ret = ImmSetConversionStatus(imc_destroy, 0, 0);
1960 ok(ret == 0, "Destroyed IME should return 0\n");
1961 ret = GetLastError();
1962 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1963
1964 /* Test ImmSetStatusWindowPos */
1965 SetLastError(0xdeadbeef);
1966 ret = ImmSetStatusWindowPos(imc_bad, 0);
1967 ok(ret == 0, "Bad IME should return 0\n");
1968 ret = GetLastError();
1969 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1970 SetLastError(0xdeadbeef);
1971 ret = ImmSetStatusWindowPos(imc_null, 0);
1972 ok(ret == 0, "NULL IME should return 0\n");
1973 ret = GetLastError();
1974 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1975 SetLastError(0xdeadbeef);
1976 ret = ImmSetStatusWindowPos(imc_destroy, 0);
1977 ok(ret == 0, "Destroyed IME should return 0\n");
1978 ret = GetLastError();
1979 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1980
1981 /* Test ImmGetImeMenuItemsA */
1982 SetLastError(0xdeadbeef);
1983 ret = ImmGetImeMenuItemsA(imc_bad, 0, 0, NULL, NULL, 0);
1984 ok(ret == 0, "Bad IME should return 0\n");
1985 ret = GetLastError();
1986 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1987 SetLastError(0xdeadbeef);
1988 ret = ImmGetImeMenuItemsA(imc_null, 0, 0, NULL, NULL, 0);
1989 ok(ret == 0, "NULL IME should return 0\n");
1990 ret = GetLastError();
1991 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1992 SetLastError(0xdeadbeef);
1993 ret = ImmGetImeMenuItemsA(imc_destroy, 0, 0, NULL, NULL, 0);
1994 ok(ret == 0, "Destroyed IME should return 0\n");
1995 ret = GetLastError();
1996 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
1997
1998 /* Test ImmLockIMC */
1999 SetLastError(0xdeadbeef);
2000 ic = ImmLockIMC(imc_bad);
2001 ok(ic == 0, "Bad IME should return 0\n");
2002 ret = GetLastError();
2003 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2004 SetLastError(0xdeadbeef);
2005 ic = ImmLockIMC(imc_null);
2006 ok(ic == 0, "NULL IME should return 0\n");
2007 ret = GetLastError();
2008 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
2009 SetLastError(0xdeadbeef);
2010 ic = ImmLockIMC(imc_destroy);
2011 ok(ic == 0, "Destroyed IME should return 0\n");
2012 ret = GetLastError();
2013 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2014
2015 /* Test ImmUnlockIMC */
2016 SetLastError(0xdeadbeef);
2017 ret = ImmUnlockIMC(imc_bad);
2018 ok(ret == 0, "Bad IME should return 0\n");
2019 ret = GetLastError();
2020 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2021 SetLastError(0xdeadbeef);
2022 ret = ImmUnlockIMC(imc_null);
2023 ok(ret == 0, "NULL IME should return 0\n");
2024 ret = GetLastError();
2025 ok(ret == 0xdeadbeef, "last error should remain unchanged %08x!\n", ret);
2026 SetLastError(0xdeadbeef);
2027 ret = ImmUnlockIMC(imc_destroy);
2028 ok(ret == 0, "Destroyed IME should return 0\n");
2029 ret = GetLastError();
2030 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2031
2032 /* Test ImmGenerateMessage */
2033 SetLastError(0xdeadbeef);
2034 ret = ImmGenerateMessage(imc_bad);
2035 ok(ret == 0, "Bad IME should return 0\n");
2036 ret = GetLastError();
2037 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2038 SetLastError(0xdeadbeef);
2039 ret = ImmGenerateMessage(imc_null);
2040 ok(ret == 0, "NULL IME should return 0\n");
2041 ret = GetLastError();
2042 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2043 SetLastError(0xdeadbeef);
2044 ret = ImmGenerateMessage(imc_destroy);
2045 ok(ret == 0, "Destroyed IME should return 0\n");
2046 ret = GetLastError();
2047 ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret);
2048}
2049
2051 if (init())
2052 {
2056 test_ImmIME();
2070 /* Reinitialize the hooks to capture all windows */
2074 if (pSendInput)
2076 else win_skip("SendInput is not available\n");
2077 }
2078 cleanup();
2079}
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
#define broken(x)
Definition: _sntprintf.h:21
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 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:33
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:1568
BOOL WINAPI ImmConfigureIMEA(HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
Definition: ime.c:2009
BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
Definition: ime.c:1624
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
Definition: ime.c:890
BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
Definition: ime.c:1697
UINT WINAPI ImmGetDescriptionA(HKL hKL, LPSTR lpszDescription, UINT uBufLen)
Definition: ime.c:1091
BOOL WINAPI ImmDisableIME(DWORD dwThreadId)
Definition: ime.c:1083
BOOL WINAPI ImmConfigureIMEW(HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
Definition: ime.c:2064
BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
Definition: ime.c:1452
BOOL WINAPI ImmSetConversionStatus(HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
Definition: ime.c:1950
BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
Definition: ime.c:1540
BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
Definition: ime.c:1518
UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
Definition: ime.c:1121
DWORD WINAPI ImmGetImeMenuItemsA(HIMC hIMC, DWORD dwFlags, DWORD dwType, LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu, DWORD dwSize)
Definition: ime.c:2120
DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
Definition: ime.c:1230
BOOL WINAPI ImmNotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
Definition: ime.c:907
BOOL WINAPI ImmGetConversionStatus(HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
Definition: ime.c:1921
BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
Definition: ime.c:1475
BOOL WINAPI ImmSetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
Definition: ime.c:1592
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
Definition: imm.c:1079
HIMC WINAPI ImmCreateContext(void)
Definition: imm.c:602
HIMC WINAPI ImmGetContext(HWND hWnd)
Definition: imm.c:1057
BOOL WINAPI ImmDestroyContext(HIMC hIMC)
Definition: imm.c:928
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
Definition: imm.c:1098
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
Definition: imm.c:1070
HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
Definition: imm.c:503
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
#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:978
static void msg_spy_cleanup(void)
Definition: imm32.c:164
static enum @1639 test_phase
static void test_ImmIsUIMessage(void)
Definition: imm32.c:907
static LRESULT CALLBACK call_wnd_proc_filter(int nCode, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:92
static void test_InvalidIMC(void)
Definition: imm32.c:1693
BOOL catch_result_str
Definition: imm32.c:366
static HWND get_ime_window(void)
Definition: imm32.c:1133
static void test_ImmNotifyIME(void)
Definition: imm32.c:299
static void test_ImmDestroyIMCC(void)
Definition: imm32.c:1454
struct _tagTRANSMSG * LPTRANSMSG
static DWORD WINAPI test_ImmGetDefaultIMEWnd_thread(void *arg)
Definition: imm32.c:1057
static void test_ImmAssociateContextEx(void)
Definition: imm32.c:637
static DWORD WINAPI test_default_ime_with_message_only_window_cb(void *arg)
Definition: imm32.c:1240
static HWND thread_ime_wnd
Definition: imm32.c:1056
static void msg_spy_pump_msg_queue(void)
Definition: imm32.c:110
DWORD timer_id
Definition: imm32.c:369
static void msg_spy_init(HWND hwnd)
Definition: imm32.c:151
static LRESULT WINAPI imm_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: imm32.c:1050
static LRESULT CALLBACK processkey_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:1577
static LPARAM
Definition: imm32.c:34
struct _tagTRANSMSG TRANSMSG
static imm_msgs * msg_spy_find_msg(UINT message)
Definition: imm32.c:145
static void test_ImmThreads(void)
Definition: imm32.c:736
WNDPROC old_wnd_proc
Definition: imm32.c:365
static void test_ImmGetDescription(void)
Definition: imm32.c:994
static BOOL init(void)
Definition: imm32.c:243
static void cleanup(void)
Definition: imm32.c:292
static DWORD WINAPI test_default_ime_window_cb(void *arg)
Definition: imm32.c:1145
static INPUT size_t
Definition: imm32.c:35
static void test_ImmGetIMCCLockCount(void)
Definition: imm32.c:1380
static DWORD WINAPI test_default_ime_disabled_cb(void *arg)
Definition: imm32.c:1223
static void test_ImmIME(void)
Definition: imm32.c:613
static WPARAM
Definition: imm32.c:34
static void test_ImmMessages(void)
Definition: imm32.c:1486
static BOOL CALLBACK is_ime_window_proc(HWND hWnd, LPARAM param)
Definition: imm32.c:1120
static DWORD WINAPI ImmGetContextThreadFunc(LPVOID lpParam)
Definition: imm32.c:684
static LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:183
static DWORD
Definition: imm32.c:33
static void test_ImmDefaultHwnd(void)
Definition: imm32.c:1067
static imm_msgs * msg_spy_find_next_msg(UINT message, UINT *start)
Definition: imm32.c:126
@ CREATE_CANCEL
Definition: imm32.c:178
@ SECOND_WINDOW
Definition: imm32.c:177
@ FIRST_WINDOW
Definition: imm32.c:177
@ NCCREATE_CANCEL
Definition: imm32.c:178
@ PHASE_UNKNOWN
Definition: imm32.c:177
@ IME_DISABLED
Definition: imm32.c:178
static HWND hwnd
Definition: imm32.c:179
static LRESULT CALLBACK get_msg_filter(int nCode, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:72
struct _igc_threadinfo igc_threadinfo
static void test_ImmGetCompositionString(void)
Definition: imm32.c:430
static void test_ImmDestroyContext(void)
Definition: imm32.c:1426
DWORD start
Definition: imm32.c:368
static struct @1640 ime_composition_test
static void test_ime_processkey(void)
Definition: imm32.c:1583
static HIMC
Definition: imm32.c:33
static void test_default_ime_window_creation(void)
Definition: imm32.c:1275
static const char wndcls[]
Definition: imm32.c:176
static struct _msg_spy msg_spy
static void test_ImmSetCompositionString(void)
Definition: imm32.c:578
static DWORD WINAPI test_default_ime_window_cancel_cb(void *arg)
Definition: imm32.c:1185
struct _msgs imm_msgs
static void msg_spy_flush_msgs(void)
Definition: imm32.c:121
static LRESULT WINAPI test_ime_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:372
BOOL catch_ime_char
Definition: imm32.c:367
static void test_ImmGetIMCLockCount(void)
Definition: imm32.c:1322
static UINT
Definition: imm32.c:34
#define CPS_CANCEL
Definition: imm.h:315
#define SCS_CHANGECLAUSE
Definition: imm.h:456
#define SCS_CAP_COMPSTR
Definition: imm.h:403
#define GCS_COMPATTR
Definition: imm.h:368
#define IME_CONFIG_REGISTERWORD
Definition: imm.h:554
#define NI_COMPOSITIONSTR
Definition: imm.h:298
#define GCS_RESULTSTR
Definition: imm.h:374
#define CFS_CANDIDATEPOS
Definition: imm.h:474
#define IACE_DEFAULT
Definition: imm.h:582
#define CPS_COMPLETE
Definition: imm.h:312
#define IGP_SETCOMPSTR
Definition: imm.h:449
#define SCS_SETSTR
Definition: imm.h:454
#define IMC_GETCANDIDATEPOS
Definition: imm.h:278
#define GCS_COMPSTR
Definition: imm.h:367
#define SCS_CHANGEATTR
Definition: imm.h:455
#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:893
LRESULT WINAPI ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam)
Definition: keymsg.c:1167
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#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:79
static HWND hWndTest
Definition: input.c:63
HKL hkl
Definition: msctf.idl:611
UINT_PTR HKL
Definition: msctf.idl:104
__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:160
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::@1641 u
KEYBDINPUT ki
Definition: imm32.c:59
int cbClsExtra
Definition: winuser.h:3194
HINSTANCE hInstance
Definition: winuser.h:3196
HCURSOR hCursor
Definition: winuser.h:3198
LPCSTR lpszMenuName
Definition: winuser.h:3200
HICON hIconSm
Definition: winuser.h:3202
UINT style
Definition: winuser.h:3192
int cbWndExtra
Definition: winuser.h:3195
UINT cbSize
Definition: winuser.h:3191
WNDPROC lpfnWndProc
Definition: winuser.h:3193
LPCSTR lpszClassName
Definition: winuser.h:3201
HICON hIcon
Definition: winuser.h:3197
HBRUSH hbrBackground
Definition: winuser.h:3199
LPCWSTR lpszClassName
Definition: winuser.h:3175
LPCWSTR lpszMenuName
Definition: winuser.h:3174
HBRUSH hbrBackground
Definition: winuser.h:3173
HICON hIcon
Definition: winuser.h:3171
HINSTANCE hInstance
Definition: winuser.h:3170
int cbClsExtra
Definition: winuser.h:3168
UINT style
Definition: winuser.h:3166
WNDPROC lpfnWndProc
Definition: winuser.h:3167
int cbWndExtra
Definition: winuser.h:3169
HCURSOR hCursor
Definition: winuser.h:3172
HIMC u_himc
Definition: imm32.c:680
HANDLE event
Definition: imm32.c:678
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:73
DWORD dwNumMsgBuf
Definition: immdev.h:72
LPARAM lParam
Definition: imm32.c:67
WPARAM wParam
Definition: imm32.c:66
UINT message
Definition: imm32.c:65
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:1142
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
int ret
int WINAPI GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
Definition: window.c:1330
#define INPUT_KEYBOARD
Definition: winable.h:10
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GMEM_LOCKCOUNT
Definition: winbase.h:309
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define WAIT_OBJECT_0
Definition: winbase.h:406
_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:764
#define HWND_MESSAGE
Definition: winuser.h:1200
#define CS_VREDRAW
Definition: winuser.h:653
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define SetWindowLongPtrA
Definition: winuser.h:5335
#define WM_IME_KEYUP
Definition: winuser.h:1829
BOOL WINAPI IsWindow(_In_opt_ HWND)
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define WM_IME_REQUEST
Definition: winuser.h:1826
#define WM_CLOSE
Definition: winuser.h:1611
UINT WINAPI RegisterWindowMessageA(_In_ LPCSTR)
BOOL WINAPI SetWindowTextA(_In_ HWND, _In_opt_ LPCSTR)
BOOL WINAPI UnloadKeyboardLayout(_In_ HKL)
#define WM_QUIT
Definition: winuser.h:1613
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define WM_KEYUP
Definition: winuser.h:1706
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:912
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:1198
#define WM_IME_NOTIFY
Definition: winuser.h:1820
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:1828
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4305
#define WM_CREATE
Definition: winuser.h:1598
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:1234
#define CS_HREDRAW
Definition: winuser.h:648
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define IDC_ARROW
Definition: winuser.h:682
#define HC_ACTION
Definition: winuser.h:48
#define VK_PROCESSKEY
Definition: winuser.h:2317
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define QS_ALLINPUT
Definition: winuser.h:897
#define SWP_NOSIZE
Definition: winuser.h:1235
#define WM_MOUSEMOVE
Definition: winuser.h:1765
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
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:1673
#define IDI_APPLICATION
Definition: winuser.h:699
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
#define WM_IME_SETCONTEXT
Definition: winuser.h:1819
#define WM_IME_CHAR
Definition: winuser.h:1824
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:1732
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2029
#define PM_REMOVE
Definition: winuser.h:1186
BOOL WINAPI UpdateWindow(_In_ HWND)
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4306
#define WM_IME_COMPOSITIONFULL
Definition: winuser.h:1822
#define WM_CHAR
Definition: winuser.h:1707
#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:1821
struct _WNDCLASSEXA WNDCLASSEXA
#define SW_SHOW
Definition: winuser.h:769
#define WM_IME_SELECT
Definition: winuser.h:1823
#define WM_DESTROY
Definition: winuser.h:1599
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define WM_KEYDOWN
Definition: winuser.h:1705
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2896
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:5336
#define WM_NCCALCSIZE
Definition: winuser.h:1675
#define GWL_STYLE
Definition: winuser.h:846
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI DestroyWindow(_In_ HWND)
#define PM_NOREMOVE
Definition: winuser.h:1185
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2044
#define KEYEVENTF_KEYUP
Definition: winuser.h:1096
LRESULT WINAPI CallWindowProcA(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2059
#define WH_CALLWNDPROC
Definition: winuser.h:34
#define GWL_EXSTYLE
Definition: winuser.h:845
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