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
29 #define NONAMELESSUNION
31 #include "wine/test.h"
45 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
47 #define ole_expect(expr, expect) { \
49 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
52 #define ole_check(expr) ole_expect(expr, S_OK);
54 static HMODULE hOleaut32
;
56 static HRESULT (WINAPI
*pOleLoadPicture
)(LPSTREAM
,LONG
,BOOL
,REFIID
,LPVOID
*);
57 static HRESULT (WINAPI
*pOleLoadPictureEx
)(LPSTREAM
,LONG
,BOOL
,REFIID
,DWORD
,DWORD
,DWORD
,LPVOID
*);
59 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
62 static const unsigned char gifimage
[35] = {
63 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
64 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
69 static const unsigned char jpgimage
[285] = {
70 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
71 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
72 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
73 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
74 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
75 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
76 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
77 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
78 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
79 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
80 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
81 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
82 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
83 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
84 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
85 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
86 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
87 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
91 static const unsigned char pngimage
[285] = {
92 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
93 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
94 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
95 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
96 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
97 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
98 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
101 /* 1bpp BI_RGB 1x1 pixel bmp */
102 static const unsigned char bmpimage
[66] = {
103 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
104 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
105 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
106 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
110 /* 8bpp BI_RLE8 1x1 pixel bmp */
111 static const unsigned char bmpimage_rle8
[] = {
112 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
113 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00,
114 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
115 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x01,
120 static const unsigned char gif4pixel
[42] = {
121 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
122 0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
123 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
126 /* APM with an empty metafile with some padding zeros - looks like under Window the
127 * metafile data should be at least 20 bytes */
128 static const unsigned char apmdata
[] = {
129 0xd7,0xcd,0xc6,0x9a, 0x00,0x00,0x00,0x00, 0x00,0x00,0xee,0x02, 0xb1,0x03,0xa0,0x05,
130 0x00,0x00,0x00,0x00, 0xee,0x53,0x01,0x00, 0x09,0x00,0x00,0x03, 0x13,0x00,0x00,0x00,
131 0x01,0x00,0x05,0x00, 0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
132 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
135 /* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
136 static const unsigned char metafile
[] = {
137 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
140 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
141 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
142 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
146 /* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
147 static const unsigned char enhmetafile
[] = {
148 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
153 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
154 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
155 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
158 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
161 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
162 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
163 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
165 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
167 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
168 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
171 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
172 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
173 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
174 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
175 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
176 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
178 0x14, 0x00, 0x00, 0x00
181 static HBITMAP stock_bm
;
183 static HDC
create_render_dc( void )
185 HDC dc
= CreateCompatibleDC( NULL
);
186 BITMAPINFO info
= {{sizeof(info
.bmiHeader
), 100, 100, 1, 32, BI_RGB
}};
188 HBITMAP dib
= CreateDIBSection( NULL
, &info
, DIB_RGB_COLORS
, &bits
, NULL
, 0 );
190 stock_bm
= SelectObject( dc
, dib
);
194 static void delete_render_dc( HDC dc
)
196 HBITMAP dib
= SelectObject( dc
, stock_bm
);
201 typedef struct NoStatStreamImpl
203 IStream IStream_iface
;
206 HGLOBAL supportHandle
;
207 ULARGE_INTEGER streamSize
;
208 ULARGE_INTEGER currentPosition
;
211 static IStream
* NoStatStream_Construct(HGLOBAL hGlobal
);
214 test_pic_with_stream(LPSTREAM stream
, unsigned int imgsize
)
216 IPicture
* pic
= NULL
;
219 OLE_HANDLE handle
, hPal
;
220 OLE_XSIZE_HIMETRIC width
;
221 OLE_YSIZE_HIMETRIC height
;
227 hres
= pOleLoadPicture(stream
, imgsize
, TRUE
, &IID_IPicture
, &pvObj
);
230 ok(hres
== S_OK
,"OLP (NULL,..) does not return 0, but 0x%08x\n",hres
);
231 ok(pic
!= NULL
,"OLP (NULL,..) returns NULL, instead of !NULL\n");
236 hres
= IPicture_QueryInterface (pic
, &IID_IPicture
, &pvObj
);
238 ok(hres
== S_OK
,"IPicture_QI does not return S_OK, but 0x%08x\n", hres
);
239 ok(pvObj
!= NULL
,"IPicture_QI does return NULL, instead of a ptr\n");
241 IPicture_Release ((IPicture
*)pvObj
);
244 hres
= IPicture_get_Handle (pic
, &handle
);
245 ok(hres
== S_OK
,"IPicture_get_Handle does not return S_OK, but 0x%08x\n", hres
);
246 ok(handle
!= 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
251 GetObjectA(UlongToHandle(handle
), sizeof(BITMAP
), &bmp
);
252 ok(bmp
.bmBits
!= 0, "not a dib\n");
256 hres
= IPicture_get_Width (pic
, &width
);
257 ok(hres
== S_OK
,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres
);
258 ok(width
!= 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
261 hres
= IPicture_get_Height (pic
, &height
);
262 ok(hres
== S_OK
,"IPicture_get_Height does not return S_OK, but 0x%08x\n", hres
);
263 ok(height
!= 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
266 hres
= IPicture_get_Type (pic
, &type
);
267 ok(hres
== S_OK
,"IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
268 ok(type
== PICTYPE_BITMAP
, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type
, PICTYPE_BITMAP
);
271 hres
= IPicture_get_Attributes (pic
, &attr
);
272 ok(hres
== S_OK
,"IPicture_get_Attributes does not return S_OK, but 0x%08x\n", hres
);
273 ok(attr
== 0, "IPicture_get_Attributes returns %d, but it should be 0.\n", attr
);
276 hres
= IPicture_get_hPal (pic
, &hPal
);
277 ok(hres
== S_OK
,"IPicture_get_hPal does not return S_OK, but 0x%08x\n", hres
);
278 /* a single pixel b/w image has no palette */
279 ok(hPal
== 0, "IPicture_get_hPal returns %d, but it should be 0.\n", hPal
);
281 res
= IPicture_Release (pic
);
282 ok (res
== 0, "refcount after release is %d, but should be 0?\n", res
);
286 test_pic(const unsigned char *imgdata
, unsigned int imgsize
)
292 LARGE_INTEGER seekto
;
293 ULARGE_INTEGER newpos1
;
297 /* Let the fun begin */
298 hglob
= GlobalAlloc (0, imgsize
);
299 data
= GlobalLock (hglob
);
300 memcpy(data
, imgdata
, imgsize
);
301 GlobalUnlock(hglob
); data
= NULL
;
303 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
304 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
306 memset(&seekto
,0,sizeof(seekto
));
307 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
308 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
309 test_pic_with_stream(stream
, imgsize
);
311 IStream_Release(stream
);
313 /* again with Non Statable and Non Seekable stream */
314 stream
= NoStatStream_Construct(hglob
);
315 hglob
= 0; /* Non-statable impl always deletes on release */
316 test_pic_with_stream(stream
, 0);
318 IStream_Release(stream
);
319 for (i
= 1; i
<= 8; i
++) {
321 hglob
= GlobalAlloc (0, imgsize
+ i
* (2 * sizeof(DWORD
)));
322 data
= GlobalLock (hglob
);
323 header
= (DWORD
*)data
;
325 /* multiple copies of header */
326 memcpy(data
,"lt\0\0",4);
328 for (j
= 2; j
<= i
; j
++) {
329 memcpy(&(header
[2 * (j
- 1)]), header
, 2 * sizeof(DWORD
));
331 memcpy(data
+ i
* (2 * sizeof(DWORD
)), imgdata
, imgsize
);
332 GlobalUnlock(hglob
); data
= NULL
;
334 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
335 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
337 memset(&seekto
,0,sizeof(seekto
));
338 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
339 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
340 test_pic_with_stream(stream
, imgsize
);
342 IStream_Release(stream
);
344 /* again with Non Statable and Non Seekable stream */
345 stream
= NoStatStream_Construct(hglob
);
346 hglob
= 0; /* Non-statable impl always deletes on release */
347 test_pic_with_stream(stream
, 0);
349 IStream_Release(stream
);
353 static void test_empty_image(void) {
356 IPicture
* pic
= NULL
;
361 ULARGE_INTEGER newpos1
;
362 LARGE_INTEGER seekto
;
366 /* Empty image. Happens occasionally in VB programs. */
367 hglob
= GlobalAlloc (0, 8);
368 data
= GlobalLock (hglob
);
369 memcpy(data
,"lt\0\0",4);
370 ((DWORD
*)data
)[1] = 0;
371 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
372 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
374 memset(&seekto
,0,sizeof(seekto
));
375 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
376 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
379 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
381 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
382 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
384 hres
= IPicture_get_Type (pic
, &type
);
385 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
386 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
389 hres
= IPicture_get_Attributes (pic
, &attr
);
390 ok (hres
== S_OK
,"empty picture get attributes failed with hres 0x%08x\n", hres
);
391 ok (attr
== 0,"attr is %d, but should be 0\n", attr
);
393 hres
= IPicture_get_Handle (pic
, &handle
);
394 ok (hres
== S_OK
,"empty picture get handle failed with hres 0x%08x\n", hres
);
395 ok (handle
== 0, "empty picture get handle did not return 0, but 0x%08x\n", handle
);
396 IPicture_Release (pic
);
397 IStream_Release (stream
);
400 static void test_empty_image_2(void) {
403 IPicture
* pic
= NULL
;
407 ULARGE_INTEGER newpos1
;
408 LARGE_INTEGER seekto
;
411 /* Empty image at random stream position. */
412 hglob
= GlobalAlloc (0, 200);
413 data
= GlobalLock (hglob
);
415 memcpy(data
,"lt\0\0",4);
416 ((DWORD
*)data
)[1] = 0;
417 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
418 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
420 memset(&seekto
,0,sizeof(seekto
));
421 seekto
.u
.LowPart
= 42;
422 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
423 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
426 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
428 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
429 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
431 hres
= IPicture_get_Type (pic
, &type
);
432 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
433 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
435 IPicture_Release (pic
);
436 IStream_Release (stream
);
439 static void test_Invoke(void)
441 IPictureDisp
*picdisp
;
443 VARIANTARG vararg
, args
[10];
444 DISPPARAMS dispparams
;
452 hglob
= GlobalAlloc (0, sizeof(gifimage
));
453 data
= GlobalLock(hglob
);
454 memcpy(data
, gifimage
, sizeof(gifimage
));
457 hr
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
458 ok_ole_success(hr
, "CreateStreamOnHGlobal");
460 hr
= pOleLoadPicture(stream
, sizeof(gifimage
), TRUE
, &IID_IPictureDisp
, (void **)&picdisp
);
461 IStream_Release(stream
);
463 ok_ole_success(hr
, "OleLoadPicture");
465 V_VT(&vararg
) = VT_BOOL
;
466 V_BOOL(&vararg
) = VARIANT_FALSE
;
467 dispparams
.cNamedArgs
= 0;
468 dispparams
.rgdispidNamedArgs
= NULL
;
469 dispparams
.cArgs
= 1;
470 dispparams
.rgvarg
= &vararg
;
471 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IPictureDisp
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
472 ok(hr
== DISP_E_UNKNOWNNAME
, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr
);
473 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IUnknown
, 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
);
476 dispparams
.cArgs
= 0;
477 dispparams
.rgvarg
= NULL
;
478 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
479 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
481 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, NULL
, NULL
, NULL
);
482 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
484 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, NULL
, NULL
, NULL
);
485 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
487 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, &varresult
, NULL
, NULL
);
488 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
490 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
491 ok_ole_success(hr
, "IPictureDisp_Invoke");
492 ok(V_VT(&varresult
) == VT_I4
, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult
));
494 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
495 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
497 hr
= IPictureDisp_Invoke(picdisp
, 0xdeadbeef, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
498 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
500 dispparams
.cArgs
= 1;
501 dispparams
.rgvarg
= &vararg
;
502 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
503 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
505 dispparams
.cArgs
= 1;
506 dispparams
.rgvarg
= &vararg
;
507 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
508 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
510 /* DISPID_PICT_RENDER */
511 hdc
= create_render_dc();
513 for (i
= 0; i
< sizeof(args
)/sizeof(args
[0]); i
++)
514 V_VT(&args
[i
]) = VT_I4
;
525 V_I4(&args
[9]) = HandleToLong(hdc
);
527 dispparams
.rgvarg
= args
;
528 dispparams
.rgdispidNamedArgs
= NULL
;
529 dispparams
.cArgs
= 10;
530 dispparams
.cNamedArgs
= 0;
532 V_VT(&varresult
) = VT_EMPTY
;
533 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
534 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
536 /* Try with one argument set to VT_I2, it'd still work if coerced. */
537 V_VT(&args
[3]) = VT_I2
;
538 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
539 ok(hr
== DISP_E_TYPEMISMATCH
, "got 0x%08x\n", hr
);
540 V_VT(&args
[3]) = VT_I4
;
542 /* Wrong argument count */
543 dispparams
.cArgs
= 9;
544 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
545 ok(hr
== DISP_E_BADPARAMCOUNT
, "got 0x%08x\n", hr
);
547 delete_render_dc(hdc
);
548 IPictureDisp_Release(picdisp
);
551 static void test_OleCreatePictureIndirect(void)
560 /* crashes on native */
561 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, NULL
);
564 hr
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void**)&pict
);
565 ok(hr
== S_OK
, "hr %08x\n", hr
);
568 hr
= IPicture_get_Type(pict
, &type
);
569 ok(hr
== S_OK
, "hr %08x\n", hr
);
570 ok(type
== PICTYPE_UNINITIALIZED
, "type %d\n", type
);
573 hr
= IPicture_get_Handle(pict
, &handle
);
574 ok(hr
== S_OK
, "hr %08x\n", hr
);
575 ok(handle
== 0, "handle %08x\n", handle
);
577 IPicture_Release(pict
);
580 static void test_apm(void)
591 hglob
= GlobalAlloc (0, sizeof(apmdata
));
592 data
= GlobalLock(hglob
);
593 memcpy(data
, apmdata
, sizeof(apmdata
));
595 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
596 ole_check(pOleLoadPictureEx(stream
, sizeof(apmdata
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
));
598 ole_check(IPicture_get_Handle(pict
, &handle
));
599 ok(handle
!= 0, "handle is null\n");
601 ole_check(IPicture_get_Type(pict
, &type
));
602 expect_eq(type
, PICTYPE_METAFILE
, short, "%d");
604 ole_check(IPicture_get_Height(pict
, &cxy
));
605 expect_eq(cxy
, 1667, LONG
, "%d");
607 ole_check(IPicture_get_Width(pict
, &cxy
));
608 expect_eq(cxy
, 1323, LONG
, "%d");
610 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
611 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
613 ole_expect(IPicture_get_hPal(pict
, &handle
), E_FAIL
);
614 IPicture_Release(pict
);
615 IStream_Release(stream
);
618 static void test_metafile(void)
625 hglob
= GlobalAlloc (0, sizeof(metafile
));
626 data
= GlobalLock(hglob
);
627 memcpy(data
, metafile
, sizeof(metafile
));
629 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
630 /* Windows does not load simple metafiles */
631 ole_expect(pOleLoadPictureEx(stream
, sizeof(metafile
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
), E_FAIL
);
633 IStream_Release(stream
);
636 static void test_enhmetafile(void)
647 hglob
= GlobalAlloc (0, sizeof(enhmetafile
));
648 data
= GlobalLock(hglob
);
649 memcpy(data
, enhmetafile
, sizeof(enhmetafile
));
651 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
652 ole_check(pOleLoadPictureEx(stream
, sizeof(enhmetafile
), TRUE
, &IID_IPicture
, 10, 10, 0, (LPVOID
*)&pict
));
654 ole_check(IPicture_get_Handle(pict
, &handle
));
655 ok(handle
!= 0, "handle is null\n");
657 ole_check(IPicture_get_Type(pict
, &type
));
658 expect_eq(type
, PICTYPE_ENHMETAFILE
, short, "%d");
660 ole_check(IPicture_get_Height(pict
, &cxy
));
661 expect_eq(cxy
, -23, LONG
, "%d");
663 ole_check(IPicture_get_Width(pict
, &cxy
));
664 expect_eq(cxy
, -25, LONG
, "%d");
666 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
667 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
669 IPicture_Release(pict
);
670 IStream_Release(stream
);
673 static HRESULT
picture_render(IPicture
*iface
, HDC hdc
, LONG x
, LONG y
, LONG cx
, LONG cy
,
674 OLE_XPOS_HIMETRIC xSrc
,
675 OLE_YPOS_HIMETRIC ySrc
,
676 OLE_XSIZE_HIMETRIC cxSrc
,
677 OLE_YSIZE_HIMETRIC cySrc
,
680 VARIANT ret
, args
[10];
686 hr
= IPicture_Render(iface
, hdc
, x
, y
, cx
, cy
, xSrc
, ySrc
, cxSrc
, cySrc
, bounds
);
688 IPicture_QueryInterface(iface
, &IID_IDispatch
, (void**)&disp
);
690 /* This is broken on 64 bits - accepted pointer argument type is still VT_I4 */
691 for (i
= 0; i
< sizeof(args
)/sizeof(args
[0]); i
++)
692 V_VT(&args
[i
]) = VT_I4
;
694 /* pack arguments and call */
695 V_INT_PTR(&args
[0]) = (INT_PTR
)bounds
;
696 V_I4(&args
[1]) = cySrc
;
697 V_I4(&args
[2]) = cxSrc
;
698 V_I4(&args
[3]) = ySrc
;
699 V_I4(&args
[4]) = xSrc
;
704 V_I4(&args
[9]) = HandleToLong(hdc
);
706 params
.rgvarg
= args
;
707 params
.rgdispidNamedArgs
= NULL
;
709 params
.cNamedArgs
= 0;
711 V_VT(&ret
) = VT_EMPTY
;
712 hr_disp
= IDispatch_Invoke(disp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
,
713 ¶ms
, &ret
, NULL
, NULL
);
714 ok(hr
== hr_disp
, "DISPID_PICT_RENDER returned wrong code, 0x%08x, expected 0x%08x\n",
717 IDispatch_Release(disp
);
722 static void test_Render(void)
728 OLE_XSIZE_HIMETRIC pWidth
;
729 OLE_YSIZE_HIMETRIC pHeight
;
730 COLORREF result
, expected
;
731 HDC hdc
= create_render_dc();
733 /* test IPicture::Render return code on uninitialized picture */
734 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
735 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
736 hres
= IPicture_get_Type(pic
, &type
);
737 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
738 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
739 /* zero dimensions */
740 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
741 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
742 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
743 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
744 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
745 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
746 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
747 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
748 hres
= picture_render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
749 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
750 hres
= picture_render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
751 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
752 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
753 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
754 /* nonzero dimensions, PICTYPE_UNINITIALIZED */
755 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 10, NULL
);
756 ole_expect(hres
, S_OK
);
757 IPicture_Release(pic
);
759 desc
.cbSizeofstruct
= sizeof(PICTDESC
);
760 desc
.picType
= PICTYPE_ICON
;
761 desc
.icon
.hicon
= LoadIconA(NULL
, (LPCSTR
)IDI_APPLICATION
);
762 if(!desc
.icon
.hicon
){
763 win_skip("LoadIcon failed. Skipping...\n");
764 delete_render_dc(hdc
);
768 hres
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, TRUE
, (void **)&pic
);
769 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
770 /* zero dimensions, PICTYPE_ICON */
771 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
772 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
773 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
774 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
775 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
776 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
777 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
778 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
779 hres
= picture_render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
780 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
781 hres
= picture_render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
782 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
783 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
784 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
786 /* Check if target size and position is respected */
787 IPicture_get_Width(pic
, &pWidth
);
788 IPicture_get_Height(pic
, &pHeight
);
790 SetPixelV(hdc
, 0, 0, 0x00223344);
791 SetPixelV(hdc
, 5, 5, 0x00223344);
792 SetPixelV(hdc
, 10, 10, 0x00223344);
793 expected
= GetPixel(hdc
, 0, 0);
795 hres
= picture_render(pic
, hdc
, 1, 1, 9, 9, 0, 0, pWidth
, -pHeight
, NULL
);
796 ole_expect(hres
, S_OK
);
798 if(hres
!= S_OK
) goto done
;
800 /* Evaluate the rendered Icon */
801 result
= GetPixel(hdc
, 0, 0);
802 ok(result
== expected
,
803 "Color at 0,0 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
804 result
= GetPixel(hdc
, 5, 5);
805 ok(result
!= expected
,
806 "Color at 5,5 should have changed, but still was 0x%06X\n", expected
);
807 result
= GetPixel(hdc
, 10, 10);
808 ok(result
== expected
,
809 "Color at 10,10 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
812 IPicture_Release(pic
);
813 delete_render_dc(hdc
);
816 static void test_get_Attributes(void)
823 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
824 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
825 hres
= IPicture_get_Type(pic
, &type
);
826 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
827 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
829 hres
= IPicture_get_Attributes(pic
, NULL
);
830 ole_expect(hres
, E_POINTER
);
833 hres
= IPicture_get_Attributes(pic
, &attr
);
834 ole_expect(hres
, S_OK
);
835 ok(attr
== 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr
);
837 IPicture_Release(pic
);
840 static void test_get_Handle(void)
845 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
846 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
847 hres
= IPicture_get_Handle(pic
, NULL
);
848 ole_expect(hres
, E_POINTER
);
850 IPicture_Release(pic
);
853 static void test_get_Type(void)
858 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
859 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
861 hres
= IPicture_get_Type(pic
, NULL
);
862 ole_expect(hres
, E_POINTER
);
864 IPicture_Release(pic
);
867 static void test_OleLoadPicturePath(void)
869 static WCHAR emptyW
[] = {0};
874 char temp_path
[MAX_PATH
];
875 char temp_file
[MAX_PATH
];
876 WCHAR temp_fileW
[MAX_PATH
+ 5] = {'f','i','l','e',':','/','/','/'};
884 LPOLESTR szURLorPath
;
887 } invalid_parameters
[] =
891 {NULL
, &IID_IPicture
, NULL
},
892 {NULL
, &IID_IPicture
, &pic
},
893 {emptyW
, NULL
, NULL
},
894 {emptyW
, &IID_IPicture
, NULL
},
897 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
899 pic
= (IPicture
*)0xdeadbeef;
900 hres
= OleLoadPicturePath(invalid_parameters
[i
].szURLorPath
, NULL
, 0, 0,
901 invalid_parameters
[i
].riid
,
902 (void **)invalid_parameters
[i
].pic
);
903 ok(hres
== E_INVALIDARG
,
904 "[%d] Expected OleLoadPicturePath to return E_INVALIDARG, got 0x%08x\n", i
, hres
);
905 ok(pic
== (IPicture
*)0xdeadbeef,
906 "[%d] Expected output pointer to be 0xdeadbeef, got %p\n", i
, pic
);
909 pic
= (IPicture
*)0xdeadbeef;
910 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, NULL
, (void **)&pic
);
912 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
913 broken(hres
== E_UNEXPECTED
) || /* NT4 */
914 broken(hres
== E_OUTOFMEMORY
), /* Win2k/Win2k3 */
915 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
917 "Expected the output interface pointer to be NULL, got %p\n", pic
);
919 pic
= (IPicture
*)0xdeadbeef;
920 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
922 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
923 broken(hres
== E_UNEXPECTED
) || /* NT4 */
924 broken(hres
== E_OUTOFMEMORY
), /* Win2k/Win2k3 */
925 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
927 "Expected the output interface pointer to be NULL, got %p\n", pic
);
929 /* Create a local temporary image file for testing. */
930 GetTempPathA(sizeof(temp_path
), temp_path
);
931 GetTempFileNameA(temp_path
, "bmp", 0, temp_file
);
932 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
933 FILE_ATTRIBUTE_NORMAL
, NULL
);
934 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
937 MultiByteToWideChar(CP_ACP
, 0, temp_file
, -1, temp_fileW
+ 8, sizeof(temp_fileW
)/sizeof(WCHAR
) - 8);
939 /* Try a normal DOS path. */
940 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
942 broken(hres
== E_UNEXPECTED
), /* NT4 */
943 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
945 IPicture_Release(pic
);
948 V_VT(&var
) = VT_BSTR
;
949 V_BSTR(&var
) = SysAllocString(temp_fileW
+ 8);
950 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
951 ok(hres
== S_OK
, "OleLoadPictureFile error %#x\n", hres
);
952 IPicture_Release(pic
);
955 /* Try a DOS path with tacked on "file:". */
956 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
958 broken(hres
== E_UNEXPECTED
), /* NT4 */
959 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
961 IPicture_Release(pic
);
964 V_VT(&var
) = VT_BSTR
;
965 V_BSTR(&var
) = SysAllocString(temp_fileW
);
966 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
967 ok(hres
== CTL_E_PATHFILEACCESSERROR
, "wrong error %#x\n", hres
);
970 DeleteFileA(temp_file
);
972 /* Try with a nonexistent file. */
973 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
974 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
975 broken(hres
== E_UNEXPECTED
) || /* NT4 */
976 broken(hres
== E_FAIL
), /*Win2k */
977 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
980 V_VT(&var
) = VT_BSTR
;
981 V_BSTR(&var
) = SysAllocString(temp_fileW
+ 8);
982 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
983 ok(hres
== CTL_E_FILENOTFOUND
, "wrong error %#x\n", hres
);
986 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
987 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
988 broken(hres
== E_UNEXPECTED
) || /* NT4 */
989 broken(hres
== E_FAIL
), /* Win2k */
990 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
993 V_VT(&var
) = VT_BSTR
;
994 V_BSTR(&var
) = SysAllocString(temp_fileW
);
995 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
996 ok(hres
== CTL_E_PATHFILEACCESSERROR
, "wrong error %#x\n", hres
);
999 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1000 FILE_ATTRIBUTE_NORMAL
, NULL
);
1001 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
1004 /* Try a "file:" URL with slash separators. */
1005 ptr
= temp_fileW
+ 8;
1013 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
1015 broken(hres
== E_UNEXPECTED
), /* NT4 */
1016 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
1018 IPicture_Release(pic
);
1021 V_VT(&var
) = VT_BSTR
;
1022 V_BSTR(&var
) = SysAllocString(temp_fileW
);
1023 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
1024 ok(hres
== CTL_E_PATHFILEACCESSERROR
, "wrong error %#x\n", hres
);
1027 DeleteFileA(temp_file
);
1029 /* Try with a nonexistent file. */
1030 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
1031 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
1032 broken(hres
== E_UNEXPECTED
) || /* NT4 */
1033 broken(hres
== E_FAIL
), /* Win2k */
1034 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
1037 V_VT(&var
) = VT_BSTR
;
1038 V_BSTR(&var
) = SysAllocString(temp_fileW
);
1039 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
1040 ok(hres
== CTL_E_PATHFILEACCESSERROR
, "wrong error %#x\n", hres
);
1044 V_VT(&var
) = VT_INT
;
1046 hres
= OleLoadPictureFile(var
, (IDispatch
**)&pic
);
1047 ok(hres
== CTL_E_FILENOTFOUND
, "wrong error %#x\n", hres
);
1049 if (0) /* crashes under Windows */
1050 hres
= OleLoadPictureFile(var
, NULL
);
1053 static void test_himetric(void)
1055 static const BYTE bmp_bits
[1024];
1056 OLE_XSIZE_HIMETRIC cx
;
1057 OLE_YSIZE_HIMETRIC cy
;
1066 desc
.cbSizeofstruct
= sizeof(desc
);
1067 desc
.picType
= PICTYPE_BITMAP
;
1068 desc
.bmp
.hpal
= NULL
;
1070 hdc
= CreateCompatibleDC(0);
1072 bmp
= CreateBitmap(1.9 * GetDeviceCaps(hdc
, LOGPIXELSX
),
1073 1.9 * GetDeviceCaps(hdc
, LOGPIXELSY
), 1, 1, NULL
);
1075 desc
.bmp
.hbitmap
= bmp
;
1077 /* size in himetric units reported rounded up to next integer value */
1078 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1079 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1082 d
= MulDiv((INT
)(1.9 * GetDeviceCaps(hdc
, LOGPIXELSX
)), 2540, GetDeviceCaps(hdc
, LOGPIXELSX
));
1083 hr
= IPicture_get_Width(pic
, &cx
);
1084 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1085 ok(cx
== d
, "got %d, expected %d\n", cx
, d
);
1088 d
= MulDiv((INT
)(1.9 * GetDeviceCaps(hdc
, LOGPIXELSY
)), 2540, GetDeviceCaps(hdc
, LOGPIXELSY
));
1089 hr
= IPicture_get_Height(pic
, &cy
);
1090 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1091 ok(cy
== d
, "got %d, expected %d\n", cy
, d
);
1094 IPicture_Release(pic
);
1096 /* same thing with icon */
1097 icon
= CreateIcon(NULL
, GetSystemMetrics(SM_CXICON
), GetSystemMetrics(SM_CYICON
),
1098 1, 1, bmp_bits
, bmp_bits
);
1099 ok(icon
!= NULL
, "failed to create icon\n");
1101 desc
.picType
= PICTYPE_ICON
;
1102 desc
.icon
.hicon
= icon
;
1104 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1105 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1108 d
= MulDiv(GetSystemMetrics(SM_CXICON
), 2540, GetDeviceCaps(hdc
, LOGPIXELSX
));
1109 hr
= IPicture_get_Width(pic
, &cx
);
1110 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1111 ok(cx
== d
, "got %d, expected %d\n", cx
, d
);
1114 d
= MulDiv(GetSystemMetrics(SM_CYICON
), 2540, GetDeviceCaps(hdc
, LOGPIXELSY
));
1115 hr
= IPicture_get_Height(pic
, &cy
);
1116 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1117 ok(cy
== d
, "got %d, expected %d\n", cy
, d
);
1119 IPicture_Release(pic
);
1125 static void test_load_save_bmp(void)
1133 IPersistStream
*src_stream
;
1134 IStream
*dst_stream
;
1135 LARGE_INTEGER offset
;
1139 desc
.cbSizeofstruct
= sizeof(desc
);
1140 desc
.picType
= PICTYPE_BITMAP
;
1142 desc
.bmp
.hbitmap
= CreateBitmap(1, 1, 1, 1, NULL
);
1143 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1144 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1147 hr
= IPicture_get_Type(pic
, &type
);
1148 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1149 ok(type
== PICTYPE_BITMAP
,"expected picture type PICTYPE_BITMAP, got %d\n", type
);
1151 hr
= IPicture_get_Handle(pic
, &handle
);
1152 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1153 ok(IntToPtr(handle
) == desc
.bmp
.hbitmap
, "get_Handle returned wrong handle %#x\n", handle
);
1155 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 4096);
1156 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1157 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1160 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1161 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1162 ok(size
== 66, "expected 66, got %d\n", size
);
1163 mem
= GlobalLock(hmem
);
1164 ok(!memcmp(&mem
[0], "BM", 2), "got wrong bmp header %04x\n", mem
[0]);
1168 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1169 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1170 ok(size
== -1, "expected -1, got %d\n", size
);
1172 offset
.QuadPart
= 0;
1173 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1174 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1176 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1177 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1179 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1180 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1182 IPersistStream_Release(src_stream
);
1183 IStream_Release(dst_stream
);
1185 mem
= GlobalLock(hmem
);
1186 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1187 ok(mem
[1] == 66, "expected stream size 66, got %u\n", mem
[1]);
1188 ok(!memcmp(&mem
[2], "BM", 2), "got wrong bmp header %04x\n", mem
[2]);
1193 DeleteObject(desc
.bmp
.hbitmap
);
1194 IPicture_Release(pic
);
1197 static void test_load_save_icon(void)
1205 IPersistStream
*src_stream
;
1206 IStream
*dst_stream
;
1207 LARGE_INTEGER offset
;
1211 desc
.cbSizeofstruct
= sizeof(desc
);
1212 desc
.picType
= PICTYPE_ICON
;
1213 desc
.icon
.hicon
= LoadIconA(NULL
, (LPCSTR
)IDI_APPLICATION
);
1214 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1215 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1218 hr
= IPicture_get_Type(pic
, &type
);
1219 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1220 ok(type
== PICTYPE_ICON
,"expected picture type PICTYPE_ICON, got %d\n", type
);
1222 hr
= IPicture_get_Handle(pic
, &handle
);
1223 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1224 ok(IntToPtr(handle
) == desc
.icon
.hicon
, "get_Handle returned wrong handle %#x\n", handle
);
1226 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 8192);
1227 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1228 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
1231 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1232 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1234 ok(size
== 766, "expected 766, got %d\n", size
);
1235 mem
= GlobalLock(hmem
);
1236 ok(mem
[0] == 0x00010000, "got wrong icon header %04x\n", mem
[0]);
1240 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1241 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1242 ok(size
== -1, "expected -1, got %d\n", size
);
1244 offset
.QuadPart
= 0;
1245 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1246 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1248 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1249 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1251 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1252 ok(hr
== S_OK
, "Saveerror %#x\n", hr
);
1254 IPersistStream_Release(src_stream
);
1255 IStream_Release(dst_stream
);
1257 mem
= GlobalLock(hmem
);
1258 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1260 ok(mem
[1] == 766, "expected stream size 766, got %u\n", mem
[1]);
1261 ok(mem
[2] == 0x00010000, "got wrong icon header %04x\n", mem
[2]);
1266 DestroyIcon(desc
.icon
.hicon
);
1267 IPicture_Release(pic
);
1270 static void test_load_save_empty_picture(void)
1278 IPersistStream
*src_stream
;
1279 IStream
*dst_stream
, *stream
;
1280 LARGE_INTEGER offset
;
1284 memset(&pic
, 0, sizeof(pic
));
1285 desc
.cbSizeofstruct
= sizeof(desc
);
1286 desc
.picType
= PICTYPE_NONE
;
1287 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void **)&pic
);
1288 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1291 hr
= IPicture_get_Type(pic
, &type
);
1292 ok(hr
== S_OK
, "get_Type error %#x\n", hr
);
1293 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1295 handle
= (OLE_HANDLE
)0xdeadbeef;
1296 hr
= IPicture_get_Handle(pic
, &handle
);
1297 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1298 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1300 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 4096);
1301 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1302 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1305 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1306 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1307 ok(size
== -1, "expected -1, got %d\n", size
);
1310 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1311 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1312 ok(size
== -1, "expected -1, got %d\n", size
);
1314 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1315 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1317 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1318 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1320 mem
= GlobalLock(hmem
);
1321 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1322 ok(mem
[1] == 0, "expected stream size 0, got %u\n", mem
[1]);
1325 IPersistStream_Release(src_stream
);
1326 IPicture_Release(pic
);
1328 /* first with statable and seekable stream */
1329 offset
.QuadPart
= 0;
1330 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1331 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1334 hr
= pOleLoadPicture(dst_stream
, 0, FALSE
, &IID_IPicture
, (void **)&pic
);
1335 ok(hr
== S_OK
, "OleLoadPicture error %#x\n", hr
);
1336 ok(pic
!= NULL
,"picture should not be not NULL\n");
1340 hr
= IPicture_get_Type(pic
, &type
);
1341 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1342 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1344 handle
= (OLE_HANDLE
)0xdeadbeef;
1345 hr
= IPicture_get_Handle(pic
, &handle
);
1346 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1347 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1349 IPicture_Release(pic
);
1351 IStream_Release(dst_stream
);
1353 /* again with non-statable and non-seekable stream */
1354 stream
= NoStatStream_Construct(hmem
);
1355 ok(stream
!= NULL
, "failed to create empty image stream\n");
1358 hr
= pOleLoadPicture(stream
, 0, FALSE
, &IID_IPicture
, (void **)&pic
);
1359 ok(hr
== S_OK
, "OleLoadPicture error %#x\n", hr
);
1360 ok(pic
!= NULL
,"picture should not be not NULL\n");
1364 hr
= IPicture_get_Type(pic
, &type
);
1365 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1366 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1368 handle
= (OLE_HANDLE
)0xdeadbeef;
1369 hr
= IPicture_get_Handle(pic
, &handle
);
1370 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1371 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1373 IPicture_Release(pic
);
1375 /* Non-statable impl always deletes on release */
1376 IStream_Release(stream
);
1379 static void test_load_save_emf(void)
1389 IPersistStream
*src_stream
;
1390 IStream
*dst_stream
;
1391 LARGE_INTEGER offset
;
1395 hdc
= CreateEnhMetaFileA(0, NULL
, NULL
, NULL
);
1396 ok(hdc
!= 0, "CreateEnhMetaFileA failed\n");
1398 desc
.cbSizeofstruct
= sizeof(desc
);
1399 desc
.picType
= PICTYPE_ENHMETAFILE
;
1400 desc
.emf
.hemf
= CloseEnhMetaFile(hdc
);
1401 ok(desc
.emf
.hemf
!= 0, "CloseEnhMetaFile failed\n");
1402 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1403 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1406 hr
= IPicture_get_Type(pic
, &type
);
1407 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1408 ok(type
== PICTYPE_ENHMETAFILE
,"expected PICTYPE_ENHMETAFILE, got %d\n", type
);
1410 hr
= IPicture_get_Handle(pic
, &handle
);
1411 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1412 ok(IntToPtr(handle
) == desc
.emf
.hemf
, "get_Handle returned wrong handle %#x\n", handle
);
1414 hmem
= GlobalAlloc(GMEM_MOVEABLE
, 0);
1415 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1416 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1419 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1420 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1421 ok(size
== 128, "expected 128, got %d\n", size
);
1422 emh
= GlobalLock(hmem
);
1425 ok(emh
->iType
== EMR_HEADER
, "wrong iType %04x\n", emh
->iType
);
1426 ok(emh
->dSignature
== ENHMETA_SIGNATURE
, "wrong dSignature %08x\n", emh
->dSignature
);
1431 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1432 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1433 ok(size
== -1, "expected -1, got %d\n", size
);
1435 offset
.QuadPart
= 0;
1436 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1437 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1439 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1440 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1442 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1443 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1445 IPersistStream_Release(src_stream
);
1446 IStream_Release(dst_stream
);
1448 mem
= GlobalLock(hmem
);
1449 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1450 ok(mem
[1] == 128, "expected 128, got %u\n", mem
[1]);
1451 emh
= (ENHMETAHEADER
*)(mem
+ 2);
1452 ok(emh
->iType
== EMR_HEADER
, "wrong iType %04x\n", emh
->iType
);
1453 ok(emh
->dSignature
== ENHMETA_SIGNATURE
, "wrong dSignature %08x\n", emh
->dSignature
);
1458 DeleteEnhMetaFile(desc
.emf
.hemf
);
1459 IPicture_Release(pic
);
1462 START_TEST(olepicture
)
1464 hOleaut32
= GetModuleHandleA("oleaut32.dll");
1465 pOleLoadPicture
= (void*)GetProcAddress(hOleaut32
, "OleLoadPicture");
1466 pOleLoadPictureEx
= (void*)GetProcAddress(hOleaut32
, "OleLoadPictureEx");
1467 if (!pOleLoadPicture
)
1469 win_skip("OleLoadPicture is not available\n");
1473 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
1474 test_pic(gifimage
, sizeof(gifimage
));
1475 test_pic(jpgimage
, sizeof(jpgimage
));
1476 test_pic(bmpimage
, sizeof(bmpimage
));
1477 test_pic(bmpimage_rle8
, sizeof(bmpimage_rle8
));
1478 test_pic(gif4pixel
, sizeof(gif4pixel
));
1479 /* FIXME: No PNG support in Windows... */
1480 if (0) test_pic(pngimage
, sizeof(pngimage
));
1482 test_empty_image_2();
1483 if (pOleLoadPictureEx
)
1490 win_skip("OleLoadPictureEx is not available\n");
1492 test_OleCreatePictureIndirect();
1494 test_get_Attributes();
1497 test_OleLoadPicturePath();
1499 test_load_save_bmp();
1500 test_load_save_icon();
1501 test_load_save_empty_picture();
1502 test_load_save_emf();
1506 /* Helper functions only ... */
1509 static inline NoStatStreamImpl
*impl_from_IStream(IStream
*iface
)
1511 return CONTAINING_RECORD(iface
, NoStatStreamImpl
, IStream_iface
);
1514 static void NoStatStreamImpl_Destroy(NoStatStreamImpl
* This
)
1516 GlobalFree(This
->supportHandle
);
1517 This
->supportHandle
=0;
1518 HeapFree(GetProcessHeap(), 0, This
);
1521 static ULONG WINAPI
NoStatStreamImpl_AddRef(
1524 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1525 return InterlockedIncrement(&This
->ref
);
1528 static HRESULT WINAPI
NoStatStreamImpl_QueryInterface(
1530 REFIID riid
, /* [in] */
1531 void** ppvObject
) /* [iid_is][out] */
1533 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1534 if (ppvObject
==0) return E_INVALIDARG
;
1537 if (IsEqualIID(&IID_IUnknown
, riid
) || IsEqualIID(&IID_IStream
, riid
))
1538 *ppvObject
= &This
->IStream_iface
;
1540 if ((*ppvObject
)==0)
1541 return E_NOINTERFACE
;
1542 NoStatStreamImpl_AddRef(iface
);
1546 static ULONG WINAPI
NoStatStreamImpl_Release(
1549 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1550 ULONG newRef
= InterlockedDecrement(&This
->ref
);
1552 NoStatStreamImpl_Destroy(This
);
1556 static HRESULT WINAPI
NoStatStreamImpl_Read(
1558 void* pv
, /* [length_is][size_is][out] */
1559 ULONG cb
, /* [in] */
1560 ULONG
* pcbRead
) /* [out] */
1562 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1563 void* supportBuffer
;
1564 ULONG bytesReadBuffer
;
1565 ULONG bytesToReadFromBuffer
;
1568 pcbRead
= &bytesReadBuffer
;
1569 bytesToReadFromBuffer
= min( This
->streamSize
.u
.LowPart
- This
->currentPosition
.u
.LowPart
, cb
);
1570 supportBuffer
= GlobalLock(This
->supportHandle
);
1571 memcpy(pv
, (char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, bytesToReadFromBuffer
);
1572 This
->currentPosition
.u
.LowPart
+=bytesToReadFromBuffer
;
1573 *pcbRead
= bytesToReadFromBuffer
;
1574 GlobalUnlock(This
->supportHandle
);
1580 static HRESULT WINAPI
NoStatStreamImpl_Write(
1582 const void* pv
, /* [size_is][in] */
1583 ULONG cb
, /* [in] */
1584 ULONG
* pcbWritten
) /* [out] */
1586 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1587 void* supportBuffer
;
1588 ULARGE_INTEGER newSize
;
1589 ULONG bytesWritten
= 0;
1591 if (pcbWritten
== 0)
1592 pcbWritten
= &bytesWritten
;
1595 newSize
.u
.HighPart
= 0;
1596 newSize
.u
.LowPart
= This
->currentPosition
.u
.LowPart
+ cb
;
1597 if (newSize
.u
.LowPart
> This
->streamSize
.u
.LowPart
)
1598 IStream_SetSize(iface
, newSize
);
1600 supportBuffer
= GlobalLock(This
->supportHandle
);
1601 memcpy((char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, pv
, cb
);
1602 This
->currentPosition
.u
.LowPart
+=cb
;
1604 GlobalUnlock(This
->supportHandle
);
1608 static HRESULT WINAPI
NoStatStreamImpl_Seek(
1610 LARGE_INTEGER dlibMove
, /* [in] */
1611 DWORD dwOrigin
, /* [in] */
1612 ULARGE_INTEGER
* plibNewPosition
) /* [out] */
1614 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1615 ULARGE_INTEGER newPosition
;
1618 case STREAM_SEEK_SET
:
1619 newPosition
.u
.HighPart
= 0;
1620 newPosition
.u
.LowPart
= 0;
1622 case STREAM_SEEK_CUR
:
1623 newPosition
= This
->currentPosition
;
1625 case STREAM_SEEK_END
:
1626 newPosition
= This
->streamSize
;
1629 return STG_E_INVALIDFUNCTION
;
1631 if (dlibMove
.QuadPart
< 0 && newPosition
.QuadPart
< -dlibMove
.QuadPart
)
1632 return STG_E_INVALIDFUNCTION
;
1633 newPosition
.QuadPart
+= dlibMove
.QuadPart
;
1634 if (plibNewPosition
) *plibNewPosition
= newPosition
;
1635 This
->currentPosition
= newPosition
;
1639 static HRESULT WINAPI
NoStatStreamImpl_SetSize(
1641 ULARGE_INTEGER libNewSize
) /* [in] */
1643 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1644 HGLOBAL supportHandle
;
1645 if (libNewSize
.u
.HighPart
!= 0)
1646 return STG_E_INVALIDFUNCTION
;
1647 if (This
->streamSize
.u
.LowPart
== libNewSize
.u
.LowPart
)
1649 supportHandle
= GlobalReAlloc(This
->supportHandle
, libNewSize
.u
.LowPart
, 0);
1650 if (supportHandle
== 0)
1651 return STG_E_MEDIUMFULL
;
1652 This
->supportHandle
= supportHandle
;
1653 This
->streamSize
.u
.LowPart
= libNewSize
.u
.LowPart
;
1657 static HRESULT WINAPI
NoStatStreamImpl_CopyTo(
1659 IStream
* pstm
, /* [unique][in] */
1660 ULARGE_INTEGER cb
, /* [in] */
1661 ULARGE_INTEGER
* pcbRead
, /* [out] */
1662 ULARGE_INTEGER
* pcbWritten
) /* [out] */
1665 BYTE tmpBuffer
[128];
1666 ULONG bytesRead
, bytesWritten
, copySize
;
1667 ULARGE_INTEGER totalBytesRead
;
1668 ULARGE_INTEGER totalBytesWritten
;
1671 return STG_E_INVALIDPOINTER
;
1672 totalBytesRead
.u
.LowPart
= totalBytesRead
.u
.HighPart
= 0;
1673 totalBytesWritten
.u
.LowPart
= totalBytesWritten
.u
.HighPart
= 0;
1675 while ( cb
.u
.LowPart
> 0 )
1677 if ( cb
.u
.LowPart
>= 128 )
1680 copySize
= cb
.u
.LowPart
;
1681 IStream_Read(iface
, tmpBuffer
, copySize
, &bytesRead
);
1682 totalBytesRead
.u
.LowPart
+= bytesRead
;
1683 IStream_Write(pstm
, tmpBuffer
, bytesRead
, &bytesWritten
);
1684 totalBytesWritten
.u
.LowPart
+= bytesWritten
;
1685 if (bytesRead
!= bytesWritten
)
1687 hr
= STG_E_MEDIUMFULL
;
1690 if (bytesRead
!=copySize
)
1693 cb
.u
.LowPart
-= bytesRead
;
1697 pcbRead
->u
.LowPart
= totalBytesRead
.u
.LowPart
;
1698 pcbRead
->u
.HighPart
= totalBytesRead
.u
.HighPart
;
1703 pcbWritten
->u
.LowPart
= totalBytesWritten
.u
.LowPart
;
1704 pcbWritten
->u
.HighPart
= totalBytesWritten
.u
.HighPart
;
1709 static HRESULT WINAPI
NoStatStreamImpl_Commit(IStream
* iface
,DWORD grfCommitFlags
)
1713 static HRESULT WINAPI
NoStatStreamImpl_Revert(IStream
* iface
) { return S_OK
; }
1715 static HRESULT WINAPI
NoStatStreamImpl_LockRegion(
1717 ULARGE_INTEGER libOffset
, /* [in] */
1718 ULARGE_INTEGER cb
, /* [in] */
1719 DWORD dwLockType
) /* [in] */
1724 static HRESULT WINAPI
NoStatStreamImpl_UnlockRegion(
1726 ULARGE_INTEGER libOffset
, /* [in] */
1727 ULARGE_INTEGER cb
, /* [in] */
1728 DWORD dwLockType
) /* [in] */
1733 static HRESULT WINAPI
NoStatStreamImpl_Stat(
1735 STATSTG
* pstatstg
, /* [out] */
1736 DWORD grfStatFlag
) /* [in] */
1741 static HRESULT WINAPI
NoStatStreamImpl_Clone(
1743 IStream
** ppstm
) /* [out] */
1747 static const IStreamVtbl NoStatStreamImpl_Vtbl
;
1750 Build an object that implements IStream, without IStream_Stat capabilities.
1751 Receives a memory handle with data buffer. If memory handle is non-null,
1752 it is assumed to be unlocked, otherwise an internal memory handle is allocated.
1753 In any case the object takes ownership of memory handle and will free it on
1756 static IStream
* NoStatStream_Construct(HGLOBAL hGlobal
)
1758 NoStatStreamImpl
* newStream
;
1760 newStream
= HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl
));
1763 newStream
->IStream_iface
.lpVtbl
= &NoStatStreamImpl_Vtbl
;
1765 newStream
->supportHandle
= hGlobal
;
1767 if (!newStream
->supportHandle
)
1768 newStream
->supportHandle
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
|
1770 newStream
->currentPosition
.u
.HighPart
= 0;
1771 newStream
->currentPosition
.u
.LowPart
= 0;
1772 newStream
->streamSize
.u
.HighPart
= 0;
1773 newStream
->streamSize
.u
.LowPart
= GlobalSize(newStream
->supportHandle
);
1775 return &newStream
->IStream_iface
;
1779 static const IStreamVtbl NoStatStreamImpl_Vtbl
=
1781 NoStatStreamImpl_QueryInterface
,
1782 NoStatStreamImpl_AddRef
,
1783 NoStatStreamImpl_Release
,
1784 NoStatStreamImpl_Read
,
1785 NoStatStreamImpl_Write
,
1786 NoStatStreamImpl_Seek
,
1787 NoStatStreamImpl_SetSize
,
1788 NoStatStreamImpl_CopyTo
,
1789 NoStatStreamImpl_Commit
,
1790 NoStatStreamImpl_Revert
,
1791 NoStatStreamImpl_LockRegion
,
1792 NoStatStreamImpl_UnlockRegion
,
1793 NoStatStreamImpl_Stat
,
1794 NoStatStreamImpl_Clone