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. */
47 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
48 win_skip( "LoadStringW not implemented\n" );
50 win_skip( "LoadStringW does not return a pointer to the resource\n" );
53 length2
= LoadStringW(hInst
, 2, returnedstringw
, sizeof(returnedstringw
) /sizeof(WCHAR
)); /* get resource string */
54 ok(length2
> 0, "LoadStringW failed to load resource 2, ret %d, err %d\n", length2
, GetLastError());
55 ok(length1
== length2
, "LoadStringW returned different values dependent on buflen. ret1 %d, ret2 %d\n",
57 ok(length1
> 0 && resourcepointer
!= NULL
, "LoadStringW failed to get pointer to resource 2, ret %d, err %d\n",
58 length1
, GetLastError());
60 /* Copy the resource since it is not '\0' terminated, and add '\0' to the end */
61 if(resourcepointer
!= NULL
) /* Check that the resource pointer was loaded to avoid access violation */
63 memcpy(copiedstringw
, resourcepointer
, length1
* sizeof(WCHAR
));
64 copiedstringw
[length1
] = '\0';
65 /* check that strings match */
66 WideCharToMultiByte( CP_ACP
, 0, returnedstringw
, -1, returnedstring
, 128, NULL
, NULL
);
67 WideCharToMultiByte( CP_ACP
, 0, copiedstringw
, -1, copiedstring
, 128, NULL
, NULL
);
68 ok(!memcmp(copiedstringw
, returnedstringw
, (length2
+ 1)*sizeof(WCHAR
)),
69 "strings don't match: returnedstring = %s, copiedstring = %s\n", returnedstring
, copiedstring
);
72 /* check that calling LoadStringW with buffer = NULL returns zero */
73 retvalue
= LoadStringW(hInst
, 2, NULL
, 0);
74 ok(!retvalue
, "LoadStringW returned a non-zero value when called with buffer = NULL, retvalue = %d\n", retvalue
);
75 /* check again, with a different buflen value, that calling LoadStringW with buffer = NULL returns zero */
76 retvalue
= LoadStringW(hInst
, 2, NULL
, 128);
77 ok(!retvalue
, "LoadStringW returned a non-zero value when called with buffer = NULL, retvalue = %d\n", retvalue
);
80 static void test_LoadStringA (void)
82 HINSTANCE hInst
= GetModuleHandle (NULL
);
83 static const char str
[] = "String resource"; /* same in resource.rc */
87 unsigned int expected
;
89 struct string_test tests
[] = {{sizeof buf
, sizeof str
- 1},
90 {sizeof str
, sizeof str
- 1},
91 {sizeof str
- 1, sizeof str
- 2}};
95 assert (sizeof str
< sizeof buf
);
96 for (i
= 0; i
< sizeof tests
/ sizeof tests
[0]; i
++) {
97 const unsigned int bufsiz
= tests
[i
].bufsiz
;
98 const unsigned int expected
= tests
[i
].expected
;
99 const int len
= LoadStringA (hInst
, 0, buf
, bufsiz
);
101 ok (len
== expected
, "bufsiz=%d: got %d, expected %d\n",
102 bufsiz
, len
, expected
);
103 if (len
!= expected
) continue;
104 ok (!memcmp (buf
, str
, len
),
105 "bufsiz=%d: got '%s', expected '%.*s'\n",
106 bufsiz
, buf
, len
, str
);
107 ok (buf
[len
] == 0, "bufsiz=%d: NUL termination missing\n",
111 ret
= LoadStringA(hInst
, 1, buf
, sizeof(buf
) );
112 ok( ret
> 0, "LoadString failed: ret %d err %d\n", ret
, GetLastError());
113 ok( LoadStringA( hInst
, MAKELONG( 1, 0x8000 ), buf
, sizeof(buf
)) == ret
,
114 "LoadString failed: ret %d err %d\n", ret
, GetLastError());
115 ok( LoadStringA( hInst
, MAKELONG( 1, 0xffff ), buf
, sizeof(buf
)) == ret
,
116 "LoadString failed: ret %d err %d\n", ret
, GetLastError());
118 ret
= LoadStringA(hInst
, 65534, buf
, sizeof(buf
) );
119 ok( ret
> 0, "LoadString failed: ret %d err %d\n", ret
, GetLastError());
120 ok( LoadStringA( hInst
, MAKELONG( 65534, 0x8000 ), buf
, sizeof(buf
)) == ret
,
121 "LoadString failed: ret %d err %d\n", ret
, GetLastError());
122 ok( LoadStringA( hInst
, MAKELONG( 65534, 0xffff ), buf
, sizeof(buf
)) == ret
,
123 "LoadString failed: ret %d err %d\n", ret
, GetLastError());
125 ret
= LoadStringA(hInst
, 0, buf
, 0);
126 ok( ret
== -1 || broken(ret
== 0),
127 "LoadStringA did not return -1 when called with buflen = 0, got %d, err %d\n",
128 ret
, GetLastError());
131 static void test_accel1(void)
137 /* now create our own valid accelerator table */
141 ac
[n
++].fVirt
= FVIRTKEY
| FNOINVERT
;
145 ac
[n
++].fVirt
= FNOINVERT
;
151 hAccel
= CreateAcceleratorTable( &ac
[0], n
);
152 ok( hAccel
!= NULL
, "create accelerator table\n");
154 r
= DestroyAcceleratorTable( hAccel
);
155 ok( r
, "destroy accelerator table\n");
157 /* now try create an invalid one */
161 ac
[n
++].fVirt
= FVIRTKEY
| FNOINVERT
;
165 ac
[n
++].fVirt
= (SHORT
) 0xffff;
169 ac
[n
++].fVirt
= (SHORT
) 0xfff0;
173 ac
[n
++].fVirt
= (SHORT
) 0x0000;
177 ac
[n
++].fVirt
= (SHORT
) 0x0001;
179 hAccel
= CreateAcceleratorTable( &ac
[0], n
);
180 ok( hAccel
!= NULL
, "create accelerator table\n");
182 r
= CopyAcceleratorTable( hAccel
, NULL
, 0 );
183 ok( r
== n
, "two entries in table\n");
185 r
= CopyAcceleratorTable( hAccel
, &ac
[0], r
);
186 ok( r
== n
, "still should be two entries in table\n");
189 ok( ac
[n
].cmd
== 1000, "cmd 0 not preserved\n");
190 ok( ac
[n
].key
== 'A', "key 0 not preserved\n");
191 ok( ac
[n
].fVirt
== (FVIRTKEY
| FNOINVERT
), "fVirt 0 not preserved\n");
194 ok( ac
[n
].cmd
== 0xffff, "cmd 1 not preserved\n");
195 ok( ac
[n
].key
== 0xffff, "key 1 not preserved\n");
196 ok( ac
[n
].fVirt
== 0x007f, "fVirt 1 not changed\n");
199 ok( ac
[n
].cmd
== 0xfff0, "cmd 2 not preserved\n");
200 ok( ac
[n
].key
== 0x00ff, "key 2 not preserved\n");
201 ok( ac
[n
].fVirt
== 0x0070, "fVirt 2 not changed\n");
204 ok( ac
[n
].cmd
== 0xfff0, "cmd 3 not preserved\n");
205 ok( ac
[n
].key
== 0x00ff, "key 3 not preserved\n");
206 ok( ac
[n
].fVirt
== 0x0000, "fVirt 3 not changed\n");
209 ok( ac
[n
].cmd
== 0xfff0, "cmd 4 not preserved\n");
210 ok( ac
[n
].key
== 0xffff, "key 4 not preserved\n");
211 ok( ac
[n
].fVirt
== 0x0001, "fVirt 4 not changed\n");
213 r
= DestroyAcceleratorTable( hAccel
);
214 ok( r
, "destroy accelerator table\n");
216 hAccel
= CreateAcceleratorTable( &ac
[0], 0 );
217 ok( !hAccel
, "zero elements should fail\n");
219 /* these will on crash win2k
220 hAccel = CreateAcceleratorTable( NULL, 1 );
221 hAccel = CreateAcceleratorTable( &ac[0], -1 );
226 * memcmp on the tables works in Windows, but does not work in wine, as
227 * there is an extra undefined and unused byte between fVirt and the key
229 static void test_accel2(void)
244 * hac = CreateAcceleratorTable( NULL, 1 );
247 /* try a zero count */
248 hac
= CreateAcceleratorTable( &ac
[0], 0 );
249 ok( !hac
, "fail\n");
250 ok( !DestroyAcceleratorTable( hac
), "destroy failed\n");
252 /* creating one accelerator should work */
253 hac
= CreateAcceleratorTable( &ac
[0], 1 );
254 ok( hac
!= NULL
, "fail\n");
255 ok( 1 == CopyAcceleratorTable( hac
, out
, 1 ), "copy failed\n");
256 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
258 /* how about two of the same type? */
259 hac
= CreateAcceleratorTable( &ac
[0], 2);
260 ok( hac
!= NULL
, "fail\n");
261 ok( 2 == CopyAcceleratorTable( hac
, NULL
, 100 ), "copy null failed\n");
262 ok( 2 == CopyAcceleratorTable( hac
, NULL
, 0 ), "copy null failed\n");
263 ok( 2 == CopyAcceleratorTable( hac
, NULL
, 1 ), "copy null failed\n");
264 ok( 1 == CopyAcceleratorTable( hac
, out
, 1 ), "copy 1 failed\n");
265 ok( 2 == CopyAcceleratorTable( hac
, out
, 2 ), "copy 2 failed\n");
266 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
267 /* ok( !memcmp( ac, out, sizeof ac ), "tables different\n"); */
269 /* how about two of the same type with a non-zero key? */
272 hac
= CreateAcceleratorTable( &ac
[0], 2);
273 ok( hac
!= NULL
, "fail\n");
274 ok( 2 == CopyAcceleratorTable( hac
, out
, 2 ), "copy 2 failed\n");
275 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
276 /* ok( !memcmp( ac, out, sizeof ac ), "tables different\n"); */
278 /* how about two of the same type with a non-zero virtual key? */
279 ac
[0].fVirt
= FVIRTKEY
;
281 ac
[1].fVirt
= FVIRTKEY
;
283 hac
= CreateAcceleratorTable( &ac
[0], 2);
284 ok( hac
!= NULL
, "fail\n");
285 ok( 2 == CopyAcceleratorTable( hac
, out
, 2 ), "copy 2 failed\n");
286 /* ok( !memcmp( ac, out, sizeof ac ), "tables different\n"); */
287 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
289 /* how virtual key codes */
290 ac
[0].fVirt
= FVIRTKEY
;
291 hac
= CreateAcceleratorTable( &ac
[0], 1);
292 ok( hac
!= NULL
, "fail\n");
293 ok( 1 == CopyAcceleratorTable( hac
, out
, 2 ), "copy 2 failed\n");
294 /* ok( !memcmp( ac, out, sizeof ac/2 ), "tables different\n"); */
295 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
297 /* how turning on all bits? */
301 hac
= CreateAcceleratorTable( &ac
[0], 1);
302 ok( hac
!= NULL
, "fail\n");
303 ok( 1 == CopyAcceleratorTable( hac
, out
, 1 ), "copy 1 failed\n");
304 /* ok( memcmp( ac, out, sizeof ac/2 ), "tables not different\n"); */
305 ok( out
[0].cmd
== ac
[0].cmd
, "cmd modified\n");
306 ok( out
[0].fVirt
== (ac
[0].fVirt
&0x7f), "fVirt not modified\n");
307 ok( out
[0].key
== ac
[0].key
, "key modified\n");
308 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
310 /* how turning on all bits? */
311 memset( ac
, 0xff, sizeof ac
);
312 hac
= CreateAcceleratorTable( &ac
[0], 2);
313 ok( hac
!= NULL
, "fail\n");
314 ok( 2 == CopyAcceleratorTable( hac
, out
, 2 ), "copy 2 failed\n");
315 /* ok( memcmp( ac, out, sizeof ac ), "tables not different\n"); */
316 ok( out
[0].cmd
== ac
[0].cmd
, "cmd modified\n");
317 ok( out
[0].fVirt
== (ac
[0].fVirt
&0x7f), "fVirt not modified\n");
318 ok( out
[0].key
== ac
[0].key
, "key modified\n");
319 ok( out
[1].cmd
== ac
[1].cmd
, "cmd modified\n");
320 ok( out
[1].fVirt
== (ac
[1].fVirt
&0x7f), "fVirt not modified\n");
321 ok( out
[1].key
== ac
[1].key
, "key modified\n");
322 ok( DestroyAcceleratorTable( hac
), "destroy failed\n");
325 static void test_PrivateExtractIcons(void) {
326 CONST CHAR szShell32Dll
[] = "shell32.dll";
329 UINT cIcons
, cIcons2
;
331 if (!pPrivateExtractIconsA
) return;
333 cIcons
= pPrivateExtractIconsA(szShell32Dll
, 0, 16, 16, NULL
, NULL
, 0, 0);
334 cIcons2
= pPrivateExtractIconsA(szShell32Dll
, 4, MAKELONG(32,16), MAKELONG(32,16),
336 ok((cIcons
== cIcons2
) && (cIcons
> 0),
337 "Icon count should be independent of requested icon sizes and base icon index! "
338 "(cIcons=%d, cIcons2=%d)\n", cIcons
, cIcons2
);
340 cIcons
= pPrivateExtractIconsA(szShell32Dll
, 0, 16, 16, ahIcon
, aIconId
, 0, 0);
341 ok(cIcons
== 0, "Zero icons requested, got cIcons=%d\n", cIcons
);
343 cIcons
= pPrivateExtractIconsA(szShell32Dll
, 0, 16, 16, ahIcon
, aIconId
, 3, 0);
344 ok(cIcons
== 3, "Three icons requested got cIcons=%d\n", cIcons
);
346 cIcons
= pPrivateExtractIconsA(szShell32Dll
, 0, MAKELONG(32,16), MAKELONG(32,16),
347 ahIcon
, aIconId
, 3, 0);
348 ok(cIcons
== 4, "Three icons requested, four expected, got cIcons=%d\n", cIcons
);
351 static void test_LoadImage(void)
356 bmp
= LoadBitmapA(GetModuleHandle(NULL
), MAKEINTRESOURCE(100));
357 ok(bmp
!= NULL
, "Could not load a bitmap resource\n");
358 if (bmp
) DeleteObject(bmp
);
360 hres
= FindResource(GetModuleHandle(NULL
), "#100", RT_BITMAP
);
361 ok(hres
!= NULL
, "Could not find a bitmap resource with a numeric string\n");
363 bmp
= LoadBitmapA(GetModuleHandle(NULL
), "#100");
364 ok(bmp
!= NULL
, "Could not load a bitmap resource with a numeric string\n");
365 if (bmp
) DeleteObject(bmp
);
370 init_function_pointers();
375 test_PrivateExtractIcons();