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
22 #define WIN32_NO_STATUS
24 #define COM_NO_WINDOWS_H
33 #define NONAMELESSUNION
35 #include <wine/test.h>
37 //#include <winbase.h>
38 //#include <winuser.h>
41 //#include <winerror.h>
49 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
51 #define ole_expect(expr, expect) { \
53 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
56 #define ole_check(expr) ole_expect(expr, S_OK);
58 static HMODULE hOleaut32
;
60 static HRESULT (WINAPI
*pOleLoadPicture
)(LPSTREAM
,LONG
,BOOL
,REFIID
,LPVOID
*);
61 static HRESULT (WINAPI
*pOleLoadPictureEx
)(LPSTREAM
,LONG
,BOOL
,REFIID
,DWORD
,DWORD
,DWORD
,LPVOID
*);
63 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
66 static const unsigned char gifimage
[35] = {
67 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
68 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
73 static const unsigned char jpgimage
[285] = {
74 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
75 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
76 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
77 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
78 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
79 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
80 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
81 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
82 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
83 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
84 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
85 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
86 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
87 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
88 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
89 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
90 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
91 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
95 static const unsigned char pngimage
[285] = {
96 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
97 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
98 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
99 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
100 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
101 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
102 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
106 static const unsigned char bmpimage
[66] = {
107 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
108 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
109 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
110 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
115 static const unsigned char gif4pixel
[42] = {
116 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
117 0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
118 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
121 /* APM with an empty metafile with some padding zeros - looks like under Window the
122 * metafile data should be at least 20 bytes */
123 static const unsigned char apmdata
[] = {
124 0xd7,0xcd,0xc6,0x9a, 0x00,0x00,0x00,0x00, 0x00,0x00,0xee,0x02, 0xb1,0x03,0xa0,0x05,
125 0x00,0x00,0x00,0x00, 0xee,0x53,0x01,0x00, 0x09,0x00,0x00,0x03, 0x13,0x00,0x00,0x00,
126 0x01,0x00,0x05,0x00, 0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
127 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
130 /* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
131 static const unsigned char metafile
[] = {
132 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
135 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
136 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
137 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
141 /* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
142 static const unsigned char enhmetafile
[] = {
143 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
148 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
149 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
150 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
153 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
156 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
157 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
158 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
160 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
162 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
163 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
166 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
167 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
168 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
169 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
170 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
171 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
173 0x14, 0x00, 0x00, 0x00
177 typedef struct NoStatStreamImpl
179 IStream IStream_iface
;
182 HGLOBAL supportHandle
;
183 ULARGE_INTEGER streamSize
;
184 ULARGE_INTEGER currentPosition
;
187 static IStream
* NoStatStream_Construct(HGLOBAL hGlobal
);
190 test_pic_with_stream(LPSTREAM stream
, unsigned int imgsize
)
192 IPicture
* pic
= NULL
;
195 OLE_HANDLE handle
, hPal
;
196 OLE_XSIZE_HIMETRIC width
;
197 OLE_YSIZE_HIMETRIC height
;
203 hres
= pOleLoadPicture(stream
, imgsize
, TRUE
, &IID_IPicture
, &pvObj
);
206 ok(hres
== S_OK
,"OLP (NULL,..) does not return 0, but 0x%08x\n",hres
);
207 ok(pic
!= NULL
,"OLP (NULL,..) returns NULL, instead of !NULL\n");
212 hres
= IPicture_QueryInterface (pic
, &IID_IPicture
, &pvObj
);
214 ok(hres
== S_OK
,"IPicture_QI does not return S_OK, but 0x%08x\n", hres
);
215 ok(pvObj
!= NULL
,"IPicture_QI does return NULL, instead of a ptr\n");
217 IPicture_Release ((IPicture
*)pvObj
);
220 hres
= IPicture_get_Handle (pic
, &handle
);
221 ok(hres
== S_OK
,"IPicture_get_Handle does not return S_OK, but 0x%08x\n", hres
);
222 ok(handle
!= 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
227 GetObjectA(UlongToHandle(handle
), sizeof(BITMAP
), &bmp
);
228 todo_wine
ok(bmp
.bmBits
!= 0, "not a dib\n");
232 hres
= IPicture_get_Width (pic
, &width
);
233 ok(hres
== S_OK
,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres
);
234 ok(width
!= 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
237 hres
= IPicture_get_Height (pic
, &height
);
238 ok(hres
== S_OK
,"IPicture_get_Height does not return S_OK, but 0x%08x\n", hres
);
239 ok(height
!= 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
242 hres
= IPicture_get_Type (pic
, &type
);
243 ok(hres
== S_OK
,"IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
244 ok(type
== PICTYPE_BITMAP
, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type
, PICTYPE_BITMAP
);
247 hres
= IPicture_get_Attributes (pic
, &attr
);
248 ok(hres
== S_OK
,"IPicture_get_Attributes does not return S_OK, but 0x%08x\n", hres
);
249 ok(attr
== 0, "IPicture_get_Attributes returns %d, but it should be 0.\n", attr
);
252 hres
= IPicture_get_hPal (pic
, &hPal
);
253 ok(hres
== S_OK
,"IPicture_get_hPal does not return S_OK, but 0x%08x\n", hres
);
254 /* a single pixel b/w image has no palette */
255 ok(hPal
== 0, "IPicture_get_hPal returns %d, but it should be 0.\n", hPal
);
257 res
= IPicture_Release (pic
);
258 ok (res
== 0, "refcount after release is %d, but should be 0?\n", res
);
262 test_pic(const unsigned char *imgdata
, unsigned int imgsize
)
268 LARGE_INTEGER seekto
;
269 ULARGE_INTEGER newpos1
;
273 /* Let the fun begin */
274 hglob
= GlobalAlloc (0, imgsize
);
275 data
= GlobalLock (hglob
);
276 memcpy(data
, imgdata
, imgsize
);
277 GlobalUnlock(hglob
); data
= NULL
;
279 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
280 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
282 memset(&seekto
,0,sizeof(seekto
));
283 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
284 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
285 test_pic_with_stream(stream
, imgsize
);
287 IStream_Release(stream
);
289 /* again with Non Statable and Non Seekable stream */
290 stream
= NoStatStream_Construct(hglob
);
291 hglob
= 0; /* Non-statable impl always deletes on release */
292 test_pic_with_stream(stream
, 0);
294 IStream_Release(stream
);
295 for (i
= 1; i
<= 8; i
++) {
297 hglob
= GlobalAlloc (0, imgsize
+ i
* (2 * sizeof(DWORD
)));
298 data
= GlobalLock (hglob
);
299 header
= (DWORD
*)data
;
301 /* multiple copies of header */
302 memcpy(data
,"lt\0\0",4);
304 for (j
= 2; j
<= i
; j
++) {
305 memcpy(&(header
[2 * (j
- 1)]), header
, 2 * sizeof(DWORD
));
307 memcpy(data
+ i
* (2 * sizeof(DWORD
)), imgdata
, imgsize
);
308 GlobalUnlock(hglob
); data
= NULL
;
310 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
311 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
313 memset(&seekto
,0,sizeof(seekto
));
314 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
315 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
316 test_pic_with_stream(stream
, imgsize
);
318 IStream_Release(stream
);
320 /* again with Non Statable and Non Seekable stream */
321 stream
= NoStatStream_Construct(hglob
);
322 hglob
= 0; /* Non-statable impl always deletes on release */
323 test_pic_with_stream(stream
, 0);
325 IStream_Release(stream
);
329 static void test_empty_image(void) {
332 IPicture
* pic
= NULL
;
337 ULARGE_INTEGER newpos1
;
338 LARGE_INTEGER seekto
;
342 /* Empty image. Happens occasionally in VB programs. */
343 hglob
= GlobalAlloc (0, 8);
344 data
= GlobalLock (hglob
);
345 memcpy(data
,"lt\0\0",4);
346 ((DWORD
*)data
)[1] = 0;
347 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
348 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
350 memset(&seekto
,0,sizeof(seekto
));
351 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
352 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
355 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
357 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
358 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
360 hres
= IPicture_get_Type (pic
, &type
);
361 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
362 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
365 hres
= IPicture_get_Attributes (pic
, &attr
);
366 ok (hres
== S_OK
,"empty picture get attributes failed with hres 0x%08x\n", hres
);
367 ok (attr
== 0,"attr is %d, but should be 0\n", attr
);
369 hres
= IPicture_get_Handle (pic
, &handle
);
370 ok (hres
== S_OK
,"empty picture get handle failed with hres 0x%08x\n", hres
);
371 ok (handle
== 0, "empty picture get handle did not return 0, but 0x%08x\n", handle
);
372 IPicture_Release (pic
);
373 IStream_Release (stream
);
376 static void test_empty_image_2(void) {
379 IPicture
* pic
= NULL
;
383 ULARGE_INTEGER newpos1
;
384 LARGE_INTEGER seekto
;
387 /* Empty image at random stream position. */
388 hglob
= GlobalAlloc (0, 200);
389 data
= GlobalLock (hglob
);
391 memcpy(data
,"lt\0\0",4);
392 ((DWORD
*)data
)[1] = 0;
393 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
394 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
396 memset(&seekto
,0,sizeof(seekto
));
397 seekto
.u
.LowPart
= 42;
398 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
399 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
402 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
404 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
405 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
407 hres
= IPicture_get_Type (pic
, &type
);
408 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
409 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
411 IPicture_Release (pic
);
412 IStream_Release (stream
);
415 static void test_Invoke(void)
417 IPictureDisp
*picdisp
;
419 VARIANTARG vararg
, args
[10];
420 DISPPARAMS dispparams
;
428 hglob
= GlobalAlloc (0, sizeof(gifimage
));
429 data
= GlobalLock(hglob
);
430 memcpy(data
, gifimage
, sizeof(gifimage
));
433 hr
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
434 ok_ole_success(hr
, "CreateStreamOnHGlobal");
436 hr
= pOleLoadPicture(stream
, sizeof(gifimage
), TRUE
, &IID_IPictureDisp
, (void **)&picdisp
);
437 IStream_Release(stream
);
439 ok_ole_success(hr
, "OleLoadPicture");
441 V_VT(&vararg
) = VT_BOOL
;
442 V_BOOL(&vararg
) = VARIANT_FALSE
;
443 dispparams
.cNamedArgs
= 0;
444 dispparams
.rgdispidNamedArgs
= NULL
;
445 dispparams
.cArgs
= 1;
446 dispparams
.rgvarg
= &vararg
;
447 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IPictureDisp
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
448 ok(hr
== DISP_E_UNKNOWNNAME
, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr
);
449 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IUnknown
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
450 ok(hr
== DISP_E_UNKNOWNNAME
, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr
);
452 dispparams
.cArgs
= 0;
453 dispparams
.rgvarg
= NULL
;
454 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
455 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
457 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, NULL
, NULL
, NULL
);
458 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
460 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, NULL
, NULL
, NULL
);
461 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
463 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, &varresult
, NULL
, NULL
);
464 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
466 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
467 ok_ole_success(hr
, "IPictureDisp_Invoke");
468 ok(V_VT(&varresult
) == VT_I4
, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult
));
470 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
471 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
473 hr
= IPictureDisp_Invoke(picdisp
, 0xdeadbeef, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
474 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
476 dispparams
.cArgs
= 1;
477 dispparams
.rgvarg
= &vararg
;
478 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
479 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
481 dispparams
.cArgs
= 1;
482 dispparams
.rgvarg
= &vararg
;
483 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
484 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
486 /* DISPID_PICT_RENDER */
489 for (i
= 0; i
< sizeof(args
)/sizeof(args
[0]); i
++)
490 V_VT(&args
[i
]) = VT_I4
;
501 V_I4(&args
[9]) = HandleToLong(hdc
);
503 dispparams
.rgvarg
= args
;
504 dispparams
.rgdispidNamedArgs
= NULL
;
505 dispparams
.cArgs
= 10;
506 dispparams
.cNamedArgs
= 0;
508 V_VT(&varresult
) = VT_EMPTY
;
509 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
510 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
512 /* Try with one argument set to VT_I2, it'd still work if coerced. */
513 V_VT(&args
[3]) = VT_I2
;
514 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
515 ok(hr
== DISP_E_TYPEMISMATCH
, "got 0x%08x\n", hr
);
516 V_VT(&args
[3]) = VT_I4
;
518 /* Wrong argument count */
519 dispparams
.cArgs
= 9;
520 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
521 ok(hr
== DISP_E_BADPARAMCOUNT
, "got 0x%08x\n", hr
);
523 ReleaseDC(NULL
, hdc
);
524 IPictureDisp_Release(picdisp
);
527 static void test_OleCreatePictureIndirect(void)
536 /* crashes on native */
537 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, NULL
);
540 hr
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void**)&pict
);
541 ok(hr
== S_OK
, "hr %08x\n", hr
);
544 hr
= IPicture_get_Type(pict
, &type
);
545 ok(hr
== S_OK
, "hr %08x\n", hr
);
546 ok(type
== PICTYPE_UNINITIALIZED
, "type %d\n", type
);
549 hr
= IPicture_get_Handle(pict
, &handle
);
550 ok(hr
== S_OK
, "hr %08x\n", hr
);
551 ok(handle
== 0, "handle %08x\n", handle
);
553 IPicture_Release(pict
);
556 static void test_apm(void)
567 hglob
= GlobalAlloc (0, sizeof(apmdata
));
568 data
= GlobalLock(hglob
);
569 memcpy(data
, apmdata
, sizeof(apmdata
));
571 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
572 ole_check(pOleLoadPictureEx(stream
, sizeof(apmdata
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
));
574 ole_check(IPicture_get_Handle(pict
, &handle
));
575 ok(handle
!= 0, "handle is null\n");
577 ole_check(IPicture_get_Type(pict
, &type
));
578 expect_eq(type
, PICTYPE_METAFILE
, short, "%d");
580 ole_check(IPicture_get_Height(pict
, &cxy
));
581 expect_eq(cxy
, 1667, LONG
, "%d");
583 ole_check(IPicture_get_Width(pict
, &cxy
));
584 expect_eq(cxy
, 1323, LONG
, "%d");
586 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
587 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
589 ole_expect(IPicture_get_hPal(pict
, &handle
), E_FAIL
);
590 IPicture_Release(pict
);
591 IStream_Release(stream
);
594 static void test_metafile(void)
601 hglob
= GlobalAlloc (0, sizeof(metafile
));
602 data
= GlobalLock(hglob
);
603 memcpy(data
, metafile
, sizeof(metafile
));
605 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
606 /* Windows does not load simple metafiles */
607 ole_expect(pOleLoadPictureEx(stream
, sizeof(metafile
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
), E_FAIL
);
609 IStream_Release(stream
);
612 static void test_enhmetafile(void)
623 hglob
= GlobalAlloc (0, sizeof(enhmetafile
));
624 data
= GlobalLock(hglob
);
625 memcpy(data
, enhmetafile
, sizeof(enhmetafile
));
627 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
628 ole_check(pOleLoadPictureEx(stream
, sizeof(enhmetafile
), TRUE
, &IID_IPicture
, 10, 10, 0, (LPVOID
*)&pict
));
630 ole_check(IPicture_get_Handle(pict
, &handle
));
631 ok(handle
!= 0, "handle is null\n");
633 ole_check(IPicture_get_Type(pict
, &type
));
634 expect_eq(type
, PICTYPE_ENHMETAFILE
, short, "%d");
636 ole_check(IPicture_get_Height(pict
, &cxy
));
637 expect_eq(cxy
, -23, LONG
, "%d");
639 ole_check(IPicture_get_Width(pict
, &cxy
));
640 expect_eq(cxy
, -25, LONG
, "%d");
642 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
643 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
645 IPicture_Release(pict
);
646 IStream_Release(stream
);
649 static HRESULT
picture_render(IPicture
*iface
, HDC hdc
, LONG x
, LONG y
, LONG cx
, LONG cy
,
650 OLE_XPOS_HIMETRIC xSrc
,
651 OLE_YPOS_HIMETRIC ySrc
,
652 OLE_XSIZE_HIMETRIC cxSrc
,
653 OLE_YSIZE_HIMETRIC cySrc
,
656 VARIANT ret
, args
[10];
662 hr
= IPicture_Render(iface
, hdc
, x
, y
, cx
, cy
, xSrc
, ySrc
, cxSrc
, cySrc
, bounds
);
664 IPicture_QueryInterface(iface
, &IID_IDispatch
, (void**)&disp
);
666 /* This is broken on 64 bits - accepted pointer argument type is still VT_I4 */
667 for (i
= 0; i
< sizeof(args
)/sizeof(args
[0]); i
++)
668 V_VT(&args
[i
]) = VT_I4
;
670 /* pack arguments and call */
671 V_INT_PTR(&args
[0]) = (INT_PTR
)bounds
;
672 V_I4(&args
[1]) = cySrc
;
673 V_I4(&args
[2]) = cxSrc
;
674 V_I4(&args
[3]) = ySrc
;
675 V_I4(&args
[4]) = xSrc
;
680 V_I4(&args
[9]) = HandleToLong(hdc
);
682 params
.rgvarg
= args
;
683 params
.rgdispidNamedArgs
= NULL
;
685 params
.cNamedArgs
= 0;
687 V_VT(&ret
) = VT_EMPTY
;
688 hr_disp
= IDispatch_Invoke(disp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
,
689 ¶ms
, &ret
, NULL
, NULL
);
690 ok(hr
== hr_disp
, "DISPID_PICT_RENDER returned wrong code, 0x%08x, expected 0x%08x\n",
693 IDispatch_Release(disp
);
698 static void test_Render(void)
704 OLE_XSIZE_HIMETRIC pWidth
;
705 OLE_YSIZE_HIMETRIC pHeight
;
706 COLORREF result
, expected
;
709 /* test IPicture::Render return code on uninitialized picture */
710 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
711 hres
= IPicture_get_Type(pic
, &type
);
712 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
713 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
714 /* zero dimensions */
715 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
716 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
717 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
718 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
719 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
720 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
721 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
722 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
723 hres
= picture_render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
724 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
725 hres
= picture_render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
726 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
727 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
728 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
729 /* nonzero dimensions, PICTYPE_UNINITIALIZED */
730 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 10, NULL
);
731 ole_expect(hres
, S_OK
);
732 IPicture_Release(pic
);
734 desc
.cbSizeofstruct
= sizeof(PICTDESC
);
735 desc
.picType
= PICTYPE_ICON
;
736 desc
.u
.icon
.hicon
= LoadIconA(NULL
, (LPCSTR
)IDI_APPLICATION
);
737 if(!desc
.u
.icon
.hicon
){
738 win_skip("LoadIcon failed. Skipping...\n");
739 ReleaseDC(NULL
, hdc
);
743 OleCreatePictureIndirect(&desc
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
744 /* zero dimensions, PICTYPE_ICON */
745 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
746 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
747 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
748 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
749 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
750 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
751 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
752 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
753 hres
= picture_render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
754 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
755 hres
= picture_render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
756 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
757 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
758 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
760 /* Check if target size and position is respected */
761 IPicture_get_Width(pic
, &pWidth
);
762 IPicture_get_Height(pic
, &pHeight
);
764 SetPixelV(hdc
, 0, 0, 0x00223344);
765 SetPixelV(hdc
, 5, 5, 0x00223344);
766 SetPixelV(hdc
, 10, 10, 0x00223344);
767 expected
= GetPixel(hdc
, 0, 0);
769 hres
= picture_render(pic
, hdc
, 1, 1, 9, 9, 0, 0, pWidth
, -pHeight
, NULL
);
770 ole_expect(hres
, S_OK
);
773 IPicture_Release(pic
);
774 ReleaseDC(NULL
, hdc
);
778 /* Evaluate the rendered Icon */
779 result
= GetPixel(hdc
, 0, 0);
780 ok(result
== expected
,
781 "Color at 0,0 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
782 result
= GetPixel(hdc
, 5, 5);
783 ok(result
!= expected
||
784 broken(result
== expected
), /* WinNT 4.0 and older may claim they drew */
785 /* the icon, even if they didn't. */
786 "Color at 5,5 should have changed, but still was 0x%06X\n", expected
);
787 result
= GetPixel(hdc
, 10, 10);
788 ok(result
== expected
,
789 "Color at 10,10 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
791 IPicture_Release(pic
);
792 ReleaseDC(NULL
, hdc
);
795 static void test_get_Attributes(void)
802 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
803 hres
= IPicture_get_Type(pic
, &type
);
804 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
805 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
807 hres
= IPicture_get_Attributes(pic
, NULL
);
808 ole_expect(hres
, E_POINTER
);
811 hres
= IPicture_get_Attributes(pic
, &attr
);
812 ole_expect(hres
, S_OK
);
813 ok(attr
== 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr
);
815 IPicture_Release(pic
);
818 static void test_get_Handle(void)
823 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
825 hres
= IPicture_get_Handle(pic
, NULL
);
826 ole_expect(hres
, E_POINTER
);
828 IPicture_Release(pic
);
831 static void test_get_Type(void)
836 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
838 hres
= IPicture_get_Type(pic
, NULL
);
839 ole_expect(hres
, E_POINTER
);
841 IPicture_Release(pic
);
844 static void test_OleLoadPicturePath(void)
846 static WCHAR emptyW
[] = {0};
851 char temp_path
[MAX_PATH
];
852 char temp_file
[MAX_PATH
];
853 WCHAR temp_fileW
[MAX_PATH
+ 5] = {'f','i','l','e',':','/','/','/'};
860 LPOLESTR szURLorPath
;
863 } invalid_parameters
[] =
867 {NULL
, &IID_IPicture
, NULL
},
868 {NULL
, &IID_IPicture
, &pic
},
869 {emptyW
, NULL
, NULL
},
870 {emptyW
, &IID_IPicture
, NULL
},
873 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
875 pic
= (IPicture
*)0xdeadbeef;
876 hres
= OleLoadPicturePath(invalid_parameters
[i
].szURLorPath
, NULL
, 0, 0,
877 invalid_parameters
[i
].riid
,
878 (void **)invalid_parameters
[i
].pic
);
879 ok(hres
== E_INVALIDARG
,
880 "[%d] Expected OleLoadPicturePath to return E_INVALIDARG, got 0x%08x\n", i
, hres
);
881 ok(pic
== (IPicture
*)0xdeadbeef,
882 "[%d] Expected output pointer to be 0xdeadbeef, got %p\n", i
, pic
);
885 pic
= (IPicture
*)0xdeadbeef;
886 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, NULL
, (void **)&pic
);
888 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
889 broken(hres
== E_UNEXPECTED
) || /* NT4 */
890 broken(hres
== E_OUTOFMEMORY
), /* Win2k/Win2k3 */
891 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
893 "Expected the output interface pointer to be NULL, got %p\n", pic
);
895 pic
= (IPicture
*)0xdeadbeef;
896 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
898 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
899 broken(hres
== E_UNEXPECTED
) || /* NT4 */
900 broken(hres
== E_OUTOFMEMORY
), /* Win2k/Win2k3 */
901 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
903 "Expected the output interface pointer to be NULL, got %p\n", pic
);
905 /* Create a local temporary image file for testing. */
906 GetTempPathA(sizeof(temp_path
), temp_path
);
907 GetTempFileNameA(temp_path
, "bmp", 0, temp_file
);
908 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
909 FILE_ATTRIBUTE_NORMAL
, NULL
);
910 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
913 MultiByteToWideChar(CP_ACP
, 0, temp_file
, -1, temp_fileW
+ 8, sizeof(temp_fileW
)/sizeof(WCHAR
) - 8);
915 /* Try a normal DOS path. */
916 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
918 broken(hres
== E_UNEXPECTED
), /* NT4 */
919 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
921 IPicture_Release(pic
);
923 /* Try a DOS path with tacked on "file:". */
924 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
926 broken(hres
== E_UNEXPECTED
), /* NT4 */
927 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
929 IPicture_Release(pic
);
931 DeleteFileA(temp_file
);
933 /* Try with a nonexistent file. */
934 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
935 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
936 broken(hres
== E_UNEXPECTED
) || /* NT4 */
937 broken(hres
== E_FAIL
), /*Win2k */
938 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
940 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
941 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
942 broken(hres
== E_UNEXPECTED
) || /* NT4 */
943 broken(hres
== E_FAIL
), /* Win2k */
944 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
946 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
947 FILE_ATTRIBUTE_NORMAL
, NULL
);
948 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
951 /* Try a "file:" URL with slash separators. */
952 ptr
= temp_fileW
+ 8;
960 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
962 broken(hres
== E_UNEXPECTED
), /* NT4 */
963 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
965 IPicture_Release(pic
);
967 DeleteFileA(temp_file
);
969 /* Try with a nonexistent file. */
970 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
971 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
972 broken(hres
== E_UNEXPECTED
) || /* NT4 */
973 broken(hres
== E_FAIL
), /* Win2k */
974 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
977 static void test_himetric(void)
979 static const BYTE bmp_bits
[1024];
980 OLE_XSIZE_HIMETRIC cx
;
981 OLE_YSIZE_HIMETRIC cy
;
990 desc
.cbSizeofstruct
= sizeof(desc
);
991 desc
.picType
= PICTYPE_BITMAP
;
992 desc
.u
.bmp
.hpal
= NULL
;
994 hdc
= CreateCompatibleDC(0);
996 bmp
= CreateBitmap(1.9 * GetDeviceCaps(hdc
, LOGPIXELSX
),
997 1.9 * GetDeviceCaps(hdc
, LOGPIXELSY
), 1, 1, NULL
);
999 desc
.u
.bmp
.hbitmap
= bmp
;
1001 /* size in himetric units reported rounded up to next integer value */
1002 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1003 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1006 d
= MulDiv((INT
)(1.9 * GetDeviceCaps(hdc
, LOGPIXELSX
)), 2540, GetDeviceCaps(hdc
, LOGPIXELSX
));
1007 hr
= IPicture_get_Width(pic
, &cx
);
1008 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1009 ok(cx
== d
, "got %d, expected %d\n", cx
, d
);
1012 d
= MulDiv((INT
)(1.9 * GetDeviceCaps(hdc
, LOGPIXELSY
)), 2540, GetDeviceCaps(hdc
, LOGPIXELSY
));
1013 hr
= IPicture_get_Height(pic
, &cy
);
1014 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1015 ok(cy
== d
, "got %d, expected %d\n", cy
, d
);
1018 IPicture_Release(pic
);
1020 /* same thing with icon */
1021 icon
= CreateIcon(NULL
, GetSystemMetrics(SM_CXICON
), GetSystemMetrics(SM_CYICON
),
1022 1, 1, bmp_bits
, bmp_bits
);
1023 ok(icon
!= NULL
, "failed to create icon\n");
1025 desc
.picType
= PICTYPE_ICON
;
1026 desc
.u
.icon
.hicon
= icon
;
1028 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1029 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1032 d
= MulDiv(GetSystemMetrics(SM_CXICON
), 2540, GetDeviceCaps(hdc
, LOGPIXELSX
));
1033 hr
= IPicture_get_Width(pic
, &cx
);
1034 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1035 ok(cx
== d
, "got %d, expected %d\n", cx
, d
);
1038 d
= MulDiv(GetSystemMetrics(SM_CYICON
), 2540, GetDeviceCaps(hdc
, LOGPIXELSY
));
1039 hr
= IPicture_get_Height(pic
, &cy
);
1040 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1041 ok(cy
== d
, "got %d, expected %d\n", cy
, d
);
1043 IPicture_Release(pic
);
1049 static void test_load_save_bmp(void)
1057 IPersistStream
*src_stream
;
1058 IStream
*dst_stream
;
1059 LARGE_INTEGER offset
;
1063 desc
.cbSizeofstruct
= sizeof(desc
);
1064 desc
.picType
= PICTYPE_BITMAP
;
1065 desc
.u
.bmp
.hpal
= 0;
1066 desc
.u
.bmp
.hbitmap
= CreateBitmap(1, 1, 1, 1, NULL
);
1067 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1068 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1071 hr
= IPicture_get_Type(pic
, &type
);
1072 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1073 ok(type
== PICTYPE_BITMAP
,"expected picture type PICTYPE_BITMAP, got %d\n", type
);
1075 hr
= IPicture_get_Handle(pic
, &handle
);
1076 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1077 ok(IntToPtr(handle
) == desc
.u
.bmp
.hbitmap
, "get_Handle returned wrong handle %#x\n", handle
);
1079 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 4096);
1080 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1081 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1084 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1085 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1087 ok(size
== 66, "expected 66, got %d\n", size
);
1088 mem
= GlobalLock(hmem
);
1090 ok(!memcmp(&mem
[0], "BM", 2), "got wrong bmp header %04x\n", mem
[0]);
1094 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1096 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1098 ok(size
== -1, "expected -1, got %d\n", size
);
1100 offset
.QuadPart
= 0;
1101 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1102 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1104 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1105 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1107 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1108 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1110 IPersistStream_Release(src_stream
);
1111 IStream_Release(dst_stream
);
1113 mem
= GlobalLock(hmem
);
1114 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1115 ok(mem
[1] == 66, "expected stream size 66, got %u\n", mem
[1]);
1116 ok(!memcmp(&mem
[2], "BM", 2), "got wrong bmp header %04x\n", mem
[2]);
1121 DeleteObject(desc
.u
.bmp
.hbitmap
);
1122 IPicture_Release(pic
);
1125 static void test_load_save_icon(void)
1133 IPersistStream
*src_stream
;
1134 IStream
*dst_stream
;
1135 LARGE_INTEGER offset
;
1139 desc
.cbSizeofstruct
= sizeof(desc
);
1140 desc
.picType
= PICTYPE_ICON
;
1141 desc
.u
.icon
.hicon
= LoadIconA(NULL
, (LPCSTR
)IDI_APPLICATION
);
1142 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1143 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1146 hr
= IPicture_get_Type(pic
, &type
);
1147 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1148 ok(type
== PICTYPE_ICON
,"expected picture type PICTYPE_ICON, got %d\n", type
);
1150 hr
= IPicture_get_Handle(pic
, &handle
);
1151 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1152 ok(IntToPtr(handle
) == desc
.u
.icon
.hicon
, "get_Handle returned wrong handle %#x\n", handle
);
1154 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 8192);
1155 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1156 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
1159 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1160 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1162 ok(size
== 766, "expected 766, got %d\n", size
);
1163 mem
= GlobalLock(hmem
);
1165 ok(mem
[0] == 0x00010000, "got wrong icon header %04x\n", mem
[0]);
1169 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1171 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1173 ok(size
== -1, "expected -1, got %d\n", size
);
1175 offset
.QuadPart
= 0;
1176 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1177 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1179 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1180 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1182 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1183 ok(hr
== S_OK
, "Saveerror %#x\n", hr
);
1185 IPersistStream_Release(src_stream
);
1186 IStream_Release(dst_stream
);
1188 mem
= GlobalLock(hmem
);
1189 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1191 ok(mem
[1] == 766, "expected stream size 766, got %u\n", mem
[1]);
1192 ok(mem
[2] == 0x00010000, "got wrong icon header %04x\n", mem
[2]);
1197 DestroyIcon(desc
.u
.icon
.hicon
);
1198 IPicture_Release(pic
);
1201 static void test_load_save_empty_picture(void)
1209 IPersistStream
*src_stream
;
1210 IStream
*dst_stream
, *stream
;
1211 LARGE_INTEGER offset
;
1215 memset(&pic
, 0, sizeof(pic
));
1216 desc
.cbSizeofstruct
= sizeof(desc
);
1217 desc
.picType
= PICTYPE_NONE
;
1218 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void **)&pic
);
1219 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1222 hr
= IPicture_get_Type(pic
, &type
);
1223 ok(hr
== S_OK
, "get_Type error %#x\n", hr
);
1224 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1226 handle
= (OLE_HANDLE
)0xdeadbeef;
1227 hr
= IPicture_get_Handle(pic
, &handle
);
1228 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1229 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1231 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 4096);
1232 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1233 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1236 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1237 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1239 ok(size
== -1, "expected -1, got %d\n", size
);
1242 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1243 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1245 ok(size
== -1, "expected -1, got %d\n", size
);
1247 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1248 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1250 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1251 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1253 mem
= GlobalLock(hmem
);
1254 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1255 ok(mem
[1] == 0, "expected stream size 0, got %u\n", mem
[1]);
1258 IPersistStream_Release(src_stream
);
1259 IPicture_Release(pic
);
1261 /* first with statable and seekable stream */
1262 offset
.QuadPart
= 0;
1263 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1264 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1267 hr
= pOleLoadPicture(dst_stream
, 0, FALSE
, &IID_IPicture
, (void **)&pic
);
1268 ok(hr
== S_OK
, "OleLoadPicture error %#x\n", hr
);
1269 ok(pic
!= NULL
,"picture should not be not NULL\n");
1273 hr
= IPicture_get_Type(pic
, &type
);
1274 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1275 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1277 handle
= (OLE_HANDLE
)0xdeadbeef;
1278 hr
= IPicture_get_Handle(pic
, &handle
);
1279 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1280 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1282 IPicture_Release(pic
);
1284 IStream_Release(dst_stream
);
1286 /* again with non-statable and non-seekable stream */
1287 stream
= NoStatStream_Construct(hmem
);
1288 ok(stream
!= NULL
, "failed to create empty image stream\n");
1291 hr
= pOleLoadPicture(stream
, 0, FALSE
, &IID_IPicture
, (void **)&pic
);
1292 ok(hr
== S_OK
, "OleLoadPicture error %#x\n", hr
);
1293 ok(pic
!= NULL
,"picture should not be not NULL\n");
1297 hr
= IPicture_get_Type(pic
, &type
);
1298 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1299 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1301 handle
= (OLE_HANDLE
)0xdeadbeef;
1302 hr
= IPicture_get_Handle(pic
, &handle
);
1303 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1304 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1306 IPicture_Release(pic
);
1308 /* Non-statable impl always deletes on release */
1309 IStream_Release(stream
);
1312 START_TEST(olepicture
)
1314 hOleaut32
= GetModuleHandleA("oleaut32.dll");
1315 pOleLoadPicture
= (void*)GetProcAddress(hOleaut32
, "OleLoadPicture");
1316 pOleLoadPictureEx
= (void*)GetProcAddress(hOleaut32
, "OleLoadPictureEx");
1317 if (!pOleLoadPicture
)
1319 win_skip("OleLoadPicture is not available\n");
1323 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
1324 test_pic(gifimage
, sizeof(gifimage
));
1325 test_pic(jpgimage
, sizeof(jpgimage
));
1326 test_pic(bmpimage
, sizeof(bmpimage
));
1327 test_pic(gif4pixel
, sizeof(gif4pixel
));
1328 /* FIXME: No PNG support in Windows... */
1329 if (0) test_pic(pngimage
, sizeof(pngimage
));
1331 test_empty_image_2();
1332 if (pOleLoadPictureEx
)
1339 win_skip("OleLoadPictureEx is not available\n");
1341 test_OleCreatePictureIndirect();
1343 test_get_Attributes();
1346 test_OleLoadPicturePath();
1348 test_load_save_bmp();
1349 test_load_save_icon();
1350 test_load_save_empty_picture();
1354 /* Helper functions only ... */
1357 static inline NoStatStreamImpl
*impl_from_IStream(IStream
*iface
)
1359 return CONTAINING_RECORD(iface
, NoStatStreamImpl
, IStream_iface
);
1362 static void NoStatStreamImpl_Destroy(NoStatStreamImpl
* This
)
1364 GlobalFree(This
->supportHandle
);
1365 This
->supportHandle
=0;
1366 HeapFree(GetProcessHeap(), 0, This
);
1369 static ULONG WINAPI
NoStatStreamImpl_AddRef(
1372 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1373 return InterlockedIncrement(&This
->ref
);
1376 static HRESULT WINAPI
NoStatStreamImpl_QueryInterface(
1378 REFIID riid
, /* [in] */
1379 void** ppvObject
) /* [iid_is][out] */
1381 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1382 if (ppvObject
==0) return E_INVALIDARG
;
1384 if (IsEqualIID(&IID_IUnknown
, riid
))
1388 else if (IsEqualIID(&IID_IStream
, riid
))
1393 if ((*ppvObject
)==0)
1394 return E_NOINTERFACE
;
1395 NoStatStreamImpl_AddRef(iface
);
1399 static ULONG WINAPI
NoStatStreamImpl_Release(
1402 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1403 ULONG newRef
= InterlockedDecrement(&This
->ref
);
1405 NoStatStreamImpl_Destroy(This
);
1409 static HRESULT WINAPI
NoStatStreamImpl_Read(
1411 void* pv
, /* [length_is][size_is][out] */
1412 ULONG cb
, /* [in] */
1413 ULONG
* pcbRead
) /* [out] */
1415 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1416 void* supportBuffer
;
1417 ULONG bytesReadBuffer
;
1418 ULONG bytesToReadFromBuffer
;
1421 pcbRead
= &bytesReadBuffer
;
1422 bytesToReadFromBuffer
= min( This
->streamSize
.u
.LowPart
- This
->currentPosition
.u
.LowPart
, cb
);
1423 supportBuffer
= GlobalLock(This
->supportHandle
);
1424 memcpy(pv
, (char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, bytesToReadFromBuffer
);
1425 This
->currentPosition
.u
.LowPart
+=bytesToReadFromBuffer
;
1426 *pcbRead
= bytesToReadFromBuffer
;
1427 GlobalUnlock(This
->supportHandle
);
1433 static HRESULT WINAPI
NoStatStreamImpl_Write(
1435 const void* pv
, /* [size_is][in] */
1436 ULONG cb
, /* [in] */
1437 ULONG
* pcbWritten
) /* [out] */
1439 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1440 void* supportBuffer
;
1441 ULARGE_INTEGER newSize
;
1442 ULONG bytesWritten
= 0;
1444 if (pcbWritten
== 0)
1445 pcbWritten
= &bytesWritten
;
1448 newSize
.u
.HighPart
= 0;
1449 newSize
.u
.LowPart
= This
->currentPosition
.u
.LowPart
+ cb
;
1450 if (newSize
.u
.LowPart
> This
->streamSize
.u
.LowPart
)
1451 IStream_SetSize(iface
, newSize
);
1453 supportBuffer
= GlobalLock(This
->supportHandle
);
1454 memcpy((char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, pv
, cb
);
1455 This
->currentPosition
.u
.LowPart
+=cb
;
1457 GlobalUnlock(This
->supportHandle
);
1461 static HRESULT WINAPI
NoStatStreamImpl_Seek(
1463 LARGE_INTEGER dlibMove
, /* [in] */
1464 DWORD dwOrigin
, /* [in] */
1465 ULARGE_INTEGER
* plibNewPosition
) /* [out] */
1467 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1468 ULARGE_INTEGER newPosition
;
1471 case STREAM_SEEK_SET
:
1472 newPosition
.u
.HighPart
= 0;
1473 newPosition
.u
.LowPart
= 0;
1475 case STREAM_SEEK_CUR
:
1476 newPosition
= This
->currentPosition
;
1478 case STREAM_SEEK_END
:
1479 newPosition
= This
->streamSize
;
1482 return STG_E_INVALIDFUNCTION
;
1484 if (dlibMove
.QuadPart
< 0 && newPosition
.QuadPart
< -dlibMove
.QuadPart
)
1485 return STG_E_INVALIDFUNCTION
;
1486 newPosition
.QuadPart
+= dlibMove
.QuadPart
;
1487 if (plibNewPosition
) *plibNewPosition
= newPosition
;
1488 This
->currentPosition
= newPosition
;
1492 static HRESULT WINAPI
NoStatStreamImpl_SetSize(
1494 ULARGE_INTEGER libNewSize
) /* [in] */
1496 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1497 HGLOBAL supportHandle
;
1498 if (libNewSize
.u
.HighPart
!= 0)
1499 return STG_E_INVALIDFUNCTION
;
1500 if (This
->streamSize
.u
.LowPart
== libNewSize
.u
.LowPart
)
1502 supportHandle
= GlobalReAlloc(This
->supportHandle
, libNewSize
.u
.LowPart
, 0);
1503 if (supportHandle
== 0)
1504 return STG_E_MEDIUMFULL
;
1505 This
->supportHandle
= supportHandle
;
1506 This
->streamSize
.u
.LowPart
= libNewSize
.u
.LowPart
;
1510 static HRESULT WINAPI
NoStatStreamImpl_CopyTo(
1512 IStream
* pstm
, /* [unique][in] */
1513 ULARGE_INTEGER cb
, /* [in] */
1514 ULARGE_INTEGER
* pcbRead
, /* [out] */
1515 ULARGE_INTEGER
* pcbWritten
) /* [out] */
1518 BYTE tmpBuffer
[128];
1519 ULONG bytesRead
, bytesWritten
, copySize
;
1520 ULARGE_INTEGER totalBytesRead
;
1521 ULARGE_INTEGER totalBytesWritten
;
1524 return STG_E_INVALIDPOINTER
;
1525 totalBytesRead
.u
.LowPart
= totalBytesRead
.u
.HighPart
= 0;
1526 totalBytesWritten
.u
.LowPart
= totalBytesWritten
.u
.HighPart
= 0;
1528 while ( cb
.u
.LowPart
> 0 )
1530 if ( cb
.u
.LowPart
>= 128 )
1533 copySize
= cb
.u
.LowPart
;
1534 IStream_Read(iface
, tmpBuffer
, copySize
, &bytesRead
);
1535 totalBytesRead
.u
.LowPart
+= bytesRead
;
1536 IStream_Write(pstm
, tmpBuffer
, bytesRead
, &bytesWritten
);
1537 totalBytesWritten
.u
.LowPart
+= bytesWritten
;
1538 if (bytesRead
!= bytesWritten
)
1540 hr
= STG_E_MEDIUMFULL
;
1543 if (bytesRead
!=copySize
)
1546 cb
.u
.LowPart
-= bytesRead
;
1550 pcbRead
->u
.LowPart
= totalBytesRead
.u
.LowPart
;
1551 pcbRead
->u
.HighPart
= totalBytesRead
.u
.HighPart
;
1556 pcbWritten
->u
.LowPart
= totalBytesWritten
.u
.LowPart
;
1557 pcbWritten
->u
.HighPart
= totalBytesWritten
.u
.HighPart
;
1562 static HRESULT WINAPI
NoStatStreamImpl_Commit(IStream
* iface
,DWORD grfCommitFlags
)
1566 static HRESULT WINAPI
NoStatStreamImpl_Revert(IStream
* iface
) { return S_OK
; }
1568 static HRESULT WINAPI
NoStatStreamImpl_LockRegion(
1570 ULARGE_INTEGER libOffset
, /* [in] */
1571 ULARGE_INTEGER cb
, /* [in] */
1572 DWORD dwLockType
) /* [in] */
1577 static HRESULT WINAPI
NoStatStreamImpl_UnlockRegion(
1579 ULARGE_INTEGER libOffset
, /* [in] */
1580 ULARGE_INTEGER cb
, /* [in] */
1581 DWORD dwLockType
) /* [in] */
1586 static HRESULT WINAPI
NoStatStreamImpl_Stat(
1588 STATSTG
* pstatstg
, /* [out] */
1589 DWORD grfStatFlag
) /* [in] */
1594 static HRESULT WINAPI
NoStatStreamImpl_Clone(
1596 IStream
** ppstm
) /* [out] */
1600 static const IStreamVtbl NoStatStreamImpl_Vtbl
;
1603 Build an object that implements IStream, without IStream_Stat capabilities.
1604 Receives a memory handle with data buffer. If memory handle is non-null,
1605 it is assumed to be unlocked, otherwise an internal memory handle is allocated.
1606 In any case the object takes ownership of memory handle and will free it on
1609 static IStream
* NoStatStream_Construct(HGLOBAL hGlobal
)
1611 NoStatStreamImpl
* newStream
;
1613 newStream
= HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl
));
1616 newStream
->IStream_iface
.lpVtbl
= &NoStatStreamImpl_Vtbl
;
1618 newStream
->supportHandle
= hGlobal
;
1620 if (!newStream
->supportHandle
)
1621 newStream
->supportHandle
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
|
1623 newStream
->currentPosition
.u
.HighPart
= 0;
1624 newStream
->currentPosition
.u
.LowPart
= 0;
1625 newStream
->streamSize
.u
.HighPart
= 0;
1626 newStream
->streamSize
.u
.LowPart
= GlobalSize(newStream
->supportHandle
);
1628 return &newStream
->IStream_iface
;
1632 static const IStreamVtbl NoStatStreamImpl_Vtbl
=
1634 NoStatStreamImpl_QueryInterface
,
1635 NoStatStreamImpl_AddRef
,
1636 NoStatStreamImpl_Release
,
1637 NoStatStreamImpl_Read
,
1638 NoStatStreamImpl_Write
,
1639 NoStatStreamImpl_Seek
,
1640 NoStatStreamImpl_SetSize
,
1641 NoStatStreamImpl_CopyTo
,
1642 NoStatStreamImpl_Commit
,
1643 NoStatStreamImpl_Revert
,
1644 NoStatStreamImpl_LockRegion
,
1645 NoStatStreamImpl_UnlockRegion
,
1646 NoStatStreamImpl_Stat
,
1647 NoStatStreamImpl_Clone