1 /*
2  * PROJECT:     ReactOS api tests
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Test for ImmEnumInputContext
5  * COPYRIGHT:   Copyright 2022 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6  */
7 
8 #include "precomp.h"
9 #include <windowsx.h>
10 
11 static HWND s_hwnd = NULL;
12 static INT s_nCounter = 0;
13 static HIMC s_hImc1 = NULL;
14 static HIMC s_hImc2 = NULL;
15 static HIMC s_hImc3 = NULL;
16 static HIMC s_hImc4 = NULL;
17 
18 static BOOL CALLBACK
19 ImcEnumProc(HIMC hImc, LPARAM lParam)
20 {
21     trace("s_nCounter %d\n", s_nCounter);
22     switch (s_nCounter)
23     {
24         case 0:
25             ok_long((LONG)lParam, 0xDEADBEEF);
26             ok(hImc == s_hImc1, "hImc was %p, s_hImc1 was %p\n", hImc, s_hImc1);
27             break;
28         case 1:
29             ok_long((LONG)lParam, 0xDEADFACE);
30             ok(hImc == s_hImc1, "hImc was %p, s_hImc1 was %p\n", hImc, s_hImc1);
31             break;
32         case 2:
33             ok_long((LONG)lParam, 0xDEADFACE);
34             ok(hImc == s_hImc2, "hImc was %p, s_hImc2 was %p\n", hImc, s_hImc1);
35             break;
36         case 3:
37             ok_long((LONG)lParam, 0xBEEFCAFE);
38             ok(hImc == s_hImc1, "hImc was %p, s_hImc1 was %p\n", hImc, s_hImc1);
39             break;
40         case 4:
41             ok_long((LONG)lParam, 0xAC1DFACE);
42             ok(hImc == s_hImc1, "hImc was %p, s_hImc1 was %p\n", hImc, s_hImc1);
43             break;
44         case 5:
45             ok_long((LONG)lParam, 0xDEADBEEF);
46             s_hImc3 = hImc;
47             ok(hImc != s_hImc1, "hImc was %p, s_hImc1 was %p\n", hImc, s_hImc1);
48             break;
49         case 6:
50             ok_long((LONG)lParam, 0xBEEFCAFE);
51             ok(hImc == s_hImc3, "hImc was %p, s_hImc3 was %p\n", hImc, s_hImc3);
52             break;
53         case 7:
54             ok_long((LONG)lParam, 0xDEADFACE);
55             ok(hImc == s_hImc3, "hImc was %p, s_hImc3 was %p\n", hImc, s_hImc3);
56             break;
57         case 8:
58             ok_long((LONG)lParam, 0xDEADFACE);
59             ok(hImc == s_hImc4, "hImc was %p, s_hImc4 was %p\n", hImc, s_hImc4);
60             break;
61         case 9:
62             ok_long((LONG)lParam, 0xFEEDF00D);
63             ok(hImc == s_hImc3, "hImc was %p, s_hImc3 was %p\n", hImc, s_hImc3);
64             break;
65         case 10:
66             ok_long((LONG)lParam, 0xFEEDF00D);
67             ok(hImc == s_hImc1, "hImc was %p, s_hImc1 was %p\n", hImc, s_hImc1);
68             break;
69         default:
70             ok_long(0, 1);
71             ok_int(0, 1);
72             break;
73     }
74     ++s_nCounter;
75     return TRUE;
76 }
77 
78 static DWORD WINAPI AnotherThreadFunc(LPVOID arg)
79 {
80     ok_int(ImmEnumInputContext(0, ImcEnumProc, 0xDEADBEEF), TRUE);
81     ok_int(s_nCounter, 6);
82 
83     ok_int(ImmEnumInputContext(GetCurrentThreadId(), ImcEnumProc, 0xBEEFCAFE), TRUE);
84     ok_int(s_nCounter, 7);
85 
86     s_hImc4 = ImmCreateContext();
87 
88     ok_int(ImmEnumInputContext(0, ImcEnumProc, 0xDEADFACE), TRUE);
89     ok_int(s_nCounter, 9);
90 
91     ok_int(ImmDestroyContext(s_hImc4), TRUE);
92     s_hImc4 = NULL;
93 
94     ok_int(ImmEnumInputContext((DWORD)-1, ImcEnumProc, 0xFEEDF00D), TRUE);
95     ok_int(s_nCounter, 11);
96 
97     PostMessageW(s_hwnd, WM_COMMAND, IDYES, 0);
98     return 0;
99 }
100 
101 /* WM_INITDIALOG */
102 static BOOL OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
103 {
104     HANDLE hThread;
105 
106     s_hwnd = hwnd;
107     s_nCounter = 0;
108 
109     s_hImc1 = ImmGetContext(hwnd);
110     ok(s_hImc1 != NULL, "s_hImc1 was NULL\n");
111 
112     ok_int(ImmEnumInputContext(0, ImcEnumProc, 0xDEADBEEF), TRUE);
113     ok_int(s_nCounter, 1);
114 
115     ok_int(ImmEnumInputContext(1, ImcEnumProc, 0xFEEDF00D), FALSE);
116     ok_int(s_nCounter, 1);
117 
118     s_hImc2 = ImmCreateContext();
119     ok(s_hImc2 != NULL, "s_hImc1 was NULL\n");
120 
121     ok_int(ImmEnumInputContext(0, ImcEnumProc, 0xDEADFACE), TRUE);
122     ok_int(s_nCounter, 3);
123 
124     ok_int(ImmDestroyContext(s_hImc2), TRUE);
125     s_hImc2 = NULL;
126 
127     ok_int(ImmEnumInputContext(0, ImcEnumProc, 0xBEEFCAFE), TRUE);
128     ok_int(s_nCounter, 4);
129 
130     ok_int(ImmEnumInputContext(GetCurrentThreadId(), ImcEnumProc, 0xAC1DFACE), TRUE);
131     ok_int(s_nCounter, 5);
132 
133     hThread = CreateThread(NULL, 0, AnotherThreadFunc, NULL, 0, NULL);
134     if (hThread == NULL)
135     {
136         skip("hThread was NULL\n");
137         PostMessageW(hwnd, WM_COMMAND, IDNO, 0);
138     }
139     CloseHandle(hThread);
140 
141     return TRUE;
142 }
143 
144 /* WM_COMMAND */
145 static void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
146 {
147     switch (id)
148     {
149         case IDOK:
150         case IDCANCEL:
151         case IDYES:
152             EndDialog(hwnd, id);
153             break;
154     }
155 }
156 
157 static INT_PTR CALLBACK
158 DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
159 {
160     switch (uMsg)
161     {
162         HANDLE_MSG(hwnd, WM_INITDIALOG, OnInitDialog);
163         HANDLE_MSG(hwnd, WM_COMMAND, OnCommand);
164     }
165     return 0;
166 }
167 
168 START_TEST(ImmEnumInputContext)
169 {
170     INT_PTR id;
171     id = DialogBoxW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(1), NULL, DialogProc);
172     if (id != IDYES)
173     {
174         skip("Tests skipped\n");
175     }
176 }
177