ReactOS  0.4.15-dev-4853-g3a72a52
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 
33 static BOOL (WINAPI *pImmAssociateContextEx)(HWND,HIMC,DWORD);
34 static BOOL (WINAPI *pImmIsUIMessageA)(HWND,UINT,WPARAM,LPARAM);
35 static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t);
36 
37 /*
38  * msgspy - record and analyse message traces sent to a certain window
39  */
40 typedef struct _msgs {
43 } imm_msgs;
44 
45 static struct _msg_spy {
47  HHOOK get_msg_hook;
50  unsigned int i_msg;
51 } msg_spy;
52 
53 typedef struct
54 {
56  union
57  {
61  } u;
62 } TEST_INPUT;
63 
64 typedef struct _tagTRANSMSG {
69 
70 static 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 
93  LPARAM lParam)
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 
110 static 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 
121 static 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 
148  return msg_spy_find_next_msg(message, &i);
149 }
150 
151 static 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 
164 static 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  */
176 static const char wndcls[] = "winetest_imm32_wndcls";
179 static HWND hwnd;
180 
181 static HWND get_ime_window(void);
182 
184 {
185  HWND default_ime_wnd;
186  switch (msg)
187  {
188  case WM_IME_SETCONTEXT:
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  }
235  if (test_phase == CREATE_CANCEL)
236  return -1;
237  return TRUE;
238  }
239 
241 }
242 
243 static 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;
264  wc.lpszClassName = wndcls;
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  }
282  ImmReleaseContext(hwnd, imc);
283 
286 
288 
289  return TRUE;
290 }
291 
292 static void cleanup(void) {
293  msg_spy_cleanup();
294  if (hwnd)
297 }
298 
299 static 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 
341  ImmReleaseContext(hwnd, imc);
342 
343  imc = ImmCreateContext();
344  ImmDestroyContext(imc);
345 
346  SetLastError(0xdeadbeef);
347  ret = ImmNotifyIME((HIMC)0xdeadcafe, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
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 
364 static 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);
400  ImmReleaseContext(hwnd, imc);
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");
449  ImmReleaseContext(hwnd, imc);
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 
504  ImmReleaseContext(hwnd, imc);
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");
533  ImmReleaseContext(hwnd, imc);
535  (LONG_PTR)ime_composition_test.old_wnd_proc);
537  }
538 
539  /* Test composition results input by hand */
541  if (winetest_interactive) {
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 
610  ImmReleaseContext(hwnd, imc);
611 }
612 
613 static 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  }
634  ImmReleaseContext(hwnd,imc);
635 }
636 
637 static void test_ImmAssociateContextEx(void)
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  }
673  ImmReleaseContext(hwnd,imc);
674 }
675 
676 typedef struct _igc_threadinfo {
682 
683 
685 {
686  HIMC h1,h2;
687  HWND hwnd2;
689  CANDIDATEFORM cdf;
690  POINT pt;
691  MSG msg;
692 
693  igc_threadinfo *info= (igc_threadinfo*)lpParam;
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 
736 static void test_ImmThreads(void)
737 {
738  HIMC himc, otherHimc, h1;
739  igc_threadinfo threadinfo;
740  HANDLE hThread;
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;
752  hThread = CreateThread(NULL, 0, ImmGetContextThreadFunc, &threadinfo, 0, &dwThreadId );
753  WaitForSingleObject(threadinfo.event, INFINITE);
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);
895  ImmReleaseContext(hwnd,himc);
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 
907 static 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 },
921  { WM_IME_SETCONTEXT, TRUE },
922  { WM_IME_NOTIFY, TRUE },
923  { WM_IME_CONTROL, FALSE },
925  { WM_IME_SELECT, TRUE },
926  { WM_IME_CHAR, FALSE },
927  { 0x287 /* FIXME */, TRUE },
928  { WM_IME_REQUEST, FALSE },
929  { WM_IME_KEYDOWN, FALSE },
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 
978 static 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 
994 static 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 */
1008  hkl = GetKeyboardLayout(0);
1009  ok(hkl != 0, "GetKeyboardLayout failed, expected != 0.\n");
1010 
1011  ret = ImmGetDescriptionW(hkl, NULL, 0);
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 
1049 static 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");
1063  old_imm_wnd_proc = (void*)SetWindowLongPtrW(thread_ime_wnd, GWLP_WNDPROC, (LONG_PTR)imm_wnd_proc);
1064  return 0;
1065 }
1066 
1067 static 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);
1093  style = GetWindowLongA(def1, GWL_STYLE);
1094  ok(style == (WS_DISABLED | WS_POPUP | WS_CLIPSIBLINGS), "got %08x\n", style);
1095  style = GetWindowLongA(def1, GWL_EXSTYLE);
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 
1133 static HWND get_ime_window(void)
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",
1248  240, 120, HWND_MESSAGE, NULL, GetModuleHandleW(NULL), NULL);
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 
1322 static void test_ImmGetIMCLockCount(void)
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);
1340  count = ImmGetIMCLockCount(imc);
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();
1346  count = ImmGetIMCLockCount(imc);
1347  ok(count == 0, "expect 0, returned %d\n", count);
1348  ic = ImmLockIMC(imc);
1349  ok(ic != NULL, "ImmLockIMC failed!\n");
1350  count = ImmGetIMCLockCount(imc);
1351  ok(count == 1, "expect 1, returned %d\n", count);
1352  ret = ImmUnlockIMC(imc);
1353  ok(ret == TRUE, "expect TRUE, ret %d\n", ret);
1354  count = ImmGetIMCLockCount(imc);
1355  ok(count == 0, "expect 0, returned %d\n", count);
1356  ret = ImmUnlockIMC(imc);
1357  ok(ret == TRUE, "expect TRUE, ret %d\n", ret);
1358  count = ImmGetIMCLockCount(imc);
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  }
1366  count = ImmGetIMCLockCount(imc);
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);
1371  count = ImmGetIMCLockCount(imc);
1372  todo_wine ok(count == 1, "expect 1, returned %d\n", count);
1373  ImmUnlockIMC(imc);
1374  count = ImmGetIMCLockCount(imc);
1375  todo_wine ok(count == 0, "expect 0, returned %d\n", count);
1376 
1377  ImmDestroyContext(imc);
1378 }
1379 
1380 static void test_ImmGetIMCCLockCount(void)
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 
1426 static void test_ImmDestroyContext(void)
1427 {
1428  HIMC imc;
1429  DWORD ret, count;
1430  INPUTCONTEXT *ic;
1431 
1432  imc = ImmCreateContext();
1433  count = ImmGetIMCLockCount(imc);
1434  ok(count == 0, "expect 0, returned %d\n", count);
1435  ic = ImmLockIMC(imc);
1436  ok(ic != NULL, "ImmLockIMC failed!\n");
1437  count = ImmGetIMCLockCount(imc);
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");
1445  count = ImmGetIMCLockCount(imc);
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 
1454 static 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 
1486 static void test_ImmMessages(void)
1487 {
1488  CANDIDATEFORM cf;
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 
1583 static 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);
1601  wclass.hCursor = LoadCursorW( NULL, (LPCWSTR)IDC_ARROW);
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 
1641  SetFocus(hWndTest);
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)
1657  PeekMessageW(&msg, hWndTest, 0, 0, PM_REMOVE);
1658  else
1659  {
1660  ok(msg.wParam != VK_PROCESSKEY,"Incorrect ProcessKey Found\n");
1661  PeekMessageW(&msg, hWndTest, 0, 0, PM_REMOVE);
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)
1677  PeekMessageW(&msg, hWndTest, 0, 0, PM_REMOVE);
1678  else
1679  {
1680  ok(msg.wParam != VK_PROCESSKEY,"Incorrect ProcessKey Found\n");
1681  PeekMessageW(&msg, hWndTest, 0, 0, PM_REMOVE);
1682  ok(msg.wParam != VK_PROCESSKEY,"ProcessKey should still not be Found\n");
1683  }
1686  }
1687 
1689  ImmSetOpenStatus(imc, FALSE);
1691 }
1692 
1693 static 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);
1762  ret = ImmGetCandidateListCountA(imc_bad,&count);
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);
1806  ret = ImmGetCompositionFontA(imc_destroy, (LPLOGFONTA)buffer);
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);
1830  ret = ImmGetCompositionStringA(imc_bad, GCS_COMPSTR, NULL, 0);
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);
1835  ret = ImmGetCompositionStringA(imc_null, GCS_COMPSTR, NULL, 0);
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 
2050 START_TEST(imm32) {
2051  if (init())
2052  {
2056  test_ImmIME();
2058  test_ImmThreads();
2068  test_InvalidIMC();
2069  msg_spy_cleanup();
2070  /* Reinitialize the hooks to capture all windows */
2071  msg_spy_init(NULL);
2072  test_ImmMessages();
2073  msg_spy_cleanup();
2074  if (pSendInput)
2076  else win_skip("SendInput is not available\n");
2077  }
2078  cleanup();
2079 }
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
DWORD WINAPI ImmGetImeMenuItemsA(HIMC hIMC, DWORD dwFlags, DWORD dwType, LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu, DWORD dwSize)
Definition: ime.c:1795
DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
Definition: utils.c:1024
DWORD HIMCC
Definition: dimm.idl:76
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
static IClassFactory * cf
static void test_ImmSetCompositionString(void)
Definition: imm32.c:578
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
Definition: utils.c:1034
struct _WNDCLASSEXA WNDCLASSEXA
#define WS_DISABLED
Definition: pedump.c:621
#define WM_IME_KEYUP
Definition: winuser.h:1826
static void test_ImmGetIMCLockCount(void)
Definition: imm32.c:1322
UINT style
Definition: winuser.h:3182
BOOL catch_result_str
Definition: imm32.c:366
static void msg_spy_init(HWND hwnd)
Definition: imm32.c:151
static void test_ImmAssociateContextEx(void)
Definition: imm32.c:637
#define WM_IME_NOTIFY
Definition: winuser.h:1817
DWORD type
Definition: imm32.c:55
BOOL WINAPI TranslateMessage(_In_ const MSG *)
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
Definition: tftpd.h:59
LONG WINAPI ImmGetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
Definition: compstr.c:850
static BOOL init(void)
Definition: imm32.c:243
MOUSEINPUT mi
Definition: imm32.c:58
LPCSTR lpszMenuName
Definition: winuser.h:3190
#define CloseHandle
Definition: compat.h:598
#define VK_PROCESSKEY
Definition: winuser.h:2307
#define WH_GETMESSAGE
Definition: winuser.h:33
DWORD WINAPI ImmGetCandidateListCountA(HIMC hIMC, LPDWORD lpdwListCount)
Definition: candidate.c:333
#define WM_IME_KEYDOWN
Definition: winuser.h:1825
int WINAPI GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
Definition: window.c:1330
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static LRESULT WINAPI imm_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: imm32.c:1050
long y
Definition: polytest.cpp:48
BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
Definition: ime.c:1380
UINT style
Definition: winuser.h:3156
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WM_CHAR
Definition: winuser.h:1704
HCURSOR hCursor
Definition: winuser.h:3188
WNDPROC lpfnWndProc
Definition: winuser.h:3183
LPCWSTR lpszMenuName
Definition: winuser.h:3164
#define WM_IME_CHAR
Definition: winuser.h:1821
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
CWPSTRUCT msg
Definition: imm32.c:41
BOOL WINAPI IsWindow(_In_opt_ HWND)
HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
Definition: utils.c:976
BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
Definition: ime.c:1144
static DWORD WINAPI ImmGetContextThreadFunc(LPVOID lpParam)
Definition: imm32.c:684
#define KEYEVENTF_KEYUP
Definition: winuser.h:1096
long x
Definition: polytest.cpp:48
HWND hwndMain
Definition: solitaire.cpp:12
static LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:183
Definition: imm32.c:45
LPCSTR lpszClassName
Definition: winuser.h:3191
BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
Definition: ime.c:1307
LPARAM lParam
Definition: imm32.c:67
#define TRUE
Definition: types.h:120
#define pt(x, y)
Definition: drawing.c:79
UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
Definition: ime.c:851
static WPARAM
Definition: imm32.c:34
HWND WINAPI SetParent(_In_ HWND, _In_opt_ HWND)
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
Definition: imm.c:1023
static struct test_info tests[]
HANDLE event
Definition: imm32.c:678
#define WM_NCCALCSIZE
Definition: winuser.h:1672
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
BOOL WINAPI ImmSetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD dwCompLen, LPVOID lpRead, DWORD dwReadLen)
Definition: compstr.c:947
GLuint GLuint GLsizei count
Definition: gl.h:1545
DWORD timer_id
Definition: imm32.c:369
UINT NTAPI GlobalFlags(HGLOBAL hMem)
Definition: heapmem.c:520
char CHAR
Definition: xmlstorage.h:175
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
Definition: imm32.c:40
unsigned int i_msg
Definition: imm32.c:50
#define CALLBACK
Definition: compat.h:35
BOOL WINAPI UpdateWindow(_In_ HWND)
HWND hWnd
Definition: settings.c:17
LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
Definition: utils.c:986
#define WM_QUIT
Definition: winuser.h:1610
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
#define WM_IME_SELECT
Definition: winuser.h:1820
HANDLE HWND
Definition: compat.h:19
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI EnumThreadWindows(_In_ DWORD, _In_ WNDENUMPROC, _In_ LPARAM)
DWORD time
Definition: winable.h:50
BOOL WINAPI PostThreadMessageA(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
static void msg_spy_pump_msg_queue(void)
Definition: imm32.c:110
#define todo_wine
Definition: custom.c:79
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define CS_HREDRAW
Definition: winuser.h:648
#define GWL_EXSTYLE
Definition: winuser.h:845
#define HWND_TOPMOST
Definition: winuser.h:1198
GLuint buffer
Definition: glext.h:5915
int cbClsExtra
Definition: winuser.h:3158
HWND WINAPI SetFocus(_In_opt_ HWND)
DWORD dwStyle
Definition: dimm.idl:80
static BOOL CALLBACK is_ime_window_proc(HWND hWnd, LPARAM param)
Definition: imm32.c:1120
#define test
Definition: rosglue.h:37
HGLOBAL NTAPI GlobalHandle(LPCVOID pMem)
Definition: heapmem.c:705
#define IDI_APPLICATION
Definition: winuser.h:699
UINT_PTR WPARAM
Definition: windef.h:207
#define WS_CHILD
Definition: pedump.c:617
#define HWND_MESSAGE
Definition: winuser.h:1200
HICON hIconSm
Definition: winuser.h:3192
int winetest_interactive
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
static void test_ImmIME(void)
Definition: imm32.c:613
HARDWAREINPUT hi
Definition: imm32.c:60
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
BOOL WINAPI ImmGetCandidateWindow(HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate)
Definition: candidate.c:359
UINT message
Definition: imm32.c:65
static DWORD WINAPI test_default_ime_disabled_cb(void *arg)
Definition: imm32.c:1223
#define WM_NCCREATE
Definition: winuser.h:1670
BOOL WINAPI DestroyWindow(_In_ HWND)
static void test_ImmGetIMCCLockCount(void)
Definition: imm32.c:1380
BOOL WINAPI ImmSetConversionStatus(HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
Definition: ime.c:1627
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4296
#define COLOR_WINDOW
Definition: winuser.h:912
#define WM_IME_COMPOSITIONFULL
Definition: winuser.h:1819
int32_t INT
Definition: typedefs.h:58
WPARAM wParam
Definition: combotst.c:138
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2029
#define CPS_CANCEL
Definition: imm.h:315
FILE * stdout
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI ImmDestroyContext(HIMC hIMC)
Definition: imm.c:890
static void msg_spy_cleanup(void)
Definition: imm32.c:164
LRESULT WINAPI CallWindowProcA(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define PM_NOREMOVE
Definition: winuser.h:1185
int WINAPI GetClassNameW(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPWSTR lpClassName, _In_ int nMaxCount)
BOOL catch_ime_char
Definition: imm32.c:367
DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
Definition: ime.c:933
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
HWND hwnd
Definition: imm32.c:46
HINSTANCE hInstance
Definition: charmap.c:20
#define INPUT_KEYBOARD
Definition: winable.h:10
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
#define FALSE
Definition: types.h:117
HINSTANCE hInstance
Definition: winuser.h:3186
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define IME_CONFIG_REGISTERWORD
Definition: imm.h:554
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
Definition: ime.c:1167
long LONG
Definition: pedump.c:60
static void msg_spy_flush_msgs(void)
Definition: imm32.c:121
static void test_default_ime_window_creation(void)
Definition: imm32.c:1275
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define CPS_COMPLETE
Definition: imm.h:312
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
WNDPROC lpfnWndProc
Definition: winuser.h:3157
static void test_ImmThreads(void)
Definition: imm32.c:736
static DWORD WINAPI test_default_ime_window_cancel_cb(void *arg)
Definition: imm32.c:1185
static const char wndcls[]
Definition: imm32.c:176
static UINT
Definition: imm32.c:34
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4295
unsigned int idx
Definition: utils.c:41
#define CW_USEDEFAULT
Definition: winuser.h:225
static imm_msgs * msg_spy_find_msg(UINT message)
Definition: imm32.c:145
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
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
BOOL WINAPI ImmConfigureIMEA(HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
Definition: ime.c:1686
#define WM_KEYDOWN
Definition: winuser.h:1702
LPCWSTR lpszClassName
Definition: winuser.h:3165
BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
Definition: ime.c:1256
LONG_PTR LPARAM
Definition: windef.h:208
UINT cbSize
Definition: winuser.h:3181
struct _tagTRANSMSG * LPTRANSMSG
static HWND thread_ime_wnd
Definition: imm32.c:1056
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
const char * LPCSTR
Definition: xmlstorage.h:183
#define SW_SHOW
Definition: winuser.h:769
#define WM_IME_REQUEST
Definition: winuser.h:1823
DWORD HIMC
Definition: dimm.idl:75
static void test_InvalidIMC(void)
Definition: imm32.c:1693
#define GCS_COMPATTR
Definition: imm.h:368
HIMC WINAPI ImmCreateContext(void)
Definition: imm.c:589
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:459
HBRUSH hbrBackground
Definition: winuser.h:3189
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define WM_DESTROY
Definition: winuser.h:1596
static HWND hWndTest
Definition: input.c:63
#define SCS_CAP_COMPSTR
Definition: imm.h:403
DWORD dwFlags
Definition: winable.h:49
#define CS_VREDRAW
Definition: winuser.h:653
HIMCC WINAPI ImmCreateIMCC(DWORD size)
Definition: utils.c:966
BOOL WINAPI ImmNotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
Definition: ime.c:652
static LRESULT CALLBACK processkey_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:1577
#define ERROR_INVALID_WINDOW_HANDLE
Definition: winerror.h:881
#define WAIT_OBJECT_0
Definition: winbase.h:403
GLsizeiptr size
Definition: glext.h:5919
#define trace
Definition: atltest.h:70
static LPARAM
Definition: imm32.c:34
struct _igc_threadinfo igc_threadinfo
r parent
Definition: btrfs.c:2979
int cbWndExtra
Definition: winuser.h:3159
static void test_ImmDestroyIMCC(void)
Definition: imm32.c:1454
LONG WINAPI ImmGetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
Definition: compstr.c:892
__wchar_t WCHAR
Definition: xmlstorage.h:180
BOOL WINAPI UnloadKeyboardLayout(_In_ HKL)
BOOL WINAPI SetWindowTextA(_In_ HWND, _In_opt_ LPCSTR)
#define WM_IME_SETCONTEXT
Definition: winuser.h:1816
HIMC WINAPI ImmGetContext(HWND hWnd)
Definition: imm.c:1010
struct _msgs imm_msgs
#define WM_TIMER
Definition: winuser.h:1729
#define WM_IME_CONTROL
Definition: winuser.h:1818
#define WM_CLOSE
Definition: winuser.h:1608
#define NI_COMPOSITIONSTR
Definition: imm.h:298
GLfloat param
Definition: glext.h:5796
#define WINAPI
Definition: msvc.h:6
#define WM_KEYUP
Definition: winuser.h:1703
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint left
Definition: glext.h:7726
HICON hIcon
Definition: winuser.h:3161
static void test_ImmIsUIMessage(void)
Definition: imm32.c:907
int cbWndExtra
Definition: winuser.h:3185
HHOOK get_msg_hook
Definition: imm32.c:47
struct _tagTRANSMSG TRANSMSG
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
#define SetLastError(x)
Definition: compat.h:611
BOOL top_level_window
Definition: imm32.c:1142
BOOL post
Definition: imm32.c:42
static void test_ImmGetDescription(void)
Definition: imm32.c:994
static DWORD
Definition: imm32.c:33
#define IMC_GETCANDIDATEPOS
Definition: imm.h:278
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
Definition: utils.c:996
static HANDLE thread
Definition: service.c:33
BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
Definition: ime.c:1206
static LRESULT CALLBACK get_msg_filter(int nCode, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:72
int ret
DWORD dwThreadId
Definition: fdebug.c:31
static LRESULT WINAPI test_ime_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:372
HIMCC hMsgBuf
Definition: immdev.h:56
static struct _msg_spy msg_spy
HICON hIcon
Definition: winuser.h:3187
POINT ptCurrentPos
Definition: dimm.idl:81
#define IGP_SETCOMPSTR
Definition: imm.h:449
#define WH_CALLWNDPROC
Definition: winuser.h:34
BOOL WINAPI ImmSetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD dwCompLen, LPVOID lpRead, DWORD dwReadLen)
Definition: compstr.c:935
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
#define SetWindowLongPtrA
Definition: winuser.h:5325
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
Definition: keymsg.c:779
#define err(...)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
UINT_PTR HKL
Definition: msctf.idl:101
ATOM WINAPI RegisterClassExA(_In_ CONST WNDCLASSEXA *)
HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
Definition: imm.c:500
BOOL WINAPI ImmConfigureIMEW(HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
Definition: ime.c:1740
static HIMC
Definition: imm32.c:33
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2059
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
#define GWLP_WNDPROC
Definition: treelist.c:66
#define broken(x)
Definition: _sntprintf.h:21
BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
Definition: ime.c:1228
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
Definition: imm.c:1051
#define SWP_NOSIZE
Definition: winuser.h:1235
HCURSOR hCursor
Definition: winuser.h:3162
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2886
#define GWL_STYLE
Definition: winuser.h:846
HWND WINAPI GetParent(_In_ HWND)
BOOL WINAPI ImmGetConversionStatus(HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
Definition: ime.c:1605
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
#define SW_SHOWNORMAL
Definition: winuser.h:764
int cbClsExtra
Definition: winuser.h:3184
static DWORD WINAPI test_default_ime_window_cb(void *arg)
Definition: imm32.c:1145
HKL hkl
Definition: msctf.idl:611
WPARAM wParam
Definition: imm32.c:66
static void test_ImmNotifyIME(void)
Definition: imm32.c:299
static LRESULT CALLBACK call_wnd_proc_filter(int nCode, WPARAM wParam, LPARAM lParam)
Definition: imm32.c:92
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
Definition: ime.c:638
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
int WINAPIV wsprintfA(_Out_ LPSTR, _In_ _Printf_format_string_ LPCSTR,...)
WORD wScan
Definition: winable.h:48
static imm_msgs * msg_spy_find_next_msg(UINT message, UINT *start)
Definition: imm32.c:126
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
DWORD dwIndex
Definition: dimm.idl:79
GLuint start
Definition: gl.h:1545
#define ARRAY_SIZE(a)
Definition: main.h:24
#define HC_ACTION
Definition: winuser.h:48
static LRESULT(WINAPI *old_imm_wnd_proc)(HWND
HBRUSH hbrBackground
Definition: winuser.h:3163
#define QS_ALLINPUT
Definition: winuser.h:897
#define ok(value,...)
Definition: atltest.h:57
HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
Definition: utils.c:1014
static INPUT size_t
Definition: imm32.c:35
PKEYBOARD_LAYOUT GetKeyboardLayout()
Definition: utils.c:194
static struct @1619 ime_composition_test
DWORD dwNumMsgBuf
Definition: immdev.h:55
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define WS_POPUP
Definition: pedump.c:616
#define SCS_CHANGECLAUSE
Definition: imm.h:456
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1762
#define NULL
Definition: types.h:112
HHOOK call_wnd_proc_hook
Definition: imm32.c:48
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
BOOL WINAPI ImmDisableIME(DWORD dwThreadId)
Definition: ime.c:822
static HWND hwnd
Definition: imm32.c:179
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
HANDLE hThread
Definition: wizard.c:28
START_TEST(imm32)
Definition: imm32.c:2050
HINSTANCE hInstance
Definition: winuser.h:3160
#define skip(...)
Definition: atltest.h:64
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
BOOL WINAPI ImmSetCandidateWindow(HIMC hIMC, LPCANDIDATEFORM lpCandidate)
Definition: candidate.c:385
#define SCS_SETSTR
Definition: imm.h:454
WNDPROC old_wnd_proc
Definition: imm32.c:365
DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
Definition: utils.c:1006
HHOOK WINAPI SetWindowsHookExW(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
#define WM_CREATE
Definition: winuser.h:1595
static void test_ImmGetContext(void)
Definition: imm32.c:978
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)
static void cleanup(void)
Definition: imm32.c:292
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
HIMC u_himc
Definition: imm32.c:680
#define GCS_RESULTSTR
Definition: imm.h:374
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
BOOL WINAPI SetForegroundWindow(_In_ HWND)
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2044
LRESULT WINAPI ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam)
Definition: keymsg.c:1039
ULONG_PTR dwExtraInfo
Definition: winable.h:51
#define GetProcAddress(x, y)
Definition: compat.h:612
#define SWP_NOMOVE
Definition: winuser.h:1234
static void test_ImmDestroyContext(void)
Definition: imm32.c:1426
static HWND get_ime_window(void)
Definition: imm32.c:1133
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define SetWindowLongPtrW
Definition: winuser.h:5326
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
#define SCS_CHANGEATTR
Definition: imm.h:455
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define PM_REMOVE
Definition: winuser.h:1186
static void test_ime_processkey(void)
Definition: imm32.c:1583
static BOOL(WINAPI *pImmAssociateContextEx)(HWND
GLfloat GLfloat p
Definition: glext.h:8902
BOOL WINAPI ImmSetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
Definition: ime.c:1280
LONG_PTR LRESULT
Definition: windef.h:209
#define CFS_CANDIDATEPOS
Definition: imm.h:474
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
#define INFINITE
Definition: serial.h:102
static DWORD WINAPI test_default_ime_with_message_only_window_cb(void *arg)
Definition: imm32.c:1240
union TEST_INPUT::@1620 u
#define IACE_DEFAULT
Definition: imm.h:582
Arabic default style
Definition: afstyles.h:93
#define GCS_COMPSTR
Definition: imm.h:367
#define WS_VISIBLE
Definition: pedump.c:620
static void test_ImmMessages(void)
Definition: imm32.c:1486
DWORD start
Definition: imm32.c:368
#define memset(x, y, z)
Definition: compat.h:39
KEYBDINPUT ki
Definition: imm32.c:59
static SERVICE_STATUS status
Definition: service.c:31
DWORD WINAPI ImmGetCandidateListA(HIMC hIMC, DWORD dwIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen)
Definition: candidate.c:325
#define GMEM_LOCKCOUNT
Definition: winbase.h:306
#define win_skip
Definition: test.h:160
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
Definition: imm.c:1032
LPARAM lParam
Definition: combotst.c:139
static char title[]
Definition: ps.c:92
WORD wVk
Definition: winable.h:47
static DWORD WINAPI test_ImmGetDefaultIMEWnd_thread(void *arg)
Definition: imm32.c:1057
static enum @1618 test_phase
UINT WINAPI ImmGetDescriptionA(HKL hKL, LPSTR lpszDescription, UINT uBufLen)
Definition: ime.c:830
UINT WINAPI RegisterWindowMessageA(_In_ LPCSTR)
KEYBDINPUT ki
Definition: winable.h:62
static UINT WPARAM wparam
Definition: combo.c:716
static void test_ImmGetCompositionString(void)
Definition: imm32.c:430
imm_msgs msgs[64]
Definition: imm32.c:49
Definition: ps.c:97
static void test_ImmDefaultHwnd(void)
Definition: imm32.c:1067