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