1 /* Unit test suite for resources.
3 * Copyright 2004 Ferenc Wagner
4 * Copyright 2003, 2004 Mike McCormack
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.
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.
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
24 #include "wine/test.h"
26 static UINT (WINAPI
*pPrivateExtractIconsA
)(LPCTSTR
, int, int, int, HICON
*, UINT
*, UINT
, UINT
) = NULL
;
28 static void init_function_pointers(void)
30 HMODULE hmod
= GetModuleHandleA("user32.dll");
31 pPrivateExtractIconsA
= (void*)GetProcAddress(hmod
, "PrivateExtractIconsA");
34 static void test_LoadStringW(void)
36 HINSTANCE hInst
= GetModuleHandle(NULL
);
37 WCHAR copiedstringw
[128], returnedstringw
[128], *resourcepointer
= NULL
;
38 char copiedstring
[128], returnedstring
[128];
39 int length1
, length2
, retvalue
;
41 /* Check that the string which is returned by LoadStringW matches
42 the string at the pointer returned by LoadStringW when called with buflen = 0 */
43 SetLastError(0xdeadbeef);
44 length1
= LoadStringW(hInst
, 2, (WCHAR
*) &resourcepointer
, 0); /* get pointer to resource. */
45 if (!length1
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
47 win_skip( "LoadStringW not implemented\n" );
50 length2
= LoadStringW(hInst
, 2, returnedstringw
, sizeof(returnedstringw
) /sizeof(WCHAR
)); /* get resource string */
51 ok(length2
> 0, "LoadStringW failed to load resource 2, ret %d, err %d\n", length2
, GetLastError());
52 ok(length1
== length2
, "LoadStringW returned different values dependent on buflen. ret1 %d, ret2 %d\n",
54 ok(length1
> 0 && resourcepointer
!= NULL
, "LoadStringW failed to get pointer to resource 2, ret %d, err %d\n",
55 length1
, GetLastError());
57 /* Copy the resource since it is not '\0' terminated, and add '\0' to the end */
58 if(resourcepointer
!= NULL
) /* Check that the resource pointer was loaded to avoid access violation */
60 memcpy(copiedstringw
, resourcepointer
, length1
* sizeof(WCHAR
));
61 copiedstringw
[length1
] = '\0';
62 /* check that strings match */
63 WideCharToMultiByte( CP_ACP
, 0, returnedstringw
, -1, returnedstring
, 128, NULL
, NULL
);
64 WideCharToMultiByte( CP_ACP
, 0, copiedstringw
, -1, copiedstring
, 128, NULL
, NULL
);
65 ok(!memcmp(copiedstringw
, returnedstringw
, (length2
+ 1)*sizeof(WCHAR
)),
66 "strings don't match: returnedstring = %s, copiedstring = %s\n", returnedstring
, copiedstring
);
69 /* check that calling LoadStringW with buffer = NULL returns zero */
70 retvalue
= LoadStringW(hInst
, 2, NULL
, 0);
71 ok(!retvalue
, "LoadStringW returned a non-zero value when called with buffer = NULL, retvalue = %d\n", retvalue
);
72 /* check again, with a different buflen value, that calling LoadStringW with buffer = NULL returns zero */
73 retvalue
= LoadStringW(hInst
, 2, NULL
, 128);
74 ok(!retvalue
, "LoadStringW returned a non-zero value when called with buffer = NULL, retvalue = %d\n", retvalue
);
77 static void test_LoadStringA (void)
79 HINSTANCE hInst
= GetModuleHandle (NULL
);
80 static const char str
[] = "String resource"; /* same in resource.rc */
84 unsigned int expected
;
86 struct string_test tests
[] = {{sizeof buf
, sizeof str
- 1},
87 {sizeof str
, sizeof str
- 1},
88 {sizeof str
- 1, sizeof str
- 2}};
92 assert (sizeof str
< sizeof buf
);
93 for (i
= 0; i
< sizeof tests
/ sizeof tests
[0]; i
++) {
94 const unsigned int bufsiz
= tests
[i
].bufsiz
;
95 const unsigned int expected
= tests
[i
].expected
;
96 const int len
= LoadStringA (hInst
, 0, buf
, bufsiz
);
98 ok (len
== expected
, "bufsiz=%d: got %d, expected %d\n",
99 bufsiz
, len
, expected
);
100 if (len
!= expected
) continue;
101 ok (!memcmp (buf
, str
, len
),
102 "bufsiz=%d: got '%s', expected '%.*s'\n",
103 bufsiz
, buf
, len
, str
);
104 ok (buf
[len
] == 0, "bufsiz=%d: NUL termination missing\n",
108 ret
= LoadStringA(hInst
, 1, buf
, sizeof(buf
) );
109 ok( ret
> 0, "LoadString failed: ret %d err %d\n", ret
, GetLastError());
110 ok( LoadStringA( hInst
, MAKELONG( 1, 0x8000 ), buf
, sizeof(buf
)) == ret
,
111 "LoadString failed: ret %d err %d\n", ret
, GetLastError());
112 ok( LoadStringA( hInst
, MAKELONG( 1, 0xffff ), buf
, sizeof(buf
)) == ret
,
113 "LoadString failed: ret %d err %d\n", ret
, GetLastError());
115 ret
= LoadStringA(hInst
, 65534, buf
, sizeof(buf
) );
116 ok( ret
> 0, "LoadString failed: ret %d err %d\n", ret
, GetLastError());
117 ok( LoadStringA( hInst
, MAKELONG( 65534, 0x8000 ), buf
, sizeof(buf
)) == ret
,
118 "LoadString failed: ret %d err %d\n", ret
, GetLastError());
119 ok( LoadStringA( hInst
, MAKELONG( 65534, 0xffff ), buf
, sizeof(buf
)) == ret
,
120 "LoadString failed: ret %d err %d\n", ret
, GetLastError());
122 ret
= LoadStringA(hInst
, 0, buf
, 0);
123 ok( ret
== -1 || broken(ret
== 0),
124 "LoadStringA did not return -1 when called with buflen = 0, got %d, err %d\n",
125 ret
, GetLastError());
128 static void test_accel1(void)
134 /* now create our own valid accelerator table */
138 ac
[n
++].fVirt
= FVIRTKEY
| FNOINVERT
;
142 ac
[n
++].fVirt
= FNOINVERT
;
148 hAccel
= CreateAcceleratorTable( &ac
[0], n
);
149 ok( hAccel
!= NULL
, "create accelerator table\n");
151 r
= DestroyAcceleratorTable( hAccel
);
152 ok( r
, "destroy accelerator table\n");
154 /* now try create an invalid one */
158 ac
[n
++].fVirt
= FVIRTKEY
| FNOINVERT
;
162 ac
[n
++].fVirt
= (SHORT
) 0xffff;
166 ac
[n
++].fVirt
= (SHORT
) 0xfff0;
170 ac
[n
++].fVirt
= (SHORT
) 0x0000;
174 ac
[n
++].fVirt
= (SHORT
) 0x0001;
176 hAccel
= CreateAcceleratorTable( &ac
[0], n
);
177 ok( hAccel
!= NULL
, "create accelerator table\n");
179 r
= CopyAcceleratorTable( hAccel
, NULL
, 0 );
180 ok( r
== n
, "two entries in table\n");
182 r
= CopyAcceleratorTable( hAccel
, &ac
[0], r
);
183 ok( r
== n
, "still should be two entries in table\n");
186 ok( ac
[n
].cmd
== 1000, "cmd 0 not preserved\n");
187 ok( ac
[n
].key
== 'A', "key 0 not preserved\n");
188 ok( ac
[n
].fVirt
== (FVIRTKEY
| FNOINVERT
), "fVirt 0 not preserved\n");
191 ok( ac
[n
].cmd
== 0xffff, "cmd 1 not preserved\n");
192 ok( ac
[n
].key
== 0xffff, "key 1 not preserved\n");
193 ok( ac
[n
].fVirt
== 0x007f, "fVirt 1 not changed\n");
196 ok( ac
[n
].cmd
== 0xfff0, "cmd 2 not preserved\n");
197 ok( ac
[n
].key
== 0x00ff, "key 2 not preserved\n");
198 ok( ac
[n
].fVirt
== 0x0070, "fVirt 2 not changed\n");
201 ok( ac
[n
].cmd
== 0xfff0, "cmd 3 not preserved\n");
202 ok( ac
[n
].key
== 0x00ff, "key 3 not preserved\n");
203 ok( ac
[n
].fVirt
== 0x0000, "fVirt 3 not changed\n");
206 ok( ac
[n
].cmd
== 0xfff0, "cmd 4 not preserved\n");
207 ok( ac
[n
].key
== 0xffff, "key 4 not preserved\n");
208 ok( ac
[n
].fVirt
== 0x0001, "fVirt 4 not changed\n");
210 r
= DestroyAcceleratorTable( hAccel
);
211 ok( r
, "destroy accelerator table\n");
213 hAccel
= CreateAcceleratorTable( &ac
[0], 0 );
214 ok( !hAccel
, "zero elements should fail\n");
216 /* these will on crash win2k
217 hAccel = CreateAcceleratorTable( NULL, 1 );
218 hAccel = CreateAcceleratorTable( &ac[0], -1 );
223 * memcmp on the tables works in Windows, but does not work in wine, as
224 * there is an extra undefined and unused byte between fVirt and the key
226 static void test_accel2(void)
241 * hac = CreateAcceleratorTable( NULL, 1 );
244 /* try a zero count */
245 hac
= CreateAcceleratorTable( &ac
[0], 0 );
246 ok( !hac
, "fail\n");
247 ok( !DestroyAcceleratorTable( hac
), "destroy failed\n");
249 /* creating one accelerator should work */
250 hac
= CreateAcceleratorTable( &ac
[0], 1 );
251 ok( hac
!= NULL
, "fail\n");
252 ok( 1 == CopyAcceleratorTable( hac
, out
, 1 ), "copy failed\n");
253 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
255 /* how about two of the same type? */
256 hac
= CreateAcceleratorTable( &ac
[0], 2);
257 ok( hac
!= NULL
, "fail\n");
258 ok( 2 == CopyAcceleratorTable( hac
, NULL
, 100 ), "copy null failed\n");
259 ok( 2 == CopyAcceleratorTable( hac
, NULL
, 0 ), "copy null failed\n");
260 ok( 2 == CopyAcceleratorTable( hac
, NULL
, 1 ), "copy null failed\n");
261 ok( 1 == CopyAcceleratorTable( hac
, out
, 1 ), "copy 1 failed\n");
262 ok( 2 == CopyAcceleratorTable( hac
, out
, 2 ), "copy 2 failed\n");
263 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
264 /* ok( !memcmp( ac, out, sizeof ac ), "tables different\n"); */
266 /* how about two of the same type with a non-zero key? */
269 hac
= CreateAcceleratorTable( &ac
[0], 2);
270 ok( hac
!= NULL
, "fail\n");
271 ok( 2 == CopyAcceleratorTable( hac
, out
, 2 ), "copy 2 failed\n");
272 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
273 /* ok( !memcmp( ac, out, sizeof ac ), "tables different\n"); */
275 /* how about two of the same type with a non-zero virtual key? */
276 ac
[0].fVirt
= FVIRTKEY
;
278 ac
[1].fVirt
= FVIRTKEY
;
280 hac
= CreateAcceleratorTable( &ac
[0], 2);
281 ok( hac
!= NULL
, "fail\n");
282 ok( 2 == CopyAcceleratorTable( hac
, out
, 2 ), "copy 2 failed\n");
283 /* ok( !memcmp( ac, out, sizeof ac ), "tables different\n"); */
284 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
286 /* how virtual key codes */
287 ac
[0].fVirt
= FVIRTKEY
;
288 hac
= CreateAcceleratorTable( &ac
[0], 1);
289 ok( hac
!= NULL
, "fail\n");
290 ok( 1 == CopyAcceleratorTable( hac
, out
, 2 ), "copy 2 failed\n");
291 /* ok( !memcmp( ac, out, sizeof ac/2 ), "tables different\n"); */
292 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
294 /* how turning on all bits? */
298 hac
= CreateAcceleratorTable( &ac
[0], 1);
299 ok( hac
!= NULL
, "fail\n");
300 ok( 1 == CopyAcceleratorTable( hac
, out
, 1 ), "copy 1 failed\n");
301 /* ok( memcmp( ac, out, sizeof ac/2 ), "tables not different\n"); */
302 ok( out
[0].cmd
== ac
[0].cmd
, "cmd modified\n");
303 ok( out
[0].fVirt
== (ac
[0].fVirt
&0x7f), "fVirt not modified\n");
304 ok( out
[0].key
== ac
[0].key
, "key modified\n");
305 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
307 /* how turning on all bits? */
308 memset( ac
, 0xff, sizeof ac
);
309 hac
= CreateAcceleratorTable( &ac
[0], 2);
310 ok( hac
!= NULL
, "fail\n");
311 ok( 2 == CopyAcceleratorTable( hac
, out
, 2 ), "copy 2 failed\n");
312 /* ok( memcmp( ac, out, sizeof ac ), "tables not different\n"); */
313 ok( out
[0].cmd
== ac
[0].cmd
, "cmd modified\n");
314 ok( out
[0].fVirt
== (ac
[0].fVirt
&0x7f), "fVirt not modified\n");
315 ok( out
[0].key
== ac
[0].key
, "key modified\n");
316 ok( out
[1].cmd
== ac
[1].cmd
, "cmd modified\n");
317 ok( out
[1].fVirt
== (ac
[1].fVirt
&0x7f), "fVirt not modified\n");
318 ok( out
[1].key
== ac
[1].key
, "key modified\n");
319 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
322 static void test_PrivateExtractIcons(void) {
323 CONST CHAR szShell32Dll
[] = "shell32.dll";
326 UINT cIcons
, cIcons2
;
328 if (!pPrivateExtractIconsA
) return;
330 cIcons
= pPrivateExtractIconsA(szShell32Dll
, 0, 16, 16, NULL
, NULL
, 0, 0);
331 cIcons2
= pPrivateExtractIconsA(szShell32Dll
, 4, MAKELONG(32,16), MAKELONG(32,16),
333 ok((cIcons
== cIcons2
) && (cIcons
> 0),
334 "Icon count should be independent of requested icon sizes and base icon index! "
335 "(cIcons=%d, cIcons2=%d)\n", cIcons
, cIcons2
);
337 cIcons
= pPrivateExtractIconsA(szShell32Dll
, 0, 16, 16, ahIcon
, aIconId
, 0, 0);
338 ok(cIcons
== 0, "Zero icons requested, got cIcons=%d\n", cIcons
);
340 cIcons
= pPrivateExtractIconsA(szShell32Dll
, 0, 16, 16, ahIcon
, aIconId
, 3, 0);
341 ok(cIcons
== 3, "Three icons requested got cIcons=%d\n", cIcons
);
343 cIcons
= pPrivateExtractIconsA(szShell32Dll
, 0, MAKELONG(32,16), MAKELONG(32,16),
344 ahIcon
, aIconId
, 3, 0);
345 ok(cIcons
== 4, "Three icons requested, four expected, got cIcons=%d\n", cIcons
);
348 static void test_LoadImage(void)
353 bmp
= LoadBitmapA(GetModuleHandle(NULL
), MAKEINTRESOURCE(100));
354 ok(bmp
!= NULL
, "Could not load a bitmap resource\n");
355 if (bmp
) DeleteObject(bmp
);
357 hres
= FindResource(GetModuleHandle(NULL
), "#100", RT_BITMAP
);
358 ok(hres
!= NULL
, "Could not find a bitmap resource with a numeric string\n");
360 bmp
= LoadBitmapA(GetModuleHandle(NULL
), "#100");
361 ok(bmp
!= NULL
, "Could not load a bitmap resource with a numeric string\n");
362 if (bmp
) DeleteObject(bmp
);
367 init_function_pointers();
372 test_PrivateExtractIcons();