2 * OLEPICTURE test program
4 * Copyright 2005 Marcus Meissner
5 * Copyright 2012 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #define NONAMELESSUNION
33 #include "wine/test.h"
47 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
49 #define ole_expect(expr, expect) { \
51 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
54 #define ole_check(expr) ole_expect(expr, S_OK);
56 static HMODULE hOleaut32
;
58 static HRESULT (WINAPI
*pOleLoadPicture
)(LPSTREAM
,LONG
,BOOL
,REFIID
,LPVOID
*);
59 static HRESULT (WINAPI
*pOleLoadPictureEx
)(LPSTREAM
,LONG
,BOOL
,REFIID
,DWORD
,DWORD
,DWORD
,LPVOID
*);
61 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
64 static const unsigned char gifimage
[35] = {
65 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
66 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
71 static const unsigned char jpgimage
[285] = {
72 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
73 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
74 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
75 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
76 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
77 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
78 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
79 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
80 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
81 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
82 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
83 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
84 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
85 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
86 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
87 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
88 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
89 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
93 static const unsigned char pngimage
[285] = {
94 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
95 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
96 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
97 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
98 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
99 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
100 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
103 /* 1bpp BI_RGB 1x1 pixel bmp */
104 static const unsigned char bmpimage
[66] = {
105 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
106 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
107 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
108 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
112 /* 8bpp BI_RLE8 1x1 pixel bmp */
113 static const unsigned char bmpimage_rle8
[] = {
114 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
115 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00,
116 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
117 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x01,
122 static const unsigned char gif4pixel
[42] = {
123 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
124 0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
125 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
128 /* APM with an empty metafile with some padding zeros - looks like under Window the
129 * metafile data should be at least 20 bytes */
130 static const unsigned char apmdata
[] = {
131 0xd7,0xcd,0xc6,0x9a, 0x00,0x00,0x00,0x00, 0x00,0x00,0xee,0x02, 0xb1,0x03,0xa0,0x05,
132 0x00,0x00,0x00,0x00, 0xee,0x53,0x01,0x00, 0x09,0x00,0x00,0x03, 0x13,0x00,0x00,0x00,
133 0x01,0x00,0x05,0x00, 0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
134 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
137 /* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
138 static const unsigned char metafile
[] = {
139 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
142 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
143 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
144 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
148 /* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
149 static const unsigned char enhmetafile
[] = {
150 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
155 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
156 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
157 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
160 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
163 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
164 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
165 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
167 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
169 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
170 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
173 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
174 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
175 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
176 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
177 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
178 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
180 0x14, 0x00, 0x00, 0x00
183 static HBITMAP stock_bm
;
185 static HDC
create_render_dc( void )
187 HDC dc
= CreateCompatibleDC( NULL
);
188 BITMAPINFO info
= {{sizeof(info
.bmiHeader
), 100, 100, 1, 32, BI_RGB
}};
190 HBITMAP dib
= CreateDIBSection( NULL
, &info
, DIB_RGB_COLORS
, &bits
, NULL
, 0 );
192 stock_bm
= SelectObject( dc
, dib
);
196 static void delete_render_dc( HDC dc
)
198 HBITMAP dib
= SelectObject( dc
, stock_bm
);
203 typedef struct NoStatStreamImpl
205 IStream IStream_iface
;
208 HGLOBAL supportHandle
;
209 ULARGE_INTEGER streamSize
;
210 ULARGE_INTEGER currentPosition
;
213 static IStream
* NoStatStream_Construct(HGLOBAL hGlobal
);
216 test_pic_with_stream(LPSTREAM stream
, unsigned int imgsize
)
218 IPicture
* pic
= NULL
;
221 OLE_HANDLE handle
, hPal
;
222 OLE_XSIZE_HIMETRIC width
;
223 OLE_YSIZE_HIMETRIC height
;
229 hres
= pOleLoadPicture(stream
, imgsize
, TRUE
, &IID_IPicture
, &pvObj
);
232 ok(hres
== S_OK
,"OLP (NULL,..) does not return 0, but 0x%08x\n",hres
);
233 ok(pic
!= NULL
,"OLP (NULL,..) returns NULL, instead of !NULL\n");
238 hres
= IPicture_QueryInterface (pic
, &IID_IPicture
, &pvObj
);
240 ok(hres
== S_OK
,"IPicture_QI does not return S_OK, but 0x%08x\n", hres
);
241 ok(pvObj
!= NULL
,"IPicture_QI does return NULL, instead of a ptr\n");
243 IPicture_Release ((IPicture
*)pvObj
);
246 hres
= IPicture_get_Handle (pic
, &handle
);
247 ok(hres
== S_OK
,"IPicture_get_Handle does not return S_OK, but 0x%08x\n", hres
);
248 ok(handle
!= 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
253 GetObjectA(UlongToHandle(handle
), sizeof(BITMAP
), &bmp
);
254 ok(bmp
.bmBits
!= 0, "not a dib\n");
258 hres
= IPicture_get_Width (pic
, &width
);
259 ok(hres
== S_OK
,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres
);
260 ok(width
!= 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
263 hres
= IPicture_get_Height (pic
, &height
);
264 ok(hres
== S_OK
,"IPicture_get_Height does not return S_OK, but 0x%08x\n", hres
);
265 ok(height
!= 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
268 hres
= IPicture_get_Type (pic
, &type
);
269 ok(hres
== S_OK
,"IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
270 ok(type
== PICTYPE_BITMAP
, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type
, PICTYPE_BITMAP
);
273 hres
= IPicture_get_Attributes (pic
, &attr
);
274 ok(hres
== S_OK
,"IPicture_get_Attributes does not return S_OK, but 0x%08x\n", hres
);
275 ok(attr
== 0, "IPicture_get_Attributes returns %d, but it should be 0.\n", attr
);
278 hres
= IPicture_get_hPal (pic
, &hPal
);
279 ok(hres
== S_OK
,"IPicture_get_hPal does not return S_OK, but 0x%08x\n", hres
);
280 /* a single pixel b/w image has no palette */
281 ok(hPal
== 0, "IPicture_get_hPal returns %d, but it should be 0.\n", hPal
);
283 res
= IPicture_Release (pic
);
284 ok (res
== 0, "refcount after release is %d, but should be 0?\n", res
);
288 test_pic(const unsigned char *imgdata
, unsigned int imgsize
)
294 LARGE_INTEGER seekto
;
295 ULARGE_INTEGER newpos1
;
299 /* Let the fun begin */
300 hglob
= GlobalAlloc (0, imgsize
);
301 data
= GlobalLock (hglob
);
302 memcpy(data
, imgdata
, imgsize
);
303 GlobalUnlock(hglob
); data
= NULL
;
305 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
306 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
308 memset(&seekto
,0,sizeof(seekto
));
309 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
310 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
311 test_pic_with_stream(stream
, imgsize
);
313 IStream_Release(stream
);
315 /* again with Non Statable and Non Seekable stream */
316 stream
= NoStatStream_Construct(hglob
);
317 hglob
= 0; /* Non-statable impl always deletes on release */
318 test_pic_with_stream(stream
, 0);
320 IStream_Release(stream
);
321 for (i
= 1; i
<= 8; i
++) {
323 hglob
= GlobalAlloc (0, imgsize
+ i
* (2 * sizeof(DWORD
)));
324 data
= GlobalLock (hglob
);
325 header
= (DWORD
*)data
;
327 /* multiple copies of header */
328 memcpy(data
,"lt\0\0",4);
330 for (j
= 2; j
<= i
; j
++) {
331 memcpy(&(header
[2 * (j
- 1)]), header
, 2 * sizeof(DWORD
));
333 memcpy(data
+ i
* (2 * sizeof(DWORD
)), imgdata
, imgsize
);
334 GlobalUnlock(hglob
); data
= NULL
;
336 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
337 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
339 memset(&seekto
,0,sizeof(seekto
));
340 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
341 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
342 test_pic_with_stream(stream
, imgsize
);
344 IStream_Release(stream
);
346 /* again with Non Statable and Non Seekable stream */
347 stream
= NoStatStream_Construct(hglob
);
348 hglob
= 0; /* Non-statable impl always deletes on release */
349 test_pic_with_stream(stream
, 0);
351 IStream_Release(stream
);
355 static void test_empty_image(void) {
358 IPicture
* pic
= NULL
;
363 ULARGE_INTEGER newpos1
;
364 LARGE_INTEGER seekto
;
368 /* Empty image. Happens occasionally in VB programs. */
369 hglob
= GlobalAlloc (0, 8);
370 data
= GlobalLock (hglob
);
371 memcpy(data
,"lt\0\0",4);
372 ((DWORD
*)data
)[1] = 0;
373 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
374 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
376 memset(&seekto
,0,sizeof(seekto
));
377 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
378 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
381 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
383 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
384 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
386 hres
= IPicture_get_Type (pic
, &type
);
387 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
388 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
391 hres
= IPicture_get_Attributes (pic
, &attr
);
392 ok (hres
== S_OK
,"empty picture get attributes failed with hres 0x%08x\n", hres
);
393 ok (attr
== 0,"attr is %d, but should be 0\n", attr
);
395 hres
= IPicture_get_Handle (pic
, &handle
);
396 ok (hres
== S_OK
,"empty picture get handle failed with hres 0x%08x\n", hres
);
397 ok (handle
== 0, "empty picture get handle did not return 0, but 0x%08x\n", handle
);
398 IPicture_Release (pic
);
399 IStream_Release (stream
);
402 static void test_empty_image_2(void) {
405 IPicture
* pic
= NULL
;
409 ULARGE_INTEGER newpos1
;
410 LARGE_INTEGER seekto
;
413 /* Empty image at random stream position. */
414 hglob
= GlobalAlloc (0, 200);
415 data
= GlobalLock (hglob
);
417 memcpy(data
,"lt\0\0",4);
418 ((DWORD
*)data
)[1] = 0;
419 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
420 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
422 memset(&seekto
,0,sizeof(seekto
));
423 seekto
.u
.LowPart
= 42;
424 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
425 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
428 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
430 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
431 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
433 hres
= IPicture_get_Type (pic
, &type
);
434 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
435 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
437 IPicture_Release (pic
);
438 IStream_Release (stream
);
441 static void test_Invoke(void)
443 IPictureDisp
*picdisp
;
445 VARIANTARG vararg
, args
[10];
446 DISPPARAMS dispparams
;
454 hglob
= GlobalAlloc (0, sizeof(gifimage
));
455 data
= GlobalLock(hglob
);
456 memcpy(data
, gifimage
, sizeof(gifimage
));
459 hr
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
460 ok_ole_success(hr
, "CreateStreamOnHGlobal");
462 hr
= pOleLoadPicture(stream
, sizeof(gifimage
), TRUE
, &IID_IPictureDisp
, (void **)&picdisp
);
463 IStream_Release(stream
);
465 ok_ole_success(hr
, "OleLoadPicture");
467 V_VT(&vararg
) = VT_BOOL
;
468 V_BOOL(&vararg
) = VARIANT_FALSE
;
469 dispparams
.cNamedArgs
= 0;
470 dispparams
.rgdispidNamedArgs
= NULL
;
471 dispparams
.cArgs
= 1;
472 dispparams
.rgvarg
= &vararg
;
473 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IPictureDisp
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
474 ok(hr
== DISP_E_UNKNOWNNAME
, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr
);
475 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IUnknown
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
476 ok(hr
== DISP_E_UNKNOWNNAME
, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr
);
478 dispparams
.cArgs
= 0;
479 dispparams
.rgvarg
= NULL
;
480 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
481 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
483 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, NULL
, NULL
, NULL
);
484 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
486 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, NULL
, NULL
, NULL
);
487 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
489 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, &varresult
, NULL
, NULL
);
490 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
492 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
493 ok_ole_success(hr
, "IPictureDisp_Invoke");
494 ok(V_VT(&varresult
) == VT_I4
, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult
));
496 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
497 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
499 hr
= IPictureDisp_Invoke(picdisp
, 0xdeadbeef, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
500 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
502 dispparams
.cArgs
= 1;
503 dispparams
.rgvarg
= &vararg
;
504 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
505 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
507 dispparams
.cArgs
= 1;
508 dispparams
.rgvarg
= &vararg
;
509 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
510 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
512 /* DISPID_PICT_RENDER */
513 hdc
= create_render_dc();
515 for (i
= 0; i
< sizeof(args
)/sizeof(args
[0]); i
++)
516 V_VT(&args
[i
]) = VT_I4
;
527 V_I4(&args
[9]) = HandleToLong(hdc
);
529 dispparams
.rgvarg
= args
;
530 dispparams
.rgdispidNamedArgs
= NULL
;
531 dispparams
.cArgs
= 10;
532 dispparams
.cNamedArgs
= 0;
534 V_VT(&varresult
) = VT_EMPTY
;
535 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
536 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
538 /* Try with one argument set to VT_I2, it'd still work if coerced. */
539 V_VT(&args
[3]) = VT_I2
;
540 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
541 ok(hr
== DISP_E_TYPEMISMATCH
, "got 0x%08x\n", hr
);
542 V_VT(&args
[3]) = VT_I4
;
544 /* Wrong argument count */
545 dispparams
.cArgs
= 9;
546 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
547 ok(hr
== DISP_E_BADPARAMCOUNT
, "got 0x%08x\n", hr
);
549 delete_render_dc(hdc
);
550 IPictureDisp_Release(picdisp
);
553 static void test_OleCreatePictureIndirect(void)
562 /* crashes on native */
563 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, NULL
);
566 hr
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void**)&pict
);
567 ok(hr
== S_OK
, "hr %08x\n", hr
);
570 hr
= IPicture_get_Type(pict
, &type
);
571 ok(hr
== S_OK
, "hr %08x\n", hr
);
572 ok(type
== PICTYPE_UNINITIALIZED
, "type %d\n", type
);
575 hr
= IPicture_get_Handle(pict
, &handle
);
576 ok(hr
== S_OK
, "hr %08x\n", hr
);
577 ok(handle
== 0, "handle %08x\n", handle
);
579 IPicture_Release(pict
);
582 static void test_apm(void)
593 hglob
= GlobalAlloc (0, sizeof(apmdata
));
594 data
= GlobalLock(hglob
);
595 memcpy(data
, apmdata
, sizeof(apmdata
));
597 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
598 ole_check(pOleLoadPictureEx(stream
, sizeof(apmdata
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
));
600 ole_check(IPicture_get_Handle(pict
, &handle
));
601 ok(handle
!= 0, "handle is null\n");
603 ole_check(IPicture_get_Type(pict
, &type
));
604 expect_eq(type
, PICTYPE_METAFILE
, short, "%d");
606 ole_check(IPicture_get_Height(pict
, &cxy
));
607 expect_eq(cxy
, 1667, LONG
, "%d");
609 ole_check(IPicture_get_Width(pict
, &cxy
));
610 expect_eq(cxy
, 1323, LONG
, "%d");
612 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
613 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
615 ole_expect(IPicture_get_hPal(pict
, &handle
), E_FAIL
);
616 IPicture_Release(pict
);
617 IStream_Release(stream
);
620 static void test_metafile(void)
627 hglob
= GlobalAlloc (0, sizeof(metafile
));
628 data
= GlobalLock(hglob
);
629 memcpy(data
, metafile
, sizeof(metafile
));
631 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
632 /* Windows does not load simple metafiles */
633 ole_expect(pOleLoadPictureEx(stream
, sizeof(metafile
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
), E_FAIL
);
635 IStream_Release(stream
);
638 static void test_enhmetafile(void)
649 hglob
= GlobalAlloc (0, sizeof(enhmetafile
));
650 data
= GlobalLock(hglob
);
651 memcpy(data
, enhmetafile
, sizeof(enhmetafile
));
653 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
654 ole_check(pOleLoadPictureEx(stream
, sizeof(enhmetafile
), TRUE
, &IID_IPicture
, 10, 10, 0, (LPVOID
*)&pict
));
656 ole_check(IPicture_get_Handle(pict
, &handle
));
657 ok(handle
!= 0, "handle is null\n");
659 ole_check(IPicture_get_Type(pict
, &type
));
660 expect_eq(type
, PICTYPE_ENHMETAFILE
, short, "%d");
662 ole_check(IPicture_get_Height(pict
, &cxy
));
663 expect_eq(cxy
, -23, LONG
, "%d");
665 ole_check(IPicture_get_Width(pict
, &cxy
));
666 expect_eq(cxy
, -25, LONG
, "%d");
668 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
669 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
671 IPicture_Release(pict
);
672 IStream_Release(stream
);
675 static HRESULT
picture_render(IPicture
*iface
, HDC hdc
, LONG x
, LONG y
, LONG cx
, LONG cy
,
676 OLE_XPOS_HIMETRIC xSrc
,
677 OLE_YPOS_HIMETRIC ySrc
,
678 OLE_XSIZE_HIMETRIC cxSrc
,
679 OLE_YSIZE_HIMETRIC cySrc
,
682 VARIANT ret
, args
[10];
688 hr
= IPicture_Render(iface
, hdc
, x
, y
, cx
, cy
, xSrc
, ySrc
, cxSrc
, cySrc
, bounds
);
690 IPicture_QueryInterface(iface
, &IID_IDispatch
, (void**)&disp
);
692 /* This is broken on 64 bits - accepted pointer argument type is still VT_I4 */
693 for (i
= 0; i
< sizeof(args
)/sizeof(args
[0]); i
++)
694 V_VT(&args
[i
]) = VT_I4
;
696 /* pack arguments and call */
697 V_INT_PTR(&args
[0]) = (INT_PTR
)bounds
;
698 V_I4(&args
[1]) = cySrc
;
699 V_I4(&args
[2]) = cxSrc
;
700 V_I4(&args
[3]) = ySrc
;
701 V_I4(&args
[4]) = xSrc
;
706 V_I4(&args
[9]) = HandleToLong(hdc
);
708 params
.rgvarg
= args
;
709 params
.rgdispidNamedArgs
= NULL
;
711 params
.cNamedArgs
= 0;
713 V_VT(&ret
) = VT_EMPTY
;
714 hr_disp
= IDispatch_Invoke(disp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
,
715 ¶ms
, &ret
, NULL
, NULL
);
716 ok(hr
== hr_disp
, "DISPID_PICT_RENDER returned wrong code, 0x%08x, expected 0x%08x\n",
719 IDispatch_Release(disp
);
724 static void test_Render(void)
730 OLE_XSIZE_HIMETRIC pWidth
;
731 OLE_YSIZE_HIMETRIC pHeight
;
732 COLORREF result
, expected
;
733 HDC hdc
= create_render_dc();
735 /* test IPicture::Render return code on uninitialized picture */
736 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
737 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
738 hres
= IPicture_get_Type(pic
, &type
);
739 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
740 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
741 /* zero dimensions */
742 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
743 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
744 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
745 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
746 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
747 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
748 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
749 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
750 hres
= picture_render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
751 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
752 hres
= picture_render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
753 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
754 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
755 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
756 /* nonzero dimensions, PICTYPE_UNINITIALIZED */
757 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 10, NULL
);
758 ole_expect(hres
, S_OK
);
759 IPicture_Release(pic
);
761 desc
.cbSizeofstruct
= sizeof(PICTDESC
);
762 desc
.picType
= PICTYPE_ICON
;
763 desc
.icon
.hicon
= LoadIconA(NULL
, (LPCSTR
)IDI_APPLICATION
);
764 if(!desc
.icon
.hicon
){
765 win_skip("LoadIcon failed. Skipping...\n");
766 delete_render_dc(hdc
);
770 hres
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, TRUE
, (void **)&pic
);
771 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
772 /* zero dimensions, PICTYPE_ICON */
773 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
774 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
775 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
776 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
777 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
778 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
779 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
780 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
781 hres
= picture_render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
782 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
783 hres
= picture_render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
784 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
785 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
786 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
788 /* Check if target size and position is respected */
789 IPicture_get_Width(pic
, &pWidth
);
790 IPicture_get_Height(pic
, &pHeight
);
792 SetPixelV(hdc
, 0, 0, 0x00223344);
793 SetPixelV(hdc
, 5, 5, 0x00223344);
794 SetPixelV(hdc
, 10, 10, 0x00223344);
795 expected
= GetPixel(hdc
, 0, 0);
797 hres
= picture_render(pic
, hdc
, 1, 1, 9, 9, 0, 0, pWidth
, -pHeight
, NULL
);
798 ole_expect(hres
, S_OK
);
800 if(hres
!= S_OK
) goto done
;
802 /* Evaluate the rendered Icon */
803 result
= GetPixel(hdc
, 0, 0);
804 ok(result
== expected
,
805 "Color at 0,0 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
806 result
= GetPixel(hdc
, 5, 5);
807 ok(result
!= expected
,
808 "Color at 5,5 should have changed, but still was 0x%06X\n", expected
);
809 result
= GetPixel(hdc
, 10, 10);
810 ok(result
== expected
,
811 "Color at 10,10 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
814 IPicture_Release(pic
);
815 delete_render_dc(hdc
);
818 static void test_get_Attributes(void)
825 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
826 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
827 hres
= IPicture_get_Type(pic
, &type
);
828 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
829 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
831 hres
= IPicture_get_Attributes(pic
, NULL
);
832 ole_expect(hres
, E_POINTER
);
835 hres
= IPicture_get_Attributes(pic
, &attr
);
836 ole_expect(hres
, S_OK
);
837 ok(attr
== 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr
);
839 IPicture_Release(pic
);
842 static void test_get_Handle(void)
847 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
848 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
849 hres
= IPicture_get_Handle(pic
, NULL
);
850 ole_expect(hres
, E_POINTER
);
852 IPicture_Release(pic
);
855 static void test_get_Type(void)
860 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
861 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
863 hres
= IPicture_get_Type(pic
, NULL
);
864 ole_expect(hres
, E_POINTER
);
866 IPicture_Release(pic
);
869 static void test_OleLoadPicturePath(void)
871 static WCHAR emptyW
[] = {0};
876 char temp_path
[MAX_PATH
];
877 char temp_file
[MAX_PATH
];
878 WCHAR temp_fileW
[MAX_PATH
+ 5] = {'f','i','l','e',':','/','/','/'};
886 LPOLESTR szURLorPath
;
889 } invalid_parameters
[] =
893 {NULL
, &IID_IPicture
, NULL
},
894 {NULL
, &IID_IPicture
, &pic
},
895 {emptyW
, NULL
, NULL
},
896 {emptyW
, &IID_IPicture
, NULL
},
899 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
901 pic
= (IPicture
*)0xdeadbeef;
902 hres
= OleLoadPicturePath(invalid_parameters
[i
].szURLorPath
, NULL
, 0, 0,
903 invalid_parameters
[i
].riid
,
904 (void **)invalid_parameters
[i
].pic
);
905 ok(hres
== E_INVALIDARG
,
906 "[%d] Expected OleLoadPicturePath to return E_INVALIDARG, got 0x%08x\n", i
, hres
);
907 ok(pic
== (IPicture
*)0xdeadbeef,
908 "[%d] Expected output pointer to be 0xdeadbeef, got %p\n", i
, pic
);
911 pic
= (IPicture
*)0xdeadbeef;
912 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, NULL
, (void **)&pic
);
914 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
915 broken(hres
== E_UNEXPECTED
) || /* NT4 */
916 broken(hres
== E_OUTOFMEMORY
), /* Win2k/Win2k3 */
917 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
919 "Expected the output interface pointer to be NULL, got %p\n", pic
);
921 pic
= (IPicture
*)0xdeadbeef;
922 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
924 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
925 broken(hres
== E_UNEXPECTED
) || /* NT4 */
926 broken(hres
== E_OUTOFMEMORY
), /* Win2k/Win2k3 */
927 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
929 "Expected the output interface pointer to be NULL, got %p\n", pic
);
931 /* Create a local temporary image file for testing. */
932 GetTempPathA(sizeof(temp_path
), temp_path
);
933 GetTempFileNameA(temp_path
, "bmp", 0, temp_file
);
934 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
935 FILE_ATTRIBUTE_NORMAL
, NULL
);
936 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
939 MultiByteToWideChar(CP_ACP
, 0, temp_file
, -1, temp_fileW
+ 8, sizeof(temp_fileW
)/sizeof(WCHAR
) - 8);
941 /* Try a normal DOS path. */
942 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
944 broken(hres
== E_UNEXPECTED
), /* NT4 */
945 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
947 IPicture_Release(pic
);
950 V_VT(&var
) = VT_BSTR
;
951 V_BSTR(&var
) = SysAllocString(temp_fileW
+ 8);
952 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
953 ok(hres
== S_OK
, "OleLoadPictureFile error %#x\n", hres
);
954 IPicture_Release(pic
);
957 /* Try a DOS path with tacked on "file:". */
958 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
960 broken(hres
== E_UNEXPECTED
), /* NT4 */
961 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
963 IPicture_Release(pic
);
966 V_VT(&var
) = VT_BSTR
;
967 V_BSTR(&var
) = SysAllocString(temp_fileW
);
968 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
969 ok(hres
== CTL_E_PATHFILEACCESSERROR
, "wrong error %#x\n", hres
);
972 DeleteFileA(temp_file
);
974 /* Try with a nonexistent file. */
975 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
976 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
977 broken(hres
== E_UNEXPECTED
) || /* NT4 */
978 broken(hres
== E_FAIL
), /*Win2k */
979 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
982 V_VT(&var
) = VT_BSTR
;
983 V_BSTR(&var
) = SysAllocString(temp_fileW
+ 8);
984 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
985 ok(hres
== CTL_E_FILENOTFOUND
, "wrong error %#x\n", hres
);
988 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
989 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
990 broken(hres
== E_UNEXPECTED
) || /* NT4 */
991 broken(hres
== E_FAIL
), /* Win2k */
992 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
995 V_VT(&var
) = VT_BSTR
;
996 V_BSTR(&var
) = SysAllocString(temp_fileW
);
997 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
998 ok(hres
== CTL_E_PATHFILEACCESSERROR
, "wrong error %#x\n", hres
);
1001 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1002 FILE_ATTRIBUTE_NORMAL
, NULL
);
1003 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
1006 /* Try a "file:" URL with slash separators. */
1007 ptr
= temp_fileW
+ 8;
1015 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
1017 broken(hres
== E_UNEXPECTED
), /* NT4 */
1018 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
1020 IPicture_Release(pic
);
1023 V_VT(&var
) = VT_BSTR
;
1024 V_BSTR(&var
) = SysAllocString(temp_fileW
);
1025 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
1026 ok(hres
== CTL_E_PATHFILEACCESSERROR
, "wrong error %#x\n", hres
);
1029 DeleteFileA(temp_file
);
1031 /* Try with a nonexistent file. */
1032 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
1033 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
1034 broken(hres
== E_UNEXPECTED
) || /* NT4 */
1035 broken(hres
== E_FAIL
), /* Win2k */
1036 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
1039 V_VT(&var
) = VT_BSTR
;
1040 V_BSTR(&var
) = SysAllocString(temp_fileW
);
1041 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
1042 ok(hres
== CTL_E_PATHFILEACCESSERROR
, "wrong error %#x\n", hres
);
1046 V_VT(&var
) = VT_INT
;
1048 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
1049 ok(hres
== CTL_E_FILENOTFOUND
, "wrong error %#x\n", hres
);
1051 if (0) /* crashes under Windows */
1052 hres
= OleLoadPictureFile(var
, NULL
);
1055 static void test_himetric(void)
1057 static const BYTE bmp_bits
[1024];
1058 OLE_XSIZE_HIMETRIC cx
;
1059 OLE_YSIZE_HIMETRIC cy
;
1068 desc
.cbSizeofstruct
= sizeof(desc
);
1069 desc
.picType
= PICTYPE_BITMAP
;
1070 desc
.bmp
.hpal
= NULL
;
1072 hdc
= CreateCompatibleDC(0);
1074 bmp
= CreateBitmap(1.9 * GetDeviceCaps(hdc
, LOGPIXELSX
),
1075 1.9 * GetDeviceCaps(hdc
, LOGPIXELSY
), 1, 1, NULL
);
1077 desc
.bmp
.hbitmap
= bmp
;
1079 /* size in himetric units reported rounded up to next integer value */
1080 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1081 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1084 d
= MulDiv((INT
)(1.9 * GetDeviceCaps(hdc
, LOGPIXELSX
)), 2540, GetDeviceCaps(hdc
, LOGPIXELSX
));
1085 hr
= IPicture_get_Width(pic
, &cx
);
1086 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1087 ok(cx
== d
, "got %d, expected %d\n", cx
, d
);
1090 d
= MulDiv((INT
)(1.9 * GetDeviceCaps(hdc
, LOGPIXELSY
)), 2540, GetDeviceCaps(hdc
, LOGPIXELSY
));
1091 hr
= IPicture_get_Height(pic
, &cy
);
1092 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1093 ok(cy
== d
, "got %d, expected %d\n", cy
, d
);
1096 IPicture_Release(pic
);
1098 /* same thing with icon */
1099 icon
= CreateIcon(NULL
, GetSystemMetrics(SM_CXICON
), GetSystemMetrics(SM_CYICON
),
1100 1, 1, bmp_bits
, bmp_bits
);
1101 ok(icon
!= NULL
, "failed to create icon\n");
1103 desc
.picType
= PICTYPE_ICON
;
1104 desc
.icon
.hicon
= icon
;
1106 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1107 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1110 d
= MulDiv(GetSystemMetrics(SM_CXICON
), 2540, GetDeviceCaps(hdc
, LOGPIXELSX
));
1111 hr
= IPicture_get_Width(pic
, &cx
);
1112 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1113 ok(cx
== d
, "got %d, expected %d\n", cx
, d
);
1116 d
= MulDiv(GetSystemMetrics(SM_CYICON
), 2540, GetDeviceCaps(hdc
, LOGPIXELSY
));
1117 hr
= IPicture_get_Height(pic
, &cy
);
1118 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1119 ok(cy
== d
, "got %d, expected %d\n", cy
, d
);
1121 IPicture_Release(pic
);
1127 static void test_load_save_bmp(void)
1135 IPersistStream
*src_stream
;
1136 IStream
*dst_stream
;
1137 LARGE_INTEGER offset
;
1141 desc
.cbSizeofstruct
= sizeof(desc
);
1142 desc
.picType
= PICTYPE_BITMAP
;
1144 desc
.bmp
.hbitmap
= CreateBitmap(1, 1, 1, 1, NULL
);
1145 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1146 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1149 hr
= IPicture_get_Type(pic
, &type
);
1150 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1151 ok(type
== PICTYPE_BITMAP
,"expected picture type PICTYPE_BITMAP, got %d\n", type
);
1153 hr
= IPicture_get_Handle(pic
, &handle
);
1154 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1155 ok(IntToPtr(handle
) == desc
.bmp
.hbitmap
, "get_Handle returned wrong handle %#x\n", handle
);
1157 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 4096);
1158 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1159 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1162 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1163 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1164 ok(size
== 66, "expected 66, got %d\n", size
);
1165 mem
= GlobalLock(hmem
);
1166 ok(!memcmp(&mem
[0], "BM", 2), "got wrong bmp header %04x\n", mem
[0]);
1170 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1171 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1172 ok(size
== -1, "expected -1, got %d\n", size
);
1174 offset
.QuadPart
= 0;
1175 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1176 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1178 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1179 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1181 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1182 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1184 IPersistStream_Release(src_stream
);
1185 IStream_Release(dst_stream
);
1187 mem
= GlobalLock(hmem
);
1188 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1189 ok(mem
[1] == 66, "expected stream size 66, got %u\n", mem
[1]);
1190 ok(!memcmp(&mem
[2], "BM", 2), "got wrong bmp header %04x\n", mem
[2]);
1195 DeleteObject(desc
.bmp
.hbitmap
);
1196 IPicture_Release(pic
);
1199 static void test_load_save_icon(void)
1207 IPersistStream
*src_stream
;
1208 IStream
*dst_stream
;
1209 LARGE_INTEGER offset
;
1213 desc
.cbSizeofstruct
= sizeof(desc
);
1214 desc
.picType
= PICTYPE_ICON
;
1215 desc
.icon
.hicon
= LoadIconA(NULL
, (LPCSTR
)IDI_APPLICATION
);
1216 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1217 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1220 hr
= IPicture_get_Type(pic
, &type
);
1221 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1222 ok(type
== PICTYPE_ICON
,"expected picture type PICTYPE_ICON, got %d\n", type
);
1224 hr
= IPicture_get_Handle(pic
, &handle
);
1225 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1226 ok(IntToPtr(handle
) == desc
.icon
.hicon
, "get_Handle returned wrong handle %#x\n", handle
);
1228 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 8192);
1229 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1230 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
1233 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1234 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1236 ok(size
== 766, "expected 766, got %d\n", size
);
1237 mem
= GlobalLock(hmem
);
1238 ok(mem
[0] == 0x00010000, "got wrong icon header %04x\n", mem
[0]);
1242 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1243 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1244 ok(size
== -1, "expected -1, got %d\n", size
);
1246 offset
.QuadPart
= 0;
1247 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1248 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1250 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1251 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1253 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1254 ok(hr
== S_OK
, "Saveerror %#x\n", hr
);
1256 IPersistStream_Release(src_stream
);
1257 IStream_Release(dst_stream
);
1259 mem
= GlobalLock(hmem
);
1260 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1262 ok(mem
[1] == 766, "expected stream size 766, got %u\n", mem
[1]);
1263 ok(mem
[2] == 0x00010000, "got wrong icon header %04x\n", mem
[2]);
1268 DestroyIcon(desc
.icon
.hicon
);
1269 IPicture_Release(pic
);
1272 static void test_load_save_empty_picture(void)
1280 IPersistStream
*src_stream
;
1281 IStream
*dst_stream
, *stream
;
1282 LARGE_INTEGER offset
;
1286 memset(&pic
, 0, sizeof(pic
));
1287 desc
.cbSizeofstruct
= sizeof(desc
);
1288 desc
.picType
= PICTYPE_NONE
;
1289 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void **)&pic
);
1290 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1293 hr
= IPicture_get_Type(pic
, &type
);
1294 ok(hr
== S_OK
, "get_Type error %#x\n", hr
);
1295 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1297 handle
= (OLE_HANDLE
)0xdeadbeef;
1298 hr
= IPicture_get_Handle(pic
, &handle
);
1299 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1300 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1302 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 4096);
1303 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1304 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1307 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1308 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1309 ok(size
== -1, "expected -1, got %d\n", size
);
1312 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1313 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1314 ok(size
== -1, "expected -1, got %d\n", size
);
1316 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1317 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1319 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1320 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1322 mem
= GlobalLock(hmem
);
1323 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1324 ok(mem
[1] == 0, "expected stream size 0, got %u\n", mem
[1]);
1327 IPersistStream_Release(src_stream
);
1328 IPicture_Release(pic
);
1330 /* first with statable and seekable stream */
1331 offset
.QuadPart
= 0;
1332 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1333 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1336 hr
= pOleLoadPicture(dst_stream
, 0, FALSE
, &IID_IPicture
, (void **)&pic
);
1337 ok(hr
== S_OK
, "OleLoadPicture error %#x\n", hr
);
1338 ok(pic
!= NULL
,"picture should not be not NULL\n");
1342 hr
= IPicture_get_Type(pic
, &type
);
1343 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1344 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1346 handle
= (OLE_HANDLE
)0xdeadbeef;
1347 hr
= IPicture_get_Handle(pic
, &handle
);
1348 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1349 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1351 IPicture_Release(pic
);
1353 IStream_Release(dst_stream
);
1355 /* again with non-statable and non-seekable stream */
1356 stream
= NoStatStream_Construct(hmem
);
1357 ok(stream
!= NULL
, "failed to create empty image stream\n");
1360 hr
= pOleLoadPicture(stream
, 0, FALSE
, &IID_IPicture
, (void **)&pic
);
1361 ok(hr
== S_OK
, "OleLoadPicture error %#x\n", hr
);
1362 ok(pic
!= NULL
,"picture should not be not NULL\n");
1366 hr
= IPicture_get_Type(pic
, &type
);
1367 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1368 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1370 handle
= (OLE_HANDLE
)0xdeadbeef;
1371 hr
= IPicture_get_Handle(pic
, &handle
);
1372 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1373 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1375 IPicture_Release(pic
);
1377 /* Non-statable impl always deletes on release */
1378 IStream_Release(stream
);
1381 static void test_load_save_emf(void)
1391 IPersistStream
*src_stream
;
1392 IStream
*dst_stream
;
1393 LARGE_INTEGER offset
;
1397 hdc
= CreateEnhMetaFileA(0, NULL
, NULL
, NULL
);
1398 ok(hdc
!= 0, "CreateEnhMetaFileA failed\n");
1400 desc
.cbSizeofstruct
= sizeof(desc
);
1401 desc
.picType
= PICTYPE_ENHMETAFILE
;
1402 desc
.emf
.hemf
= CloseEnhMetaFile(hdc
);
1403 ok(desc
.emf
.hemf
!= 0, "CloseEnhMetaFile failed\n");
1404 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1405 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1408 hr
= IPicture_get_Type(pic
, &type
);
1409 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1410 ok(type
== PICTYPE_ENHMETAFILE
,"expected PICTYPE_ENHMETAFILE, got %d\n", type
);
1412 hr
= IPicture_get_Handle(pic
, &handle
);
1413 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1414 ok(IntToPtr(handle
) == desc
.emf
.hemf
, "get_Handle returned wrong handle %#x\n", handle
);
1416 hmem
= GlobalAlloc(GMEM_MOVEABLE
, 0);
1417 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1418 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1421 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1422 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1423 ok(size
== 128, "expected 128, got %d\n", size
);
1424 emh
= GlobalLock(hmem
);
1427 ok(emh
->iType
== EMR_HEADER
, "wrong iType %04x\n", emh
->iType
);
1428 ok(emh
->dSignature
== ENHMETA_SIGNATURE
, "wrong dSignature %08x\n", emh
->dSignature
);
1433 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1434 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1435 ok(size
== -1, "expected -1, got %d\n", size
);
1437 offset
.QuadPart
= 0;
1438 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1439 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1441 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1442 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1444 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1445 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1447 IPersistStream_Release(src_stream
);
1448 IStream_Release(dst_stream
);
1450 mem
= GlobalLock(hmem
);
1451 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1452 ok(mem
[1] == 128, "expected 128, got %u\n", mem
[1]);
1453 emh
= (ENHMETAHEADER
*)(mem
+ 2);
1454 ok(emh
->iType
== EMR_HEADER
, "wrong iType %04x\n", emh
->iType
);
1455 ok(emh
->dSignature
== ENHMETA_SIGNATURE
, "wrong dSignature %08x\n", emh
->dSignature
);
1460 DeleteEnhMetaFile(desc
.emf
.hemf
);
1461 IPicture_Release(pic
);
1464 START_TEST(olepicture
)
1466 hOleaut32
= GetModuleHandleA("oleaut32.dll");
1467 pOleLoadPicture
= (void*)GetProcAddress(hOleaut32
, "OleLoadPicture");
1468 pOleLoadPictureEx
= (void*)GetProcAddress(hOleaut32
, "OleLoadPictureEx");
1469 if (!pOleLoadPicture
)
1471 win_skip("OleLoadPicture is not available\n");
1475 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
1476 test_pic(gifimage
, sizeof(gifimage
));
1477 test_pic(jpgimage
, sizeof(jpgimage
));
1478 test_pic(bmpimage
, sizeof(bmpimage
));
1479 test_pic(bmpimage_rle8
, sizeof(bmpimage_rle8
));
1480 test_pic(gif4pixel
, sizeof(gif4pixel
));
1481 /* FIXME: No PNG support in Windows... */
1482 if (0) test_pic(pngimage
, sizeof(pngimage
));
1484 test_empty_image_2();
1485 if (pOleLoadPictureEx
)
1492 win_skip("OleLoadPictureEx is not available\n");
1494 test_OleCreatePictureIndirect();
1496 test_get_Attributes();
1499 test_OleLoadPicturePath();
1501 test_load_save_bmp();
1502 test_load_save_icon();
1503 test_load_save_empty_picture();
1504 test_load_save_emf();
1508 /* Helper functions only ... */
1511 static inline NoStatStreamImpl
*impl_from_IStream(IStream
*iface
)
1513 return CONTAINING_RECORD(iface
, NoStatStreamImpl
, IStream_iface
);
1516 static void NoStatStreamImpl_Destroy(NoStatStreamImpl
* This
)
1518 GlobalFree(This
->supportHandle
);
1519 This
->supportHandle
=0;
1520 HeapFree(GetProcessHeap(), 0, This
);
1523 static ULONG WINAPI
NoStatStreamImpl_AddRef(
1526 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1527 return InterlockedIncrement(&This
->ref
);
1530 static HRESULT WINAPI
NoStatStreamImpl_QueryInterface(
1532 REFIID riid
, /* [in] */
1533 void** ppvObject
) /* [iid_is][out] */
1535 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1536 if (ppvObject
==0) return E_INVALIDARG
;
1539 if (IsEqualIID(&IID_IUnknown
, riid
) || IsEqualIID(&IID_IStream
, riid
))
1540 *ppvObject
= &This
->IStream_iface
;
1542 if ((*ppvObject
)==0)
1543 return E_NOINTERFACE
;
1544 NoStatStreamImpl_AddRef(iface
);
1548 static ULONG WINAPI
NoStatStreamImpl_Release(
1551 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1552 ULONG newRef
= InterlockedDecrement(&This
->ref
);
1554 NoStatStreamImpl_Destroy(This
);
1558 static HRESULT WINAPI
NoStatStreamImpl_Read(
1560 void* pv
, /* [length_is][size_is][out] */
1561 ULONG cb
, /* [in] */
1562 ULONG
* pcbRead
) /* [out] */
1564 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1565 void* supportBuffer
;
1566 ULONG bytesReadBuffer
;
1567 ULONG bytesToReadFromBuffer
;
1570 pcbRead
= &bytesReadBuffer
;
1571 bytesToReadFromBuffer
= min( This
->streamSize
.u
.LowPart
- This
->currentPosition
.u
.LowPart
, cb
);
1572 supportBuffer
= GlobalLock(This
->supportHandle
);
1573 memcpy(pv
, (char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, bytesToReadFromBuffer
);
1574 This
->currentPosition
.u
.LowPart
+=bytesToReadFromBuffer
;
1575 *pcbRead
= bytesToReadFromBuffer
;
1576 GlobalUnlock(This
->supportHandle
);
1582 static HRESULT WINAPI
NoStatStreamImpl_Write(
1584 const void* pv
, /* [size_is][in] */
1585 ULONG cb
, /* [in] */
1586 ULONG
* pcbWritten
) /* [out] */
1588 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1589 void* supportBuffer
;
1590 ULARGE_INTEGER newSize
;
1591 ULONG bytesWritten
= 0;
1593 if (pcbWritten
== 0)
1594 pcbWritten
= &bytesWritten
;
1597 newSize
.u
.HighPart
= 0;
1598 newSize
.u
.LowPart
= This
->currentPosition
.u
.LowPart
+ cb
;
1599 if (newSize
.u
.LowPart
> This
->streamSize
.u
.LowPart
)
1600 IStream_SetSize(iface
, newSize
);
1602 supportBuffer
= GlobalLock(This
->supportHandle
);
1603 memcpy((char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, pv
, cb
);
1604 This
->currentPosition
.u
.LowPart
+=cb
;
1606 GlobalUnlock(This
->supportHandle
);
1610 static HRESULT WINAPI
NoStatStreamImpl_Seek(
1612 LARGE_INTEGER dlibMove
, /* [in] */
1613 DWORD dwOrigin
, /* [in] */
1614 ULARGE_INTEGER
* plibNewPosition
) /* [out] */
1616 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1617 ULARGE_INTEGER newPosition
;
1620 case STREAM_SEEK_SET
:
1621 newPosition
.u
.HighPart
= 0;
1622 newPosition
.u
.LowPart
= 0;
1624 case STREAM_SEEK_CUR
:
1625 newPosition
= This
->currentPosition
;
1627 case STREAM_SEEK_END
:
1628 newPosition
= This
->streamSize
;
1631 return STG_E_INVALIDFUNCTION
;
1633 if (dlibMove
.QuadPart
< 0 && newPosition
.QuadPart
< -dlibMove
.QuadPart
)
1634 return STG_E_INVALIDFUNCTION
;
1635 newPosition
.QuadPart
+= dlibMove
.QuadPart
;
1636 if (plibNewPosition
) *plibNewPosition
= newPosition
;
1637 This
->currentPosition
= newPosition
;
1641 static HRESULT WINAPI
NoStatStreamImpl_SetSize(
1643 ULARGE_INTEGER libNewSize
) /* [in] */
1645 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1646 HGLOBAL supportHandle
;
1647 if (libNewSize
.u
.HighPart
!= 0)
1648 return STG_E_INVALIDFUNCTION
;
1649 if (This
->streamSize
.u
.LowPart
== libNewSize
.u
.LowPart
)
1651 supportHandle
= GlobalReAlloc(This
->supportHandle
, libNewSize
.u
.LowPart
, 0);
1652 if (supportHandle
== 0)
1653 return STG_E_MEDIUMFULL
;
1654 This
->supportHandle
= supportHandle
;
1655 This
->streamSize
.u
.LowPart
= libNewSize
.u
.LowPart
;
1659 static HRESULT WINAPI
NoStatStreamImpl_CopyTo(
1661 IStream
* pstm
, /* [unique][in] */
1662 ULARGE_INTEGER cb
, /* [in] */
1663 ULARGE_INTEGER
* pcbRead
, /* [out] */
1664 ULARGE_INTEGER
* pcbWritten
) /* [out] */
1667 BYTE tmpBuffer
[128];
1668 ULONG bytesRead
, bytesWritten
, copySize
;
1669 ULARGE_INTEGER totalBytesRead
;
1670 ULARGE_INTEGER totalBytesWritten
;
1673 return STG_E_INVALIDPOINTER
;
1674 totalBytesRead
.u
.LowPart
= totalBytesRead
.u
.HighPart
= 0;
1675 totalBytesWritten
.u
.LowPart
= totalBytesWritten
.u
.HighPart
= 0;
1677 while ( cb
.u
.LowPart
> 0 )
1679 if ( cb
.u
.LowPart
>= 128 )
1682 copySize
= cb
.u
.LowPart
;
1683 IStream_Read(iface
, tmpBuffer
, copySize
, &bytesRead
);
1684 totalBytesRead
.u
.LowPart
+= bytesRead
;
1685 IStream_Write(pstm
, tmpBuffer
, bytesRead
, &bytesWritten
);
1686 totalBytesWritten
.u
.LowPart
+= bytesWritten
;
1687 if (bytesRead
!= bytesWritten
)
1689 hr
= STG_E_MEDIUMFULL
;
1692 if (bytesRead
!=copySize
)
1695 cb
.u
.LowPart
-= bytesRead
;
1699 pcbRead
->u
.LowPart
= totalBytesRead
.u
.LowPart
;
1700 pcbRead
->u
.HighPart
= totalBytesRead
.u
.HighPart
;
1705 pcbWritten
->u
.LowPart
= totalBytesWritten
.u
.LowPart
;
1706 pcbWritten
->u
.HighPart
= totalBytesWritten
.u
.HighPart
;
1711 static HRESULT WINAPI
NoStatStreamImpl_Commit(IStream
* iface
,DWORD grfCommitFlags
)
1715 static HRESULT WINAPI
NoStatStreamImpl_Revert(IStream
* iface
) { return S_OK
; }
1717 static HRESULT WINAPI
NoStatStreamImpl_LockRegion(
1719 ULARGE_INTEGER libOffset
, /* [in] */
1720 ULARGE_INTEGER cb
, /* [in] */
1721 DWORD dwLockType
) /* [in] */
1726 static HRESULT WINAPI
NoStatStreamImpl_UnlockRegion(
1728 ULARGE_INTEGER libOffset
, /* [in] */
1729 ULARGE_INTEGER cb
, /* [in] */
1730 DWORD dwLockType
) /* [in] */
1735 static HRESULT WINAPI
NoStatStreamImpl_Stat(
1737 STATSTG
* pstatstg
, /* [out] */
1738 DWORD grfStatFlag
) /* [in] */
1743 static HRESULT WINAPI
NoStatStreamImpl_Clone(
1745 IStream
** ppstm
) /* [out] */
1749 static const IStreamVtbl NoStatStreamImpl_Vtbl
;
1752 Build an object that implements IStream, without IStream_Stat capabilities.
1753 Receives a memory handle with data buffer. If memory handle is non-null,
1754 it is assumed to be unlocked, otherwise an internal memory handle is allocated.
1755 In any case the object takes ownership of memory handle and will free it on
1758 static IStream
* NoStatStream_Construct(HGLOBAL hGlobal
)
1760 NoStatStreamImpl
* newStream
;
1762 newStream
= HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl
));
1765 newStream
->IStream_iface
.lpVtbl
= &NoStatStreamImpl_Vtbl
;
1767 newStream
->supportHandle
= hGlobal
;
1769 if (!newStream
->supportHandle
)
1770 newStream
->supportHandle
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
|
1772 newStream
->currentPosition
.u
.HighPart
= 0;
1773 newStream
->currentPosition
.u
.LowPart
= 0;
1774 newStream
->streamSize
.u
.HighPart
= 0;
1775 newStream
->streamSize
.u
.LowPart
= GlobalSize(newStream
->supportHandle
);
1777 return &newStream
->IStream_iface
;
1781 static const IStreamVtbl NoStatStreamImpl_Vtbl
=
1783 NoStatStreamImpl_QueryInterface
,
1784 NoStatStreamImpl_AddRef
,
1785 NoStatStreamImpl_Release
,
1786 NoStatStreamImpl_Read
,
1787 NoStatStreamImpl_Write
,
1788 NoStatStreamImpl_Seek
,
1789 NoStatStreamImpl_SetSize
,
1790 NoStatStreamImpl_CopyTo
,
1791 NoStatStreamImpl_Commit
,
1792 NoStatStreamImpl_Revert
,
1793 NoStatStreamImpl_LockRegion
,
1794 NoStatStreamImpl_UnlockRegion
,
1795 NoStatStreamImpl_Stat
,
1796 NoStatStreamImpl_Clone