1 /*
2  * PROJECT:     ReactOS api tests
3  * LICENSE:     LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4  * PURPOSE:     Test for Shell Hook
5  * COPYRIGHT:   Copyright 2020-2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6  */
7 #include "shelltest.h"
8 
9 struct TEST_ENTRY
10 {
11     INT lineno;
12     UINT cCreated;
13     UINT cDestroyed;
14     BOOL bIsChild;
15     BOOL bHasOwner;
16     DWORD style;
17     DWORD exstyle;
18     DWORD owner_style;
19     DWORD owner_exstyle;
20 };
21 
22 #define STYLE_0  WS_POPUP
23 #define STYLE_1  (WS_POPUP | WS_VISIBLE)
24 #define STYLE_2  (WS_OVERLAPPED | WS_VISIBLE)
25 
26 #define EXSTYLE_0  0
27 #define EXSTYLE_1  WS_EX_APPWINDOW
28 #define EXSTYLE_2  WS_EX_TOOLWINDOW
29 #define EXSTYLE_3  (WS_EX_APPWINDOW | WS_EX_TOOLWINDOW)
30 
31 #define TYPE_0 FALSE, FALSE
32 #define TYPE_1 FALSE, TRUE
33 #define TYPE_2 TRUE, TRUE
34 
35 static const TEST_ENTRY s_entries1[] =
36 {
37     // TYPE_0
38     { __LINE__, 0, 0, TYPE_0, STYLE_0, EXSTYLE_0 },
39     { __LINE__, 0, 0, TYPE_0, STYLE_0, EXSTYLE_1 },
40     { __LINE__, 0, 0, TYPE_0, STYLE_0, EXSTYLE_2 },
41     { __LINE__, 0, 0, TYPE_0, STYLE_0, EXSTYLE_3 },
42     { __LINE__, 1, 1, TYPE_0, STYLE_1, EXSTYLE_0 },
43     { __LINE__, 1, 1, TYPE_0, STYLE_1, EXSTYLE_1 },
44     { __LINE__, 0, 0, TYPE_0, STYLE_1, EXSTYLE_2 },
45     { __LINE__, 1, 1, TYPE_0, STYLE_1, EXSTYLE_3 },
46     { __LINE__, 1, 1, TYPE_0, STYLE_2, EXSTYLE_0 },
47     { __LINE__, 1, 1, TYPE_0, STYLE_2, EXSTYLE_1 },
48     { __LINE__, 0, 0, TYPE_0, STYLE_2, EXSTYLE_2 },
49     { __LINE__, 1, 1, TYPE_0, STYLE_2, EXSTYLE_3 },
50 
51     // TYPE_1
52     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_0, EXSTYLE_0 },
53     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_0, EXSTYLE_1 },
54     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_0, EXSTYLE_2 },
55     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_0, EXSTYLE_3 },
56     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_1, EXSTYLE_0 },
57     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_1, EXSTYLE_1 },
58     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_1, EXSTYLE_2 },
59     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_1, EXSTYLE_3 },
60     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_2, EXSTYLE_0 },
61     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_2, EXSTYLE_1 },
62     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_2, EXSTYLE_2 },
63     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_0, STYLE_2, EXSTYLE_3 },
64     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_0, EXSTYLE_0 },
65     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_0, EXSTYLE_1 },
66     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_0, EXSTYLE_2 },
67     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_0, EXSTYLE_3 },
68     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_1, EXSTYLE_0 },
69     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_1, EXSTYLE_1 },
70     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_1, EXSTYLE_2 },
71     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_1, EXSTYLE_3 },
72     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_2, EXSTYLE_0 },
73     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_2, EXSTYLE_1 },
74     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_2, EXSTYLE_2 },
75     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_1, STYLE_2, EXSTYLE_3 },
76     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_0, EXSTYLE_0 },
77     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_0, EXSTYLE_1 },
78     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_0, EXSTYLE_2 },
79     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_0, EXSTYLE_3 },
80     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_1, EXSTYLE_0 },
81     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_1, EXSTYLE_1 },
82     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_1, EXSTYLE_2 },
83     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_1, EXSTYLE_3 },
84     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_2, EXSTYLE_0 },
85     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_2, EXSTYLE_1 },
86     { __LINE__, 0, 0, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_2, EXSTYLE_2 },
87     { __LINE__, 0, 1, TYPE_1, STYLE_1, EXSTYLE_2, STYLE_2, EXSTYLE_3 },
88     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_0, EXSTYLE_0 },
89     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_0, EXSTYLE_1 },
90     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_0, EXSTYLE_2 },
91     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_0, EXSTYLE_3 },
92     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_1, EXSTYLE_0 },
93     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_1, EXSTYLE_1 },
94     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_1, EXSTYLE_2 },
95     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_1, EXSTYLE_3 },
96     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_2, EXSTYLE_0 },
97     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_2, EXSTYLE_1 },
98     { __LINE__, 1, 1, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_2, EXSTYLE_2 },
99     { __LINE__, 1, 2, TYPE_1, STYLE_1, EXSTYLE_3, STYLE_2, EXSTYLE_3 },
100     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_0, EXSTYLE_0 },
101     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_0, EXSTYLE_1 },
102     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_0, EXSTYLE_2 },
103     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_0, EXSTYLE_3 },
104     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_1, EXSTYLE_0 },
105     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_1, EXSTYLE_1 },
106     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_1, EXSTYLE_2 },
107     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_1, EXSTYLE_3 },
108     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_2, EXSTYLE_0 },
109     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_2, EXSTYLE_1 },
110     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_2, EXSTYLE_2 },
111     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_0, STYLE_2, EXSTYLE_3 },
112     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_0, EXSTYLE_0 },
113     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_0, EXSTYLE_1 },
114     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_0, EXSTYLE_2 },
115     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_0, EXSTYLE_3 },
116     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_1, EXSTYLE_0 },
117     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_1, EXSTYLE_1 },
118     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_1, EXSTYLE_2 },
119     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_1, EXSTYLE_3 },
120     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_2, EXSTYLE_0 },
121     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_2, EXSTYLE_1 },
122     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_2, EXSTYLE_2 },
123     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_1, STYLE_2, EXSTYLE_3 },
124     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_0, EXSTYLE_0 },
125     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_0, EXSTYLE_1 },
126     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_0, EXSTYLE_2 },
127     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_0, EXSTYLE_3 },
128     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_1, EXSTYLE_0 },
129     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_1, EXSTYLE_1 },
130     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_1, EXSTYLE_2 },
131     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_1, EXSTYLE_3 },
132     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_2, EXSTYLE_0 },
133     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_2, EXSTYLE_1 },
134     { __LINE__, 0, 0, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_2, EXSTYLE_2 },
135     { __LINE__, 0, 1, TYPE_1, STYLE_2, EXSTYLE_2, STYLE_2, EXSTYLE_3 },
136     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_0, EXSTYLE_0 },
137     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_0, EXSTYLE_1 },
138     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_0, EXSTYLE_2 },
139     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_0, EXSTYLE_3 },
140     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_1, EXSTYLE_0 },
141     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_1, EXSTYLE_1 },
142     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_1, EXSTYLE_2 },
143     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_1, EXSTYLE_3 },
144     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_2, EXSTYLE_0 },
145     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_2, EXSTYLE_1 },
146     { __LINE__, 1, 1, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_2, EXSTYLE_2 },
147     { __LINE__, 1, 2, TYPE_1, STYLE_2, EXSTYLE_3, STYLE_2, EXSTYLE_3 },
148 
149     // TYPE_2
150     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_0, EXSTYLE_0 },
151     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_0, EXSTYLE_1 },
152     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_0, EXSTYLE_2 },
153     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_0, EXSTYLE_3 },
154     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_1, EXSTYLE_0 },
155     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_1, EXSTYLE_1 },
156     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_1, EXSTYLE_2 },
157     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_1, EXSTYLE_3 },
158     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_2, EXSTYLE_0 },
159     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_2, EXSTYLE_1 },
160     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_2, EXSTYLE_2 },
161     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_0, STYLE_2, EXSTYLE_3 },
162     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_0, EXSTYLE_0 },
163     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_0, EXSTYLE_1 },
164     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_0, EXSTYLE_2 },
165     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_0, EXSTYLE_3 },
166     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_1, EXSTYLE_0 },
167     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_1, EXSTYLE_1 },
168     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_1, EXSTYLE_2 },
169     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_1, EXSTYLE_3 },
170     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_2, EXSTYLE_0 },
171     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_2, EXSTYLE_1 },
172     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_2, EXSTYLE_2 },
173     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_1, STYLE_2, EXSTYLE_3 },
174     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_0, EXSTYLE_0 },
175     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_0, EXSTYLE_1 },
176     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_0, EXSTYLE_2 },
177     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_0, EXSTYLE_3 },
178     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_1, EXSTYLE_0 },
179     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_1, EXSTYLE_1 },
180     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_1, EXSTYLE_2 },
181     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_1, EXSTYLE_3 },
182     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_2, EXSTYLE_0 },
183     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_2, EXSTYLE_1 },
184     { __LINE__, 0, 0, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_2, EXSTYLE_2 },
185     { __LINE__, 0, 1, TYPE_2, STYLE_1, EXSTYLE_2, STYLE_2, EXSTYLE_3 },
186     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_0, EXSTYLE_0 },
187     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_0, EXSTYLE_1 },
188     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_0, EXSTYLE_2 },
189     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_0, EXSTYLE_3 },
190     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_1, EXSTYLE_0 },
191     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_1, EXSTYLE_1 },
192     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_1, EXSTYLE_2 },
193     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_1, EXSTYLE_3 },
194     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_2, EXSTYLE_0 },
195     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_2, EXSTYLE_1 },
196     { __LINE__, 1, 1, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_2, EXSTYLE_2 },
197     { __LINE__, 1, 2, TYPE_2, STYLE_1, EXSTYLE_3, STYLE_2, EXSTYLE_3 },
198     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_0, EXSTYLE_0 },
199     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_0, EXSTYLE_1 },
200     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_0, EXSTYLE_2 },
201     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_0, EXSTYLE_3 },
202     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_1, EXSTYLE_0 },
203     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_1, EXSTYLE_1 },
204     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_1, EXSTYLE_2 },
205     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_1, EXSTYLE_3 },
206     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_2, EXSTYLE_0 },
207     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_2, EXSTYLE_1 },
208     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_2, EXSTYLE_2 },
209     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_0, STYLE_2, EXSTYLE_3 },
210     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_0, EXSTYLE_0 },
211     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_0, EXSTYLE_1 },
212     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_0, EXSTYLE_2 },
213     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_0, EXSTYLE_3 },
214     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_1, EXSTYLE_0 },
215     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_1, EXSTYLE_1 },
216     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_1, EXSTYLE_2 },
217     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_1, EXSTYLE_3 },
218     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_2, EXSTYLE_0 },
219     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_2, EXSTYLE_1 },
220     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_2, EXSTYLE_2 },
221     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_1, STYLE_2, EXSTYLE_3 },
222     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_0, EXSTYLE_0 },
223     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_0, EXSTYLE_1 },
224     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_0, EXSTYLE_2 },
225     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_0, EXSTYLE_3 },
226     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_1, EXSTYLE_0 },
227     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_1, EXSTYLE_1 },
228     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_1, EXSTYLE_2 },
229     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_1, EXSTYLE_3 },
230     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_2, EXSTYLE_0 },
231     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_2, EXSTYLE_1 },
232     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_2, EXSTYLE_2 },
233     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_2, STYLE_2, EXSTYLE_3 },
234     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_0, EXSTYLE_0 },
235     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_0, EXSTYLE_1 },
236     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_0, EXSTYLE_2 },
237     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_0, EXSTYLE_3 },
238     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_1, EXSTYLE_0 },
239     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_1, EXSTYLE_1 },
240     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_1, EXSTYLE_2 },
241     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_1, EXSTYLE_3 },
242     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_2, EXSTYLE_0 },
243     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_2, EXSTYLE_1 },
244     { __LINE__, 0, 0, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_2, EXSTYLE_2 },
245     { __LINE__, 0, 1, TYPE_2, STYLE_2, EXSTYLE_3, STYLE_2, EXSTYLE_3 },
246 };
247 
248 static HHOOK s_hShellHook = NULL;
249 static UINT s_cCreated = 0;
250 static UINT s_cDestroyed = 0;
251 static WCHAR s_szName[] = L"ReactOS ShellHook testcase";
252 static HWND s_hwndParent = NULL;
253 static HWND s_hwndTarget = NULL;
254 static HWND s_hwndMain = NULL;
255 
256 static HWND
257 DoCreateWindow(HWND hwndParent, DWORD style, DWORD exstyle, BOOL bFullscreen = FALSE)
258 {
259     INT x = CW_USEDEFAULT, y = CW_USEDEFAULT, cx = 300, cy = 100;
260     if (bFullscreen)
261     {
262         x = y = 0;
263         cx = GetSystemMetrics(SM_CXSCREEN);
264         cy = GetSystemMetrics(SM_CYSCREEN);
265     }
266     return CreateWindowExW(exstyle, s_szName, s_szName, style, x, y, cx, cy,
267                            hwndParent, NULL, GetModuleHandleW(NULL), NULL);
268 }
269 
270 static void DoTestEntryPart1(const TEST_ENTRY *pEntry)
271 {
272     ok(!pEntry->bIsChild || pEntry->bHasOwner,
273        "Line %d: bIsChild && !bHasOwner\n", pEntry->lineno);
274 
275     s_hwndParent = NULL;
276     if (pEntry->bIsChild || pEntry->bHasOwner)
277         s_hwndParent = DoCreateWindow(NULL, pEntry->owner_style, pEntry->owner_exstyle);
278 
279     DWORD style = pEntry->style;
280     DWORD exstyle = pEntry->exstyle;
281     if (pEntry->bIsChild)
282         style |= WS_CHILD;
283     else
284         style &= ~WS_CHILD;
285 
286     s_cCreated = s_cDestroyed = 0;
287     s_hwndTarget = DoCreateWindow(s_hwndParent, style, exstyle);
288 }
289 
290 static void DoTestEntryPart2(const TEST_ENTRY *pEntry)
291 {
292     DestroyWindow(s_hwndTarget);
293     s_hwndTarget = NULL;
294 
295     if (pEntry->bIsChild || pEntry->bHasOwner)
296     {
297         DestroyWindow(s_hwndParent);
298         s_hwndParent = NULL;
299     }
300 
301     ok(s_cCreated == pEntry->cCreated,
302        "Line %d: cCreated expected %u but was %u\n",
303        pEntry->lineno, pEntry->cCreated, s_cCreated);
304 
305     ok(s_cDestroyed == pEntry->cDestroyed,
306        "Line %d: cDestroyed expected %u but was %u\n",
307        pEntry->lineno, pEntry->cDestroyed, s_cDestroyed);
308 }
309 
310 static
311 LRESULT CALLBACK
312 ShellProc(
313     INT nCode,
314     WPARAM wParam,
315     LPARAM lParam)
316 {
317     if (nCode < 0)
318         return CallNextHookEx(s_hShellHook, nCode, wParam, lParam);
319 
320     switch (nCode)
321     {
322         case HSHELL_WINDOWCREATED:
323             s_cCreated++;
324             break;
325 
326         case HSHELL_WINDOWDESTROYED:
327             s_cDestroyed++;
328             break;
329     }
330 
331     return CallNextHookEx(s_hShellHook, nCode, wParam, lParam);
332 }
333 
334 static INT_PTR CALLBACK
335 DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
336 {
337 #define ID_TESTSTART 1000
338 #define ID_TESTEND 2000
339     switch (uMsg)
340     {
341         case WM_INITDIALOG:
342             ok_int(s_cCreated, 0);
343             ok_int(s_cDestroyed, 0);
344             PostMessageW(hwnd, WM_COMMAND, ID_TESTSTART, 0);
345             return TRUE;
346 
347         case WM_COMMAND:
348             switch (LOWORD(wParam))
349             {
350                 case IDOK:
351                 case IDCANCEL:
352                     DestroyWindow(hwnd);
353                     break;
354 
355                 default:
356                 {
357                     if (ID_TESTSTART <= LOWORD(wParam) && LOWORD(wParam) < ID_TESTEND)
358                     {
359                         UINT_PTR i = (UINT_PTR)wParam - ID_TESTSTART;
360 
361                         if (i < _countof(s_entries1))
362                         {
363                             DoTestEntryPart1(&s_entries1[i]);
364                             PostMessageW(hwnd, WM_COMMAND, ID_TESTEND + i, 0);
365                         }
366                         else
367                         {
368                             DestroyWindow(hwnd);
369                         }
370                     }
371                     else if (ID_TESTEND <= LOWORD(wParam))
372                     {
373                         UINT_PTR i = (UINT_PTR)wParam - ID_TESTEND;
374 
375                         if (i < _countof(s_entries1))
376                         {
377                             DoTestEntryPart2(&s_entries1[i]);
378                             PostMessageW(hwnd, WM_COMMAND, ID_TESTSTART + i + 1, 0);
379                         }
380                     }
381                 }
382             }
383             break;
384 
385         case WM_DESTROY:
386             PostQuitMessage(0);
387             break;
388     }
389 
390     return 0;
391 }
392 
393 static LRESULT CALLBACK
394 WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
395 {
396     switch (uMsg)
397     {
398         case WM_CREATE:
399             break;
400         default:
401             return DefWindowProcW(hwnd, uMsg, wParam, lParam);
402     }
403     return 0;
404 }
405 
406 START_TEST(ShellHook)
407 {
408     WNDCLASSW wc = { CS_HREDRAW | CS_VREDRAW, WindowProc };
409     wc.hInstance = GetModuleHandleW(NULL);
410     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
411     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
412     wc.hbrBackground = (HBRUSH)(INT_PTR)(COLOR_3DFACE + 1);
413     wc.lpszClassName = s_szName;
414     if (!RegisterClassW(&wc))
415     {
416         skip("RegisterClassW failed\n");
417         return;
418     }
419 
420     s_hShellHook = SetWindowsHookEx(WH_SHELL, ShellProc, NULL, GetCurrentThreadId());
421     if (!s_hShellHook)
422     {
423         skip("!s_hShellHook\n");
424         return;
425     }
426 
427     s_hwndMain = CreateDialogW(GetModuleHandleW(NULL), L"ShellHook", NULL, DialogProc);
428     if (!s_hShellHook)
429     {
430         skip("!s_hwndMain\n");
431         UnhookWindowsHookEx(s_hShellHook);
432         return;
433     }
434 
435     ShowWindow(s_hwndMain, SW_SHOWNOACTIVATE);
436     UpdateWindow(s_hwndMain);
437 
438     MSG msg;
439     while (GetMessageW(&msg, NULL, 0, 0))
440     {
441         if (IsDialogMessageW(s_hwndMain, &msg))
442             continue;
443 
444         TranslateMessage(&msg);
445         DispatchMessageW(&msg);
446     }
447 
448     UnhookWindowsHookEx(s_hShellHook);
449 }
450