2005-06-06 12:03:58 +02:00
|
|
|
/*
|
|
|
|
* OLEPICTURE test program
|
|
|
|
*
|
|
|
|
* Copyright 2005 Marcus Meissner
|
2012-06-01 08:37:47 +02:00
|
|
|
* Copyright 2012 Dmitry Timoshkov
|
2005-06-06 12:03:58 +02:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2006-05-18 14:49:52 +02:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2005-06-06 12:03:58 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <float.h>
|
|
|
|
|
|
|
|
#define COBJMACROS
|
2011-03-15 11:35:36 +01:00
|
|
|
#define CONST_VTABLE
|
2008-12-10 13:08:47 +01:00
|
|
|
#define NONAMELESSUNION
|
2005-06-06 12:03:58 +02:00
|
|
|
|
2007-10-04 01:56:53 +02:00
|
|
|
#include "wine/test.h"
|
2005-06-06 12:03:58 +02:00
|
|
|
#include <windef.h>
|
|
|
|
#include <winbase.h>
|
|
|
|
#include <winuser.h>
|
|
|
|
#include <wingdi.h>
|
|
|
|
#include <winnls.h>
|
|
|
|
#include <winerror.h>
|
|
|
|
#include <winnt.h>
|
|
|
|
|
2010-05-20 05:26:15 +02:00
|
|
|
#include <urlmon.h>
|
2005-06-06 12:03:58 +02:00
|
|
|
#include <wtypes.h>
|
|
|
|
#include <olectl.h>
|
|
|
|
#include <objidl.h>
|
|
|
|
|
2007-10-04 01:56:53 +02:00
|
|
|
#define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
|
|
|
|
|
|
|
|
#define ole_expect(expr, expect) { \
|
|
|
|
HRESULT r = expr; \
|
|
|
|
ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ole_check(expr) ole_expect(expr, S_OK);
|
|
|
|
|
2005-06-06 12:03:58 +02:00
|
|
|
static HMODULE hOleaut32;
|
|
|
|
|
|
|
|
static HRESULT (WINAPI *pOleLoadPicture)(LPSTREAM,LONG,BOOL,REFIID,LPVOID*);
|
2012-01-09 10:01:37 +01:00
|
|
|
static HRESULT (WINAPI *pOleLoadPictureEx)(LPSTREAM,LONG,BOOL,REFIID,DWORD,DWORD,DWORD,LPVOID*);
|
2005-06-06 12:03:58 +02:00
|
|
|
|
2006-10-12 13:56:01 +02:00
|
|
|
#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
|
2006-07-28 02:22:02 +02:00
|
|
|
|
2005-06-06 12:03:58 +02:00
|
|
|
/* 1x1 pixel gif */
|
|
|
|
static const unsigned char gifimage[35] = {
|
|
|
|
0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
|
|
|
|
0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
|
|
|
|
0x01,0x00,0x3b
|
|
|
|
};
|
|
|
|
|
|
|
|
/* 1x1 pixel jpg */
|
|
|
|
static const unsigned char jpgimage[285] = {
|
|
|
|
0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
|
|
|
|
0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
|
|
|
|
0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
|
|
|
|
0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
|
|
|
|
0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
|
|
|
|
0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
|
|
|
|
0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
|
|
|
|
0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
|
|
|
|
0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
|
|
|
|
0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
|
|
|
|
0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
|
|
|
|
0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
|
|
|
|
0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
|
|
|
|
0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
|
|
|
|
};
|
|
|
|
|
|
|
|
/* 1x1 pixel png */
|
|
|
|
static const unsigned char pngimage[285] = {
|
|
|
|
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
|
|
|
|
0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
|
|
|
|
0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
|
|
|
|
0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
|
|
|
|
0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
|
|
|
|
0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
|
|
|
|
0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
|
|
|
|
};
|
|
|
|
|
|
|
|
/* 1x1 pixel bmp */
|
|
|
|
static const unsigned char bmpimage[66] = {
|
|
|
|
0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
|
|
|
|
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
|
|
|
|
0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
|
|
|
|
0x00,0x00
|
|
|
|
};
|
|
|
|
|
|
|
|
/* 2x2 pixel gif */
|
|
|
|
static const unsigned char gif4pixel[42] = {
|
|
|
|
0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
|
|
|
|
0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
|
|
|
|
};
|
|
|
|
|
2007-10-04 01:56:53 +02:00
|
|
|
/* APM with an empty metafile with some padding zeros - looks like under Window the
|
|
|
|
* metafile data should be at least 20 bytes */
|
|
|
|
static const unsigned char apmdata[] = {
|
|
|
|
0xd7,0xcd,0xc6,0x9a, 0x00,0x00,0x00,0x00, 0x00,0x00,0xee,0x02, 0xb1,0x03,0xa0,0x05,
|
|
|
|
0x00,0x00,0x00,0x00, 0xee,0x53,0x01,0x00, 0x09,0x00,0x00,0x03, 0x13,0x00,0x00,0x00,
|
|
|
|
0x01,0x00,0x05,0x00, 0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
|
|
|
|
};
|
|
|
|
|
2008-10-04 01:24:37 +02:00
|
|
|
/* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
|
|
|
|
static const unsigned char metafile[] = {
|
|
|
|
0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
|
|
|
|
0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
|
|
0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
|
|
|
|
0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00
|
|
|
|
};
|
|
|
|
|
|
|
|
/* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
|
|
|
|
static const unsigned char enhmetafile[] = {
|
|
|
|
0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
|
|
|
|
0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
|
|
|
|
0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
|
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
|
|
|
|
0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
|
|
|
|
0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
|
|
|
|
0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
|
|
|
|
0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
|
|
|
|
0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
|
|
|
|
0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
|
|
|
|
0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
|
|
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
|
|
|
0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
|
|
|
0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
|
|
|
0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
|
|
|
0x14, 0x00, 0x00, 0x00
|
|
|
|
};
|
|
|
|
|
2016-08-26 12:11:04 +02:00
|
|
|
static HBITMAP stock_bm;
|
|
|
|
|
|
|
|
static HDC create_render_dc( void )
|
|
|
|
{
|
|
|
|
HDC dc = CreateCompatibleDC( NULL );
|
|
|
|
BITMAPINFO info = {{sizeof(info.bmiHeader), 100, 100, 1, 32, BI_RGB }};
|
|
|
|
void *bits;
|
|
|
|
HBITMAP dib = CreateDIBSection( NULL, &info, DIB_RGB_COLORS, &bits, NULL, 0 );
|
|
|
|
|
|
|
|
stock_bm = SelectObject( dc, dib );
|
|
|
|
return dc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void delete_render_dc( HDC dc )
|
|
|
|
{
|
|
|
|
HBITMAP dib = SelectObject( dc, stock_bm );
|
|
|
|
DeleteObject( dib );
|
|
|
|
DeleteDC( dc );
|
|
|
|
}
|
2008-10-04 01:24:37 +02:00
|
|
|
|
2011-03-15 11:35:36 +01:00
|
|
|
typedef struct NoStatStreamImpl
|
2005-11-07 12:09:10 +01:00
|
|
|
{
|
2011-03-15 11:35:36 +01:00
|
|
|
IStream IStream_iface;
|
2005-11-07 12:09:10 +01:00
|
|
|
LONG ref;
|
|
|
|
|
|
|
|
HGLOBAL supportHandle;
|
|
|
|
ULARGE_INTEGER streamSize;
|
|
|
|
ULARGE_INTEGER currentPosition;
|
2011-03-15 11:35:36 +01:00
|
|
|
} NoStatStreamImpl;
|
|
|
|
|
|
|
|
static IStream* NoStatStream_Construct(HGLOBAL hGlobal);
|
2005-11-07 12:09:10 +01:00
|
|
|
|
2005-06-06 12:03:58 +02:00
|
|
|
static void
|
2005-11-07 12:09:10 +01:00
|
|
|
test_pic_with_stream(LPSTREAM stream, unsigned int imgsize)
|
2005-06-06 12:03:58 +02:00
|
|
|
{
|
|
|
|
IPicture* pic = NULL;
|
|
|
|
HRESULT hres;
|
|
|
|
LPVOID pvObj = NULL;
|
|
|
|
OLE_HANDLE handle, hPal;
|
|
|
|
OLE_XSIZE_HIMETRIC width;
|
|
|
|
OLE_YSIZE_HIMETRIC height;
|
|
|
|
short type;
|
|
|
|
DWORD attr;
|
|
|
|
ULONG res;
|
|
|
|
|
|
|
|
pvObj = NULL;
|
|
|
|
hres = pOleLoadPicture(stream, imgsize, TRUE, &IID_IPicture, &pvObj);
|
|
|
|
pic = pvObj;
|
|
|
|
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hres == S_OK,"OLP (NULL,..) does not return 0, but 0x%08x\n",hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok(pic != NULL,"OLP (NULL,..) returns NULL, instead of !NULL\n");
|
|
|
|
if (pic == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pvObj = NULL;
|
|
|
|
hres = IPicture_QueryInterface (pic, &IID_IPicture, &pvObj);
|
|
|
|
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hres == S_OK,"IPicture_QI does not return S_OK, but 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok(pvObj != NULL,"IPicture_QI does return NULL, instead of a ptr\n");
|
|
|
|
|
|
|
|
IPicture_Release ((IPicture*)pvObj);
|
|
|
|
|
|
|
|
handle = 0;
|
|
|
|
hres = IPicture_get_Handle (pic, &handle);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hres == S_OK,"IPicture_get_Handle does not return S_OK, but 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok(handle != 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
|
|
|
|
|
2010-07-16 21:19:28 +02:00
|
|
|
if (handle)
|
|
|
|
{
|
|
|
|
BITMAP bmp;
|
2013-10-24 23:25:25 +02:00
|
|
|
GetObjectA(UlongToHandle(handle), sizeof(BITMAP), &bmp);
|
2010-07-16 21:19:28 +02:00
|
|
|
todo_wine ok(bmp.bmBits != 0, "not a dib\n");
|
|
|
|
}
|
|
|
|
|
2005-06-06 12:03:58 +02:00
|
|
|
width = 0;
|
|
|
|
hres = IPicture_get_Width (pic, &width);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hres == S_OK,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok(width != 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
|
|
|
|
|
|
|
|
height = 0;
|
|
|
|
hres = IPicture_get_Height (pic, &height);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hres == S_OK,"IPicture_get_Height does not return S_OK, but 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok(height != 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
|
|
|
|
|
|
|
|
type = 0;
|
|
|
|
hres = IPicture_get_Type (pic, &type);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hres == S_OK,"IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok(type == PICTYPE_BITMAP, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type, PICTYPE_BITMAP);
|
|
|
|
|
|
|
|
attr = 0;
|
|
|
|
hres = IPicture_get_Attributes (pic, &attr);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hres == S_OK,"IPicture_get_Attributes does not return S_OK, but 0x%08x\n", hres);
|
|
|
|
ok(attr == 0, "IPicture_get_Attributes returns %d, but it should be 0.\n", attr);
|
2005-06-06 12:03:58 +02:00
|
|
|
|
|
|
|
hPal = 0;
|
|
|
|
hres = IPicture_get_hPal (pic, &hPal);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hres == S_OK,"IPicture_get_hPal does not return S_OK, but 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
/* a single pixel b/w image has no palette */
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hPal == 0, "IPicture_get_hPal returns %d, but it should be 0.\n", hPal);
|
2005-06-06 12:03:58 +02:00
|
|
|
|
|
|
|
res = IPicture_Release (pic);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok (res == 0, "refcount after release is %d, but should be 0?\n", res);
|
2005-11-07 12:09:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_pic(const unsigned char *imgdata, unsigned int imgsize)
|
|
|
|
{
|
|
|
|
LPSTREAM stream;
|
|
|
|
HGLOBAL hglob;
|
|
|
|
LPBYTE data;
|
|
|
|
HRESULT hres;
|
|
|
|
LARGE_INTEGER seekto;
|
|
|
|
ULARGE_INTEGER newpos1;
|
2006-11-06 22:47:25 +01:00
|
|
|
DWORD * header;
|
2006-12-24 04:02:33 +01:00
|
|
|
unsigned int i,j;
|
2005-11-07 12:09:10 +01:00
|
|
|
|
|
|
|
/* Let the fun begin */
|
|
|
|
hglob = GlobalAlloc (0, imgsize);
|
|
|
|
data = GlobalLock (hglob);
|
|
|
|
memcpy(data, imgdata, imgsize);
|
2006-12-24 04:02:33 +01:00
|
|
|
GlobalUnlock(hglob); data = NULL;
|
2005-11-07 12:09:10 +01:00
|
|
|
|
|
|
|
hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
|
2005-11-07 12:09:10 +01:00
|
|
|
|
|
|
|
memset(&seekto,0,sizeof(seekto));
|
|
|
|
hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
|
2005-11-07 12:09:10 +01:00
|
|
|
test_pic_with_stream(stream, imgsize);
|
2006-11-06 22:47:25 +01:00
|
|
|
|
|
|
|
IStream_Release(stream);
|
2005-11-07 12:09:10 +01:00
|
|
|
|
|
|
|
/* again with Non Statable and Non Seekable stream */
|
2011-03-15 11:35:36 +01:00
|
|
|
stream = NoStatStream_Construct(hglob);
|
2006-12-24 04:02:33 +01:00
|
|
|
hglob = 0; /* Non-statable impl always deletes on release */
|
2005-11-07 12:09:10 +01:00
|
|
|
test_pic_with_stream(stream, 0);
|
2006-11-06 22:47:25 +01:00
|
|
|
|
|
|
|
IStream_Release(stream);
|
|
|
|
for (i = 1; i <= 8; i++) {
|
2006-12-24 04:02:33 +01:00
|
|
|
/* more fun!!! */
|
|
|
|
hglob = GlobalAlloc (0, imgsize + i * (2 * sizeof(DWORD)));
|
|
|
|
data = GlobalLock (hglob);
|
|
|
|
header = (DWORD *)data;
|
|
|
|
|
|
|
|
/* multiple copies of header */
|
|
|
|
memcpy(data,"lt\0\0",4);
|
|
|
|
header[1] = imgsize;
|
|
|
|
for (j = 2; j <= i; j++) {
|
|
|
|
memcpy(&(header[2 * (j - 1)]), header, 2 * sizeof(DWORD));
|
|
|
|
}
|
|
|
|
memcpy(data + i * (2 * sizeof(DWORD)), imgdata, imgsize);
|
|
|
|
GlobalUnlock(hglob); data = NULL;
|
|
|
|
|
2006-11-06 22:47:25 +01:00
|
|
|
hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
|
|
|
|
ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
|
|
|
|
|
|
|
|
memset(&seekto,0,sizeof(seekto));
|
|
|
|
hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
|
|
|
|
ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
|
|
|
|
test_pic_with_stream(stream, imgsize);
|
|
|
|
|
|
|
|
IStream_Release(stream);
|
|
|
|
|
|
|
|
/* again with Non Statable and Non Seekable stream */
|
2011-03-15 11:35:36 +01:00
|
|
|
stream = NoStatStream_Construct(hglob);
|
2006-12-24 04:02:33 +01:00
|
|
|
hglob = 0; /* Non-statable impl always deletes on release */
|
2006-11-06 22:47:25 +01:00
|
|
|
test_pic_with_stream(stream, 0);
|
|
|
|
|
2006-12-24 04:02:33 +01:00
|
|
|
IStream_Release(stream);
|
2006-11-06 22:47:25 +01:00
|
|
|
}
|
2005-06-06 12:03:58 +02:00
|
|
|
}
|
|
|
|
|
2005-06-27 11:57:28 +02:00
|
|
|
static void test_empty_image(void) {
|
2005-06-06 12:03:58 +02:00
|
|
|
LPBYTE data;
|
|
|
|
LPSTREAM stream;
|
|
|
|
IPicture* pic = NULL;
|
|
|
|
HRESULT hres;
|
|
|
|
LPVOID pvObj = NULL;
|
|
|
|
HGLOBAL hglob;
|
|
|
|
OLE_HANDLE handle;
|
|
|
|
ULARGE_INTEGER newpos1;
|
|
|
|
LARGE_INTEGER seekto;
|
|
|
|
short type;
|
2009-01-05 22:25:43 +01:00
|
|
|
DWORD attr;
|
2005-06-06 12:03:58 +02:00
|
|
|
|
2005-06-17 22:59:49 +02:00
|
|
|
/* Empty image. Happens occasionally in VB programs. */
|
2005-06-06 12:03:58 +02:00
|
|
|
hglob = GlobalAlloc (0, 8);
|
|
|
|
data = GlobalLock (hglob);
|
|
|
|
memcpy(data,"lt\0\0",4);
|
|
|
|
((DWORD*)data)[1] = 0;
|
|
|
|
hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
|
|
|
|
memset(&seekto,0,sizeof(seekto));
|
|
|
|
hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
|
|
|
|
pvObj = NULL;
|
|
|
|
hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
|
|
|
|
pic = pvObj;
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
|
|
|
|
|
|
|
|
hres = IPicture_get_Type (pic, &type);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
|
|
|
|
|
2009-01-05 22:25:43 +01:00
|
|
|
attr = 0xdeadbeef;
|
|
|
|
hres = IPicture_get_Attributes (pic, &attr);
|
|
|
|
ok (hres == S_OK,"empty picture get attributes failed with hres 0x%08x\n", hres);
|
|
|
|
ok (attr == 0,"attr is %d, but should be 0\n", attr);
|
|
|
|
|
2005-06-06 12:03:58 +02:00
|
|
|
hres = IPicture_get_Handle (pic, &handle);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok (hres == S_OK,"empty picture get handle failed with hres 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok (handle == 0, "empty picture get handle did not return 0, but 0x%08x\n", handle);
|
|
|
|
IPicture_Release (pic);
|
2009-12-11 13:14:32 +01:00
|
|
|
IStream_Release (stream);
|
2005-06-06 12:03:58 +02:00
|
|
|
}
|
|
|
|
|
2005-06-27 11:57:28 +02:00
|
|
|
static void test_empty_image_2(void) {
|
2005-06-06 12:03:58 +02:00
|
|
|
LPBYTE data;
|
|
|
|
LPSTREAM stream;
|
|
|
|
IPicture* pic = NULL;
|
|
|
|
HRESULT hres;
|
|
|
|
LPVOID pvObj = NULL;
|
|
|
|
HGLOBAL hglob;
|
|
|
|
ULARGE_INTEGER newpos1;
|
|
|
|
LARGE_INTEGER seekto;
|
|
|
|
short type;
|
|
|
|
|
|
|
|
/* Empty image at random stream position. */
|
|
|
|
hglob = GlobalAlloc (0, 200);
|
|
|
|
data = GlobalLock (hglob);
|
|
|
|
data += 42;
|
|
|
|
memcpy(data,"lt\0\0",4);
|
|
|
|
((DWORD*)data)[1] = 0;
|
|
|
|
hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
|
|
|
|
memset(&seekto,0,sizeof(seekto));
|
|
|
|
seekto.u.LowPart = 42;
|
|
|
|
hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
|
|
|
|
pvObj = NULL;
|
|
|
|
hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
|
|
|
|
pic = pvObj;
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
|
|
|
|
|
|
|
|
hres = IPicture_get_Type (pic, &type);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
|
2005-06-06 12:03:58 +02:00
|
|
|
ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
|
|
|
|
|
|
|
|
IPicture_Release (pic);
|
2009-12-11 13:14:32 +01:00
|
|
|
IStream_Release (stream);
|
2005-06-06 12:03:58 +02:00
|
|
|
}
|
|
|
|
|
2006-07-28 02:22:02 +02:00
|
|
|
static void test_Invoke(void)
|
|
|
|
{
|
|
|
|
IPictureDisp *picdisp;
|
|
|
|
HRESULT hr;
|
2014-02-28 13:57:19 +01:00
|
|
|
VARIANTARG vararg, args[10];
|
2006-07-28 02:22:02 +02:00
|
|
|
DISPPARAMS dispparams;
|
|
|
|
VARIANT varresult;
|
|
|
|
IStream *stream;
|
|
|
|
HGLOBAL hglob;
|
|
|
|
void *data;
|
2014-02-28 13:57:19 +01:00
|
|
|
HDC hdc;
|
|
|
|
int i;
|
2006-07-28 02:22:02 +02:00
|
|
|
|
2009-12-11 13:14:32 +01:00
|
|
|
hglob = GlobalAlloc (0, sizeof(gifimage));
|
|
|
|
data = GlobalLock(hglob);
|
|
|
|
memcpy(data, gifimage, sizeof(gifimage));
|
2006-07-28 02:22:02 +02:00
|
|
|
GlobalUnlock(hglob);
|
|
|
|
|
2009-12-11 13:14:32 +01:00
|
|
|
hr = CreateStreamOnHGlobal (hglob, FALSE, &stream);
|
2006-07-28 02:22:02 +02:00
|
|
|
ok_ole_success(hr, "CreateStreamOnHGlobal");
|
|
|
|
|
2009-12-11 13:14:32 +01:00
|
|
|
hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp);
|
2006-07-28 02:22:02 +02:00
|
|
|
IStream_Release(stream);
|
2009-12-11 13:14:32 +01:00
|
|
|
GlobalFree(hglob);
|
2006-07-28 02:22:02 +02:00
|
|
|
ok_ole_success(hr, "OleLoadPicture");
|
|
|
|
|
|
|
|
V_VT(&vararg) = VT_BOOL;
|
|
|
|
V_BOOL(&vararg) = VARIANT_FALSE;
|
|
|
|
dispparams.cNamedArgs = 0;
|
|
|
|
dispparams.rgdispidNamedArgs = NULL;
|
|
|
|
dispparams.cArgs = 1;
|
|
|
|
dispparams.rgvarg = &vararg;
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IPictureDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
|
2006-07-28 02:22:02 +02:00
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
|
2006-07-28 02:22:02 +02:00
|
|
|
|
|
|
|
dispparams.cArgs = 0;
|
|
|
|
dispparams.rgvarg = NULL;
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
|
2006-07-28 02:22:02 +02:00
|
|
|
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
|
2006-07-28 02:22:02 +02:00
|
|
|
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
|
2006-07-28 02:22:02 +02:00
|
|
|
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
|
2006-07-28 02:22:02 +02:00
|
|
|
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
|
|
|
|
ok_ole_success(hr, "IPictureDisp_Invoke");
|
2006-07-28 02:24:10 +02:00
|
|
|
ok(V_VT(&varresult) == VT_I4, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult));
|
2006-07-28 02:22:02 +02:00
|
|
|
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
|
2006-07-28 02:22:02 +02:00
|
|
|
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
|
2006-07-28 02:24:10 +02:00
|
|
|
|
|
|
|
dispparams.cArgs = 1;
|
|
|
|
dispparams.rgvarg = &vararg;
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
|
2006-07-28 02:24:10 +02:00
|
|
|
|
|
|
|
dispparams.cArgs = 1;
|
|
|
|
dispparams.rgvarg = &vararg;
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
|
2006-10-12 13:56:01 +02:00
|
|
|
ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
|
2006-07-28 02:22:02 +02:00
|
|
|
|
2014-02-28 13:57:19 +01:00
|
|
|
/* DISPID_PICT_RENDER */
|
2016-08-26 12:11:04 +02:00
|
|
|
hdc = create_render_dc();
|
2014-02-28 13:57:19 +01:00
|
|
|
|
2018-06-18 00:09:30 +02:00
|
|
|
for (i = 0; i < ARRAY_SIZE(args); i++)
|
2014-02-28 13:57:19 +01:00
|
|
|
V_VT(&args[i]) = VT_I4;
|
|
|
|
|
|
|
|
V_I4(&args[0]) = 0;
|
|
|
|
V_I4(&args[1]) = 10;
|
|
|
|
V_I4(&args[2]) = 10;
|
|
|
|
V_I4(&args[3]) = 0;
|
|
|
|
V_I4(&args[4]) = 0;
|
|
|
|
V_I4(&args[5]) = 10;
|
|
|
|
V_I4(&args[6]) = 10;
|
|
|
|
V_I4(&args[7]) = 0;
|
|
|
|
V_I4(&args[8]) = 0;
|
|
|
|
V_I4(&args[9]) = HandleToLong(hdc);
|
|
|
|
|
|
|
|
dispparams.rgvarg = args;
|
|
|
|
dispparams.rgdispidNamedArgs = NULL;
|
|
|
|
dispparams.cArgs = 10;
|
|
|
|
dispparams.cNamedArgs = 0;
|
|
|
|
|
|
|
|
V_VT(&varresult) = VT_EMPTY;
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_RENDER, &GUID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
|
|
|
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
|
|
|
|
|
|
|
/* Try with one argument set to VT_I2, it'd still work if coerced. */
|
|
|
|
V_VT(&args[3]) = VT_I2;
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_RENDER, &GUID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
|
|
|
|
ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
|
|
|
|
V_VT(&args[3]) = VT_I4;
|
|
|
|
|
|
|
|
/* Wrong argument count */
|
|
|
|
dispparams.cArgs = 9;
|
|
|
|
hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_RENDER, &GUID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
|
|
|
|
ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
|
|
|
|
|
2016-08-26 12:11:04 +02:00
|
|
|
delete_render_dc(hdc);
|
2006-07-28 02:22:02 +02:00
|
|
|
IPictureDisp_Release(picdisp);
|
|
|
|
}
|
|
|
|
|
2018-07-06 10:10:37 +02:00
|
|
|
static HRESULT create_picture(short type, IPicture **pict)
|
|
|
|
{
|
|
|
|
PICTDESC desc;
|
|
|
|
|
|
|
|
desc.cbSizeofstruct = sizeof(desc);
|
|
|
|
desc.picType = type;
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case PICTYPE_UNINITIALIZED:
|
|
|
|
return OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void **)pict);
|
|
|
|
|
|
|
|
case PICTYPE_NONE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PICTYPE_BITMAP:
|
|
|
|
desc.u.bmp.hbitmap = CreateBitmap(1, 1, 1, 1, NULL);
|
|
|
|
desc.u.bmp.hpal = (HPALETTE)0xbeefdead;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PICTYPE_ICON:
|
|
|
|
desc.u.icon.hicon = LoadIconA(NULL, (LPCSTR)IDI_APPLICATION);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PICTYPE_METAFILE:
|
|
|
|
{
|
|
|
|
HDC hdc = CreateMetaFileA(NULL);
|
|
|
|
desc.u.wmf.hmeta = CloseMetaFile(hdc);
|
|
|
|
desc.u.wmf.xExt = 1;
|
|
|
|
desc.u.wmf.yExt = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PICTYPE_ENHMETAFILE:
|
|
|
|
{
|
|
|
|
HDC hdc = CreateEnhMetaFileA(0, NULL, NULL, NULL);
|
|
|
|
desc.u.emf.hemf = CloseEnhMetaFile(hdc);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
ok(0, "picture type %d is not supported\n", type);
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (void **)pict);
|
|
|
|
}
|
|
|
|
|
2007-06-05 11:33:24 +02:00
|
|
|
static void test_OleCreatePictureIndirect(void)
|
|
|
|
{
|
2018-07-06 10:10:37 +02:00
|
|
|
PICTDESC desc;
|
2010-08-24 20:36:38 +02:00
|
|
|
OLE_HANDLE handle;
|
2007-06-05 11:33:24 +02:00
|
|
|
IPicture *pict;
|
|
|
|
HRESULT hr;
|
2018-07-06 10:10:37 +02:00
|
|
|
short type, i;
|
2007-06-05 11:33:24 +02:00
|
|
|
|
2010-08-24 20:36:38 +02:00
|
|
|
if (0)
|
|
|
|
{
|
|
|
|
/* crashes on native */
|
2012-05-17 11:29:42 +02:00
|
|
|
OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, NULL);
|
2010-08-24 20:36:38 +02:00
|
|
|
}
|
|
|
|
|
2018-07-06 10:10:37 +02:00
|
|
|
desc.cbSizeofstruct = sizeof(desc);
|
|
|
|
desc.picType = PICTYPE_UNINITIALIZED;
|
|
|
|
pict = (void *)0xdeadbeef;
|
|
|
|
hr = OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (void **)&pict);
|
|
|
|
ok(hr == E_UNEXPECTED, "got %#x\n", hr);
|
|
|
|
ok(pict == NULL, "got %p\n", pict);
|
|
|
|
|
|
|
|
for (i = PICTYPE_UNINITIALIZED; i <= PICTYPE_ENHMETAFILE; i++)
|
|
|
|
{
|
|
|
|
hr = create_picture(i, &pict);
|
|
|
|
ok(hr == S_OK, "%d: got %#x\n", i, hr);
|
|
|
|
|
|
|
|
type = 0xdead;
|
|
|
|
hr = IPicture_get_Type(pict, &type);
|
|
|
|
ok(hr == S_OK, "%d: got %#x\n", i, hr);
|
|
|
|
ok(type == i, "%d: got %d\n", i, type);
|
|
|
|
|
|
|
|
handle = 0xdeadbeef;
|
|
|
|
hr = IPicture_get_Handle(pict, &handle);
|
|
|
|
ok(hr == S_OK, "%d: got %#x\n", i, hr);
|
|
|
|
if (type == PICTYPE_UNINITIALIZED || type == PICTYPE_NONE)
|
|
|
|
ok(handle == 0, "%d: got %#x\n", i, handle);
|
|
|
|
else
|
|
|
|
ok(handle != 0 && handle != 0xdeadbeef, "%d: got %#x\n", i, handle);
|
|
|
|
|
|
|
|
handle = 0xdeadbeef;
|
|
|
|
hr = IPicture_get_hPal(pict, &handle);
|
|
|
|
if (type == PICTYPE_BITMAP)
|
|
|
|
{
|
|
|
|
ok(hr == S_OK, "%d: got %#x\n", i, hr);
|
|
|
|
ok(handle == 0xbeefdead, "%d: got %#x\n", i, handle);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ok(hr == E_FAIL, "%d: got %#x\n", i, hr);
|
|
|
|
ok(handle == 0xdeadbeef || handle == 0 /* win64 */, "%d: got %#x\n", i, handle);
|
|
|
|
}
|
2007-06-05 11:33:24 +02:00
|
|
|
|
2018-07-06 10:10:37 +02:00
|
|
|
hr = IPicture_set_hPal(pict, HandleToUlong(GetStockObject(DEFAULT_PALETTE)));
|
|
|
|
if (type == PICTYPE_BITMAP)
|
|
|
|
ok(hr == S_OK, "%d: got %#x\n", i, hr);
|
|
|
|
else
|
|
|
|
ok(hr == E_FAIL, "%d: got %#x\n", i, hr);
|
2007-06-05 11:33:24 +02:00
|
|
|
|
2018-07-06 10:10:37 +02:00
|
|
|
IPicture_Release(pict);
|
|
|
|
}
|
2007-06-05 11:33:24 +02:00
|
|
|
}
|
|
|
|
|
2009-01-29 21:58:17 +01:00
|
|
|
static void test_apm(void)
|
2007-10-04 01:56:53 +02:00
|
|
|
{
|
|
|
|
OLE_HANDLE handle;
|
|
|
|
LPSTREAM stream;
|
|
|
|
IPicture *pict;
|
|
|
|
HGLOBAL hglob;
|
|
|
|
LPBYTE *data;
|
|
|
|
LONG cxy;
|
|
|
|
BOOL keep;
|
|
|
|
short type;
|
|
|
|
|
|
|
|
hglob = GlobalAlloc (0, sizeof(apmdata));
|
|
|
|
data = GlobalLock(hglob);
|
|
|
|
memcpy(data, apmdata, sizeof(apmdata));
|
|
|
|
|
|
|
|
ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
|
2012-01-09 10:01:37 +01:00
|
|
|
ole_check(pOleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict));
|
2007-10-04 01:56:53 +02:00
|
|
|
|
|
|
|
ole_check(IPicture_get_Handle(pict, &handle));
|
|
|
|
ok(handle != 0, "handle is null\n");
|
|
|
|
|
|
|
|
ole_check(IPicture_get_Type(pict, &type));
|
|
|
|
expect_eq(type, PICTYPE_METAFILE, short, "%d");
|
|
|
|
|
|
|
|
ole_check(IPicture_get_Height(pict, &cxy));
|
|
|
|
expect_eq(cxy, 1667, LONG, "%d");
|
|
|
|
|
|
|
|
ole_check(IPicture_get_Width(pict, &cxy));
|
|
|
|
expect_eq(cxy, 1323, LONG, "%d");
|
|
|
|
|
|
|
|
ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
|
|
|
|
todo_wine expect_eq(keep, FALSE, LONG, "%d");
|
|
|
|
|
|
|
|
ole_expect(IPicture_get_hPal(pict, &handle), E_FAIL);
|
|
|
|
IPicture_Release(pict);
|
|
|
|
IStream_Release(stream);
|
2008-10-04 01:24:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void test_metafile(void)
|
|
|
|
{
|
|
|
|
LPSTREAM stream;
|
|
|
|
IPicture *pict;
|
|
|
|
HGLOBAL hglob;
|
|
|
|
LPBYTE *data;
|
|
|
|
|
|
|
|
hglob = GlobalAlloc (0, sizeof(metafile));
|
|
|
|
data = GlobalLock(hglob);
|
|
|
|
memcpy(data, metafile, sizeof(metafile));
|
|
|
|
|
|
|
|
ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
|
|
|
|
/* Windows does not load simple metafiles */
|
2012-01-09 10:01:37 +01:00
|
|
|
ole_expect(pOleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL);
|
2008-10-04 01:24:37 +02:00
|
|
|
|
|
|
|
IStream_Release(stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test_enhmetafile(void)
|
|
|
|
{
|
|
|
|
OLE_HANDLE handle;
|
|
|
|
LPSTREAM stream;
|
|
|
|
IPicture *pict;
|
|
|
|
HGLOBAL hglob;
|
|
|
|
LPBYTE *data;
|
|
|
|
LONG cxy;
|
|
|
|
BOOL keep;
|
|
|
|
short type;
|
|
|
|
|
|
|
|
hglob = GlobalAlloc (0, sizeof(enhmetafile));
|
|
|
|
data = GlobalLock(hglob);
|
|
|
|
memcpy(data, enhmetafile, sizeof(enhmetafile));
|
|
|
|
|
|
|
|
ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
|
2012-01-09 10:01:37 +01:00
|
|
|
ole_check(pOleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict));
|
2008-10-04 01:24:37 +02:00
|
|
|
|
|
|
|
ole_check(IPicture_get_Handle(pict, &handle));
|
|
|
|
ok(handle != 0, "handle is null\n");
|
|
|
|
|
|
|
|
ole_check(IPicture_get_Type(pict, &type));
|
|
|
|
expect_eq(type, PICTYPE_ENHMETAFILE, short, "%d");
|
|
|
|
|
|
|
|
ole_check(IPicture_get_Height(pict, &cxy));
|
|
|
|
expect_eq(cxy, -23, LONG, "%d");
|
|
|
|
|
|
|
|
ole_check(IPicture_get_Width(pict, &cxy));
|
|
|
|
expect_eq(cxy, -25, LONG, "%d");
|
|
|
|
|
|
|
|
ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
|
|
|
|
todo_wine expect_eq(keep, FALSE, LONG, "%d");
|
|
|
|
|
|
|
|
IPicture_Release(pict);
|
|
|
|
IStream_Release(stream);
|
2007-10-04 01:56:53 +02:00
|
|
|
}
|
|
|
|
|
2014-02-28 13:57:19 +01:00
|
|
|
static HRESULT picture_render(IPicture *iface, HDC hdc, LONG x, LONG y, LONG cx, LONG cy,
|
|
|
|
OLE_XPOS_HIMETRIC xSrc,
|
|
|
|
OLE_YPOS_HIMETRIC ySrc,
|
|
|
|
OLE_XSIZE_HIMETRIC cxSrc,
|
|
|
|
OLE_YSIZE_HIMETRIC cySrc,
|
|
|
|
const RECT *bounds)
|
|
|
|
{
|
|
|
|
VARIANT ret, args[10];
|
|
|
|
HRESULT hr, hr_disp;
|
|
|
|
DISPPARAMS params;
|
|
|
|
IDispatch *disp;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
hr = IPicture_Render(iface, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, bounds);
|
|
|
|
|
|
|
|
IPicture_QueryInterface(iface, &IID_IDispatch, (void**)&disp);
|
|
|
|
|
|
|
|
/* This is broken on 64 bits - accepted pointer argument type is still VT_I4 */
|
2018-06-18 00:09:30 +02:00
|
|
|
for (i = 0; i < ARRAY_SIZE(args); i++)
|
2014-02-28 13:57:19 +01:00
|
|
|
V_VT(&args[i]) = VT_I4;
|
|
|
|
|
|
|
|
/* pack arguments and call */
|
|
|
|
V_INT_PTR(&args[0]) = (INT_PTR)bounds;
|
|
|
|
V_I4(&args[1]) = cySrc;
|
|
|
|
V_I4(&args[2]) = cxSrc;
|
|
|
|
V_I4(&args[3]) = ySrc;
|
|
|
|
V_I4(&args[4]) = xSrc;
|
|
|
|
V_I4(&args[5]) = cy;
|
|
|
|
V_I4(&args[6]) = cx;
|
|
|
|
V_I4(&args[7]) = y;
|
|
|
|
V_I4(&args[8]) = x;
|
|
|
|
V_I4(&args[9]) = HandleToLong(hdc);
|
|
|
|
|
|
|
|
params.rgvarg = args;
|
|
|
|
params.rgdispidNamedArgs = NULL;
|
|
|
|
params.cArgs = 10;
|
|
|
|
params.cNamedArgs = 0;
|
|
|
|
|
|
|
|
V_VT(&ret) = VT_EMPTY;
|
|
|
|
hr_disp = IDispatch_Invoke(disp, DISPID_PICT_RENDER, &GUID_NULL, 0, DISPATCH_METHOD,
|
|
|
|
¶ms, &ret, NULL, NULL);
|
|
|
|
ok(hr == hr_disp, "DISPID_PICT_RENDER returned wrong code, 0x%08x, expected 0x%08x\n",
|
|
|
|
hr_disp, hr);
|
|
|
|
|
|
|
|
IDispatch_Release(disp);
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
2008-12-10 13:08:47 +01:00
|
|
|
static void test_Render(void)
|
|
|
|
{
|
|
|
|
IPicture *pic;
|
|
|
|
HRESULT hres;
|
|
|
|
short type;
|
|
|
|
PICTDESC desc;
|
2009-10-14 18:54:39 +02:00
|
|
|
OLE_XSIZE_HIMETRIC pWidth;
|
|
|
|
OLE_YSIZE_HIMETRIC pHeight;
|
2009-10-18 20:42:47 +02:00
|
|
|
COLORREF result, expected;
|
2016-08-26 12:11:04 +02:00
|
|
|
HDC hdc = create_render_dc();
|
2008-12-10 13:08:47 +01:00
|
|
|
|
|
|
|
/* test IPicture::Render return code on uninitialized picture */
|
2018-01-05 12:25:11 +01:00
|
|
|
hres = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void **)&pic);
|
|
|
|
ok(hres == S_OK, "Failed to create a picture, hr %#x.\n", hres);
|
2008-12-10 13:08:47 +01:00
|
|
|
hres = IPicture_get_Type(pic, &type);
|
|
|
|
ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
|
|
|
|
ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
|
|
|
|
/* zero dimensions */
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
|
|
|
/* nonzero dimensions, PICTYPE_UNINITIALIZED */
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 10, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, S_OK);
|
|
|
|
IPicture_Release(pic);
|
|
|
|
|
|
|
|
desc.cbSizeofstruct = sizeof(PICTDESC);
|
|
|
|
desc.picType = PICTYPE_ICON;
|
2013-10-24 23:25:25 +02:00
|
|
|
desc.u.icon.hicon = LoadIconA(NULL, (LPCSTR)IDI_APPLICATION);
|
2008-12-10 13:08:47 +01:00
|
|
|
if(!desc.u.icon.hicon){
|
|
|
|
win_skip("LoadIcon failed. Skipping...\n");
|
2016-08-26 12:11:04 +02:00
|
|
|
delete_render_dc(hdc);
|
2008-12-10 13:08:47 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-05 12:25:11 +01:00
|
|
|
hres = OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (void **)&pic);
|
|
|
|
ok(hres == S_OK, "Failed to create a picture, hr %#x.\n", hres);
|
2008-12-10 13:08:47 +01:00
|
|
|
/* zero dimensions, PICTYPE_ICON */
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
2014-02-28 13:57:19 +01:00
|
|
|
hres = picture_render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
|
2008-12-10 13:08:47 +01:00
|
|
|
ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
|
|
|
|
|
2009-10-14 18:54:39 +02:00
|
|
|
/* Check if target size and position is respected */
|
|
|
|
IPicture_get_Width(pic, &pWidth);
|
|
|
|
IPicture_get_Height(pic, &pHeight);
|
|
|
|
|
2012-01-23 15:14:58 +01:00
|
|
|
SetPixelV(hdc, 0, 0, 0x00223344);
|
|
|
|
SetPixelV(hdc, 5, 5, 0x00223344);
|
|
|
|
SetPixelV(hdc, 10, 10, 0x00223344);
|
2009-10-18 20:42:47 +02:00
|
|
|
expected = GetPixel(hdc, 0, 0);
|
2009-10-14 18:54:39 +02:00
|
|
|
|
oleaut32/tests: Fix the IPicture::Render() usage.
When one specifies the target rectangle (0, 0, width, -height)
IPicture::Render() places the origin at 0,0 and flips the image
vertically. This means that in order to paint an icon on the DC
it's necessary to specify the rectangle (0, height, width, -height),
i.e. place the origin at 0,height. I've written a test app that
verifies this behaviour, ufortunately I don't see a way to add
a Wine test case for this.
The test currently works by chance under Windows because in case
of (0, 0, width, -height) IPicture::Render() draws black rectangle
instead of an icon at (0, 0, width, height). If Wine intends to
replicate this behaviour it should be fixed by a separate patch.
Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
2018-08-24 10:04:02 +02:00
|
|
|
hres = picture_render(pic, hdc, 1, 1, 9, 9, 0, pHeight, pWidth, -pHeight, NULL);
|
2009-10-18 20:42:47 +02:00
|
|
|
ole_expect(hres, S_OK);
|
|
|
|
|
2016-08-26 12:11:04 +02:00
|
|
|
if(hres != S_OK) goto done;
|
2009-10-14 18:54:39 +02:00
|
|
|
|
2009-10-18 20:42:47 +02:00
|
|
|
/* Evaluate the rendered Icon */
|
2009-10-14 18:54:39 +02:00
|
|
|
result = GetPixel(hdc, 0, 0);
|
2009-10-18 20:42:47 +02:00
|
|
|
ok(result == expected,
|
|
|
|
"Color at 0,0 should be unchanged 0x%06X, but was 0x%06X\n", expected, result);
|
2009-10-14 18:54:39 +02:00
|
|
|
result = GetPixel(hdc, 5, 5);
|
2016-08-26 12:11:05 +02:00
|
|
|
ok(result != expected,
|
2009-10-18 20:42:47 +02:00
|
|
|
"Color at 5,5 should have changed, but still was 0x%06X\n", expected);
|
2009-10-14 18:54:39 +02:00
|
|
|
result = GetPixel(hdc, 10, 10);
|
2009-10-18 20:42:47 +02:00
|
|
|
ok(result == expected,
|
|
|
|
"Color at 10,10 should be unchanged 0x%06X, but was 0x%06X\n", expected, result);
|
2009-10-14 18:54:39 +02:00
|
|
|
|
2016-08-26 12:11:04 +02:00
|
|
|
done:
|
2009-10-14 18:54:39 +02:00
|
|
|
IPicture_Release(pic);
|
2016-08-26 12:11:04 +02:00
|
|
|
delete_render_dc(hdc);
|
2008-12-10 13:08:47 +01:00
|
|
|
}
|
|
|
|
|
2009-01-05 22:25:43 +01:00
|
|
|
static void test_get_Attributes(void)
|
|
|
|
{
|
|
|
|
IPicture *pic;
|
|
|
|
HRESULT hres;
|
|
|
|
short type;
|
|
|
|
DWORD attr;
|
|
|
|
|
2018-01-05 12:25:11 +01:00
|
|
|
hres = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void **)&pic);
|
|
|
|
ok(hres == S_OK, "Failed to create a picture, hr %#x.\n", hres);
|
2009-01-05 22:25:43 +01:00
|
|
|
hres = IPicture_get_Type(pic, &type);
|
|
|
|
ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
|
|
|
|
ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
|
|
|
|
|
2009-01-05 22:40:07 +01:00
|
|
|
hres = IPicture_get_Attributes(pic, NULL);
|
|
|
|
ole_expect(hres, E_POINTER);
|
|
|
|
|
2009-01-05 22:25:43 +01:00
|
|
|
attr = 0xdeadbeef;
|
|
|
|
hres = IPicture_get_Attributes(pic, &attr);
|
|
|
|
ole_expect(hres, S_OK);
|
|
|
|
ok(attr == 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr);
|
|
|
|
|
|
|
|
IPicture_Release(pic);
|
|
|
|
}
|
|
|
|
|
2009-01-07 07:07:06 +01:00
|
|
|
static void test_get_Handle(void)
|
|
|
|
{
|
|
|
|
IPicture *pic;
|
|
|
|
HRESULT hres;
|
|
|
|
|
2018-01-05 12:25:11 +01:00
|
|
|
hres = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void **)&pic);
|
|
|
|
ok(hres == S_OK, "Failed to create a picture, hr %#x.\n", hres);
|
2009-01-07 07:07:06 +01:00
|
|
|
hres = IPicture_get_Handle(pic, NULL);
|
|
|
|
ole_expect(hres, E_POINTER);
|
|
|
|
|
|
|
|
IPicture_Release(pic);
|
|
|
|
}
|
|
|
|
|
2009-01-07 07:31:00 +01:00
|
|
|
static void test_get_Type(void)
|
|
|
|
{
|
|
|
|
IPicture *pic;
|
|
|
|
HRESULT hres;
|
|
|
|
|
2018-01-05 12:25:11 +01:00
|
|
|
hres = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void **)&pic);
|
|
|
|
ok(hres == S_OK, "Failed to create a picture, hr %#x.\n", hres);
|
2009-01-07 07:31:00 +01:00
|
|
|
|
|
|
|
hres = IPicture_get_Type(pic, NULL);
|
|
|
|
ole_expect(hres, E_POINTER);
|
|
|
|
|
|
|
|
IPicture_Release(pic);
|
|
|
|
}
|
|
|
|
|
2010-05-20 05:26:15 +02:00
|
|
|
static void test_OleLoadPicturePath(void)
|
|
|
|
{
|
|
|
|
static WCHAR emptyW[] = {0};
|
|
|
|
|
|
|
|
IPicture *pic;
|
|
|
|
HRESULT hres;
|
|
|
|
int i;
|
2010-05-20 05:29:42 +02:00
|
|
|
char temp_path[MAX_PATH];
|
|
|
|
char temp_file[MAX_PATH];
|
|
|
|
WCHAR temp_fileW[MAX_PATH + 5] = {'f','i','l','e',':','/','/','/'};
|
|
|
|
HANDLE file;
|
|
|
|
DWORD size;
|
|
|
|
WCHAR *ptr;
|
2010-05-20 05:26:15 +02:00
|
|
|
|
|
|
|
const struct
|
|
|
|
{
|
|
|
|
LPOLESTR szURLorPath;
|
|
|
|
REFIID riid;
|
|
|
|
IPicture **pic;
|
|
|
|
} invalid_parameters[] =
|
|
|
|
{
|
|
|
|
{NULL, NULL, NULL},
|
|
|
|
{NULL, NULL, &pic},
|
|
|
|
{NULL, &IID_IPicture, NULL},
|
|
|
|
{NULL, &IID_IPicture, &pic},
|
|
|
|
{emptyW, NULL, NULL},
|
|
|
|
{emptyW, &IID_IPicture, NULL},
|
|
|
|
};
|
|
|
|
|
2018-06-18 00:09:30 +02:00
|
|
|
for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
|
2010-05-20 05:26:15 +02:00
|
|
|
{
|
|
|
|
pic = (IPicture *)0xdeadbeef;
|
|
|
|
hres = OleLoadPicturePath(invalid_parameters[i].szURLorPath, NULL, 0, 0,
|
|
|
|
invalid_parameters[i].riid,
|
|
|
|
(void **)invalid_parameters[i].pic);
|
|
|
|
ok(hres == E_INVALIDARG,
|
|
|
|
"[%d] Expected OleLoadPicturePath to return E_INVALIDARG, got 0x%08x\n", i, hres);
|
|
|
|
ok(pic == (IPicture *)0xdeadbeef,
|
|
|
|
"[%d] Expected output pointer to be 0xdeadbeef, got %p\n", i, pic);
|
|
|
|
}
|
|
|
|
|
|
|
|
pic = (IPicture *)0xdeadbeef;
|
|
|
|
hres = OleLoadPicturePath(emptyW, NULL, 0, 0, NULL, (void **)&pic);
|
|
|
|
todo_wine
|
|
|
|
ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */
|
2011-02-25 00:55:45 +01:00
|
|
|
broken(hres == E_UNEXPECTED) || /* NT4 */
|
|
|
|
broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */
|
2010-05-20 05:26:15 +02:00
|
|
|
"Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres);
|
|
|
|
ok(pic == NULL,
|
|
|
|
"Expected the output interface pointer to be NULL, got %p\n", pic);
|
|
|
|
|
|
|
|
pic = (IPicture *)0xdeadbeef;
|
|
|
|
hres = OleLoadPicturePath(emptyW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
|
|
|
|
todo_wine
|
|
|
|
ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */
|
2011-02-25 00:55:45 +01:00
|
|
|
broken(hres == E_UNEXPECTED) || /* NT4 */
|
|
|
|
broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */
|
2010-05-20 05:26:15 +02:00
|
|
|
"Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres);
|
|
|
|
ok(pic == NULL,
|
|
|
|
"Expected the output interface pointer to be NULL, got %p\n", pic);
|
2010-05-20 05:29:42 +02:00
|
|
|
|
|
|
|
/* Create a local temporary image file for testing. */
|
|
|
|
GetTempPathA(sizeof(temp_path), temp_path);
|
|
|
|
GetTempFileNameA(temp_path, "bmp", 0, temp_file);
|
|
|
|
file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
|
|
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
WriteFile(file, bmpimage, sizeof(bmpimage), &size, NULL);
|
|
|
|
CloseHandle(file);
|
|
|
|
|
2018-06-18 00:09:30 +02:00
|
|
|
MultiByteToWideChar(CP_ACP, 0, temp_file, -1, temp_fileW + 8, ARRAY_SIZE(temp_fileW) - 8);
|
2010-05-20 05:29:42 +02:00
|
|
|
|
|
|
|
/* Try a normal DOS path. */
|
|
|
|
hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic);
|
|
|
|
ok(hres == S_OK ||
|
2011-02-25 00:55:45 +01:00
|
|
|
broken(hres == E_UNEXPECTED), /* NT4 */
|
2010-05-20 05:29:42 +02:00
|
|
|
"Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
|
|
|
|
if (pic)
|
|
|
|
IPicture_Release(pic);
|
|
|
|
|
|
|
|
/* Try a DOS path with tacked on "file:". */
|
|
|
|
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
|
|
|
|
ok(hres == S_OK ||
|
2011-02-25 00:55:45 +01:00
|
|
|
broken(hres == E_UNEXPECTED), /* NT4 */
|
2010-05-20 05:29:42 +02:00
|
|
|
"Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
|
|
|
|
if (pic)
|
|
|
|
IPicture_Release(pic);
|
|
|
|
|
|
|
|
DeleteFileA(temp_file);
|
|
|
|
|
2010-06-24 10:18:34 +02:00
|
|
|
/* Try with a nonexistent file. */
|
2010-05-20 05:29:42 +02:00
|
|
|
hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic);
|
2011-02-25 01:08:34 +01:00
|
|
|
ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
|
2011-02-25 00:55:45 +01:00
|
|
|
broken(hres == E_UNEXPECTED) || /* NT4 */
|
|
|
|
broken(hres == E_FAIL), /*Win2k */
|
2010-05-20 05:29:42 +02:00
|
|
|
"Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
|
|
|
|
|
|
|
|
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
|
2011-02-25 01:08:34 +01:00
|
|
|
ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
|
2011-02-25 00:55:45 +01:00
|
|
|
broken(hres == E_UNEXPECTED) || /* NT4 */
|
|
|
|
broken(hres == E_FAIL), /* Win2k */
|
2010-05-20 05:29:42 +02:00
|
|
|
"Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
|
|
|
|
|
|
|
|
file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
|
|
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
WriteFile(file, bmpimage, sizeof(bmpimage), &size, NULL);
|
|
|
|
CloseHandle(file);
|
|
|
|
|
|
|
|
/* Try a "file:" URL with slash separators. */
|
|
|
|
ptr = temp_fileW + 8;
|
|
|
|
while (*ptr)
|
|
|
|
{
|
|
|
|
if (*ptr == '\\')
|
|
|
|
*ptr = '/';
|
|
|
|
ptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
|
|
|
|
ok(hres == S_OK ||
|
2011-02-25 00:55:45 +01:00
|
|
|
broken(hres == E_UNEXPECTED), /* NT4 */
|
2010-05-20 05:29:42 +02:00
|
|
|
"Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
|
|
|
|
if (pic)
|
|
|
|
IPicture_Release(pic);
|
|
|
|
|
|
|
|
DeleteFileA(temp_file);
|
|
|
|
|
2010-06-24 10:18:34 +02:00
|
|
|
/* Try with a nonexistent file. */
|
2010-05-20 05:29:42 +02:00
|
|
|
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
|
2011-02-25 01:08:34 +01:00
|
|
|
ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
|
2011-02-25 00:55:45 +01:00
|
|
|
broken(hres == E_UNEXPECTED) || /* NT4 */
|
|
|
|
broken(hres == E_FAIL), /* Win2k */
|
2010-05-20 05:29:42 +02:00
|
|
|
"Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
|
2010-05-20 05:26:15 +02:00
|
|
|
}
|
|
|
|
|
2010-08-23 08:59:06 +02:00
|
|
|
static void test_himetric(void)
|
|
|
|
{
|
|
|
|
static const BYTE bmp_bits[1024];
|
|
|
|
OLE_XSIZE_HIMETRIC cx;
|
|
|
|
OLE_YSIZE_HIMETRIC cy;
|
|
|
|
IPicture *pic;
|
|
|
|
PICTDESC desc;
|
|
|
|
HBITMAP bmp;
|
|
|
|
HRESULT hr;
|
|
|
|
HICON icon;
|
|
|
|
HDC hdc;
|
|
|
|
INT d;
|
|
|
|
|
|
|
|
desc.cbSizeofstruct = sizeof(desc);
|
|
|
|
desc.picType = PICTYPE_BITMAP;
|
|
|
|
desc.u.bmp.hpal = NULL;
|
|
|
|
|
|
|
|
hdc = CreateCompatibleDC(0);
|
|
|
|
|
|
|
|
bmp = CreateBitmap(1.9 * GetDeviceCaps(hdc, LOGPIXELSX),
|
|
|
|
1.9 * GetDeviceCaps(hdc, LOGPIXELSY), 1, 1, NULL);
|
|
|
|
|
|
|
|
desc.u.bmp.hbitmap = bmp;
|
|
|
|
|
|
|
|
/* size in himetric units reported rounded up to next integer value */
|
2012-05-17 11:29:42 +02:00
|
|
|
hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
|
2010-08-23 08:59:06 +02:00
|
|
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
|
|
|
|
|
|
|
cx = 0;
|
|
|
|
d = MulDiv((INT)(1.9 * GetDeviceCaps(hdc, LOGPIXELSX)), 2540, GetDeviceCaps(hdc, LOGPIXELSX));
|
|
|
|
hr = IPicture_get_Width(pic, &cx);
|
|
|
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
|
|
|
ok(cx == d, "got %d, expected %d\n", cx, d);
|
|
|
|
|
|
|
|
cy = 0;
|
|
|
|
d = MulDiv((INT)(1.9 * GetDeviceCaps(hdc, LOGPIXELSY)), 2540, GetDeviceCaps(hdc, LOGPIXELSY));
|
|
|
|
hr = IPicture_get_Height(pic, &cy);
|
|
|
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
|
|
|
ok(cy == d, "got %d, expected %d\n", cy, d);
|
|
|
|
|
|
|
|
DeleteObject(bmp);
|
|
|
|
IPicture_Release(pic);
|
|
|
|
|
|
|
|
/* same thing with icon */
|
|
|
|
icon = CreateIcon(NULL, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON),
|
|
|
|
1, 1, bmp_bits, bmp_bits);
|
|
|
|
ok(icon != NULL, "failed to create icon\n");
|
|
|
|
|
|
|
|
desc.picType = PICTYPE_ICON;
|
|
|
|
desc.u.icon.hicon = icon;
|
|
|
|
|
2012-05-17 11:29:42 +02:00
|
|
|
hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
|
2010-08-23 08:59:06 +02:00
|
|
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
|
|
|
|
|
|
|
cx = 0;
|
|
|
|
d = MulDiv(GetSystemMetrics(SM_CXICON), 2540, GetDeviceCaps(hdc, LOGPIXELSX));
|
|
|
|
hr = IPicture_get_Width(pic, &cx);
|
|
|
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
|
|
|
ok(cx == d, "got %d, expected %d\n", cx, d);
|
|
|
|
|
|
|
|
cy = 0;
|
|
|
|
d = MulDiv(GetSystemMetrics(SM_CYICON), 2540, GetDeviceCaps(hdc, LOGPIXELSY));
|
|
|
|
hr = IPicture_get_Height(pic, &cy);
|
|
|
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
|
|
|
ok(cy == d, "got %d, expected %d\n", cy, d);
|
|
|
|
|
|
|
|
IPicture_Release(pic);
|
|
|
|
DestroyIcon(icon);
|
|
|
|
|
|
|
|
DeleteDC(hdc);
|
|
|
|
}
|
|
|
|
|
2012-05-17 11:30:44 +02:00
|
|
|
static void test_load_save_bmp(void)
|
|
|
|
{
|
|
|
|
IPicture *pic;
|
|
|
|
PICTDESC desc;
|
|
|
|
short type;
|
|
|
|
OLE_HANDLE handle;
|
|
|
|
HGLOBAL hmem;
|
|
|
|
DWORD *mem;
|
|
|
|
IPersistStream *src_stream;
|
|
|
|
IStream *dst_stream;
|
2015-11-24 10:27:31 +01:00
|
|
|
LARGE_INTEGER offset;
|
2012-05-17 11:30:44 +02:00
|
|
|
HRESULT hr;
|
2015-11-24 10:27:31 +01:00
|
|
|
LONG size;
|
2012-05-17 11:30:44 +02:00
|
|
|
|
|
|
|
desc.cbSizeofstruct = sizeof(desc);
|
|
|
|
desc.picType = PICTYPE_BITMAP;
|
|
|
|
desc.u.bmp.hpal = 0;
|
|
|
|
desc.u.bmp.hbitmap = CreateBitmap(1, 1, 1, 1, NULL);
|
|
|
|
hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
|
|
|
|
ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr);
|
|
|
|
|
|
|
|
type = -1;
|
|
|
|
hr = IPicture_get_Type(pic, &type);
|
|
|
|
ok(hr == S_OK,"get_Type error %#8x\n", hr);
|
|
|
|
ok(type == PICTYPE_BITMAP,"expected picture type PICTYPE_BITMAP, got %d\n", type);
|
|
|
|
|
|
|
|
hr = IPicture_get_Handle(pic, &handle);
|
|
|
|
ok(hr == S_OK,"get_Handle error %#8x\n", hr);
|
2012-05-25 10:29:28 +02:00
|
|
|
ok(IntToPtr(handle) == desc.u.bmp.hbitmap, "get_Handle returned wrong handle %#x\n", handle);
|
2012-05-17 11:30:44 +02:00
|
|
|
|
|
|
|
hmem = GlobalAlloc(GMEM_ZEROINIT, 4096);
|
|
|
|
hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
|
|
|
|
ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
|
|
|
|
|
2015-11-24 10:27:31 +01:00
|
|
|
size = -1;
|
|
|
|
hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
|
|
|
|
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
|
2015-11-25 06:09:13 +01:00
|
|
|
todo_wine
|
2015-11-24 10:27:31 +01:00
|
|
|
ok(size == 66, "expected 66, got %d\n", size);
|
|
|
|
mem = GlobalLock(hmem);
|
2015-11-25 06:09:13 +01:00
|
|
|
todo_wine
|
2015-11-24 10:27:31 +01:00
|
|
|
ok(!memcmp(&mem[0], "BM", 2), "got wrong bmp header %04x\n", mem[0]);
|
|
|
|
GlobalUnlock(hmem);
|
|
|
|
|
|
|
|
size = -1;
|
|
|
|
hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
|
2015-11-25 06:09:13 +01:00
|
|
|
todo_wine
|
2015-11-24 10:27:31 +01:00
|
|
|
ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr);
|
2015-11-25 06:09:13 +01:00
|
|
|
todo_wine
|
2015-11-24 10:27:31 +01:00
|
|
|
ok(size == -1, "expected -1, got %d\n", size);
|
|
|
|
|
|
|
|
offset.QuadPart = 0;
|
|
|
|
hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL);
|
|
|
|
ok(hr == S_OK, "IStream_Seek %#x\n", hr);
|
|
|
|
|
2012-05-17 11:30:44 +02:00
|
|
|
hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
|
|
|
|
ok(hr == S_OK, "QueryInterface error %#x\n", hr);
|
|
|
|
|
|
|
|
hr = IPersistStream_Save(src_stream, dst_stream, TRUE);
|
|
|
|
ok(hr == S_OK, "Save error %#x\n", hr);
|
|
|
|
|
|
|
|
IPersistStream_Release(src_stream);
|
|
|
|
IStream_Release(dst_stream);
|
|
|
|
|
|
|
|
mem = GlobalLock(hmem);
|
|
|
|
ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]);
|
|
|
|
ok(mem[1] == 66, "expected stream size 66, got %u\n", mem[1]);
|
|
|
|
ok(!memcmp(&mem[2], "BM", 2), "got wrong bmp header %04x\n", mem[2]);
|
|
|
|
|
|
|
|
GlobalUnlock(hmem);
|
|
|
|
GlobalFree(hmem);
|
|
|
|
|
|
|
|
DeleteObject(desc.u.bmp.hbitmap);
|
|
|
|
IPicture_Release(pic);
|
|
|
|
}
|
|
|
|
|
2012-06-01 08:37:47 +02:00
|
|
|
static void test_load_save_icon(void)
|
|
|
|
{
|
|
|
|
IPicture *pic;
|
|
|
|
PICTDESC desc;
|
|
|
|
short type;
|
|
|
|
OLE_HANDLE handle;
|
|
|
|
HGLOBAL hmem;
|
|
|
|
DWORD *mem;
|
|
|
|
IPersistStream *src_stream;
|
|
|
|
IStream *dst_stream;
|
2015-11-24 10:27:31 +01:00
|
|
|
LARGE_INTEGER offset;
|
2012-06-01 08:37:47 +02:00
|
|
|
HRESULT hr;
|
2015-11-24 10:27:31 +01:00
|
|
|
LONG size;
|
2012-06-01 08:37:47 +02:00
|
|
|
|
|
|
|
desc.cbSizeofstruct = sizeof(desc);
|
|
|
|
desc.picType = PICTYPE_ICON;
|
2013-10-24 23:25:25 +02:00
|
|
|
desc.u.icon.hicon = LoadIconA(NULL, (LPCSTR)IDI_APPLICATION);
|
2012-06-01 08:37:47 +02:00
|
|
|
hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
|
|
|
|
ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr);
|
|
|
|
|
|
|
|
type = -1;
|
|
|
|
hr = IPicture_get_Type(pic, &type);
|
|
|
|
ok(hr == S_OK,"get_Type error %#8x\n", hr);
|
|
|
|
ok(type == PICTYPE_ICON,"expected picture type PICTYPE_ICON, got %d\n", type);
|
|
|
|
|
|
|
|
hr = IPicture_get_Handle(pic, &handle);
|
|
|
|
ok(hr == S_OK,"get_Handle error %#8x\n", hr);
|
|
|
|
ok(IntToPtr(handle) == desc.u.icon.hicon, "get_Handle returned wrong handle %#x\n", handle);
|
|
|
|
|
|
|
|
hmem = GlobalAlloc(GMEM_ZEROINIT, 8192);
|
|
|
|
hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
|
|
|
|
ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
|
|
|
|
|
2015-11-24 10:27:31 +01:00
|
|
|
size = -1;
|
|
|
|
hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
|
|
|
|
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
|
|
|
|
todo_wine
|
|
|
|
ok(size == 766, "expected 766, got %d\n", size);
|
|
|
|
mem = GlobalLock(hmem);
|
2015-11-25 06:09:13 +01:00
|
|
|
todo_wine
|
2015-11-24 10:27:31 +01:00
|
|
|
ok(mem[0] == 0x00010000, "got wrong icon header %04x\n", mem[0]);
|
|
|
|
GlobalUnlock(hmem);
|
|
|
|
|
|
|
|
size = -1;
|
|
|
|
hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
|
2015-11-25 06:09:13 +01:00
|
|
|
todo_wine
|
2015-11-24 10:27:31 +01:00
|
|
|
ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr);
|
2015-11-25 06:09:13 +01:00
|
|
|
todo_wine
|
2015-11-24 10:27:31 +01:00
|
|
|
ok(size == -1, "expected -1, got %d\n", size);
|
|
|
|
|
|
|
|
offset.QuadPart = 0;
|
|
|
|
hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL);
|
|
|
|
ok(hr == S_OK, "IStream_Seek %#x\n", hr);
|
|
|
|
|
2012-06-01 08:37:47 +02:00
|
|
|
hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
|
|
|
|
ok(hr == S_OK, "QueryInterface error %#x\n", hr);
|
|
|
|
|
|
|
|
hr = IPersistStream_Save(src_stream, dst_stream, TRUE);
|
|
|
|
ok(hr == S_OK, "Saveerror %#x\n", hr);
|
|
|
|
|
|
|
|
IPersistStream_Release(src_stream);
|
|
|
|
IStream_Release(dst_stream);
|
|
|
|
|
|
|
|
mem = GlobalLock(hmem);
|
|
|
|
ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]);
|
|
|
|
todo_wine
|
|
|
|
ok(mem[1] == 766, "expected stream size 766, got %u\n", mem[1]);
|
|
|
|
ok(mem[2] == 0x00010000, "got wrong icon header %04x\n", mem[2]);
|
|
|
|
|
|
|
|
GlobalUnlock(hmem);
|
|
|
|
GlobalFree(hmem);
|
|
|
|
|
2012-10-18 20:18:47 +02:00
|
|
|
DestroyIcon(desc.u.icon.hicon);
|
2012-06-01 08:37:47 +02:00
|
|
|
IPicture_Release(pic);
|
|
|
|
}
|
|
|
|
|
2012-11-26 10:49:58 +01:00
|
|
|
static void test_load_save_empty_picture(void)
|
|
|
|
{
|
|
|
|
IPicture *pic;
|
|
|
|
PICTDESC desc;
|
|
|
|
short type;
|
|
|
|
OLE_HANDLE handle;
|
|
|
|
HGLOBAL hmem;
|
|
|
|
DWORD *mem;
|
|
|
|
IPersistStream *src_stream;
|
2014-04-10 10:03:09 +02:00
|
|
|
IStream *dst_stream, *stream;
|
|
|
|
LARGE_INTEGER offset;
|
2012-11-26 10:49:58 +01:00
|
|
|
HRESULT hr;
|
2015-11-24 10:27:31 +01:00
|
|
|
LONG size;
|
2012-11-26 10:49:58 +01:00
|
|
|
|
|
|
|
memset(&pic, 0, sizeof(pic));
|
|
|
|
desc.cbSizeofstruct = sizeof(desc);
|
|
|
|
desc.picType = PICTYPE_NONE;
|
|
|
|
hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void **)&pic);
|
|
|
|
ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr);
|
|
|
|
|
|
|
|
type = -1;
|
|
|
|
hr = IPicture_get_Type(pic, &type);
|
2015-11-24 10:27:31 +01:00
|
|
|
ok(hr == S_OK, "get_Type error %#x\n", hr);
|
2012-11-26 10:49:58 +01:00
|
|
|
ok(type == PICTYPE_NONE,"expected picture type PICTYPE_NONE, got %d\n", type);
|
|
|
|
|
|
|
|
handle = (OLE_HANDLE)0xdeadbeef;
|
|
|
|
hr = IPicture_get_Handle(pic, &handle);
|
|
|
|
ok(hr == S_OK,"get_Handle error %#8x\n", hr);
|
|
|
|
ok(!handle, "get_Handle returned wrong handle %#x\n", handle);
|
|
|
|
|
|
|
|
hmem = GlobalAlloc(GMEM_ZEROINIT, 4096);
|
|
|
|
hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
|
|
|
|
ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
|
|
|
|
|
2015-11-24 10:27:31 +01:00
|
|
|
size = -1;
|
|
|
|
hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
|
|
|
|
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
|
2015-11-25 06:09:13 +01:00
|
|
|
todo_wine
|
2015-11-24 10:27:31 +01:00
|
|
|
ok(size == -1, "expected -1, got %d\n", size);
|
|
|
|
|
|
|
|
size = -1;
|
|
|
|
hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
|
|
|
|
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
|
2015-11-25 06:09:13 +01:00
|
|
|
todo_wine
|
2015-11-24 10:27:31 +01:00
|
|
|
ok(size == -1, "expected -1, got %d\n", size);
|
|
|
|
|
2012-11-26 10:49:58 +01:00
|
|
|
hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
|
|
|
|
ok(hr == S_OK, "QueryInterface error %#x\n", hr);
|
|
|
|
|
|
|
|
hr = IPersistStream_Save(src_stream, dst_stream, TRUE);
|
|
|
|
ok(hr == S_OK, "Save error %#x\n", hr);
|
|
|
|
|
|
|
|
mem = GlobalLock(hmem);
|
|
|
|
ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]);
|
|
|
|
ok(mem[1] == 0, "expected stream size 0, got %u\n", mem[1]);
|
|
|
|
GlobalUnlock(hmem);
|
|
|
|
|
|
|
|
IPersistStream_Release(src_stream);
|
2014-04-10 10:03:09 +02:00
|
|
|
IPicture_Release(pic);
|
|
|
|
|
|
|
|
/* first with statable and seekable stream */
|
|
|
|
offset.QuadPart = 0;
|
|
|
|
hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL);
|
|
|
|
ok(hr == S_OK, "IStream_Seek %#x\n", hr);
|
|
|
|
|
|
|
|
pic = NULL;
|
|
|
|
hr = pOleLoadPicture(dst_stream, 0, FALSE, &IID_IPicture, (void **)&pic);
|
|
|
|
ok(hr == S_OK, "OleLoadPicture error %#x\n", hr);
|
|
|
|
ok(pic != NULL,"picture should not be not NULL\n");
|
|
|
|
if (pic != NULL)
|
|
|
|
{
|
|
|
|
type = -1;
|
|
|
|
hr = IPicture_get_Type(pic, &type);
|
|
|
|
ok(hr == S_OK,"get_Type error %#8x\n", hr);
|
|
|
|
ok(type == PICTYPE_NONE,"expected picture type PICTYPE_NONE, got %d\n", type);
|
|
|
|
|
|
|
|
handle = (OLE_HANDLE)0xdeadbeef;
|
|
|
|
hr = IPicture_get_Handle(pic, &handle);
|
|
|
|
ok(hr == S_OK,"get_Handle error %#8x\n", hr);
|
|
|
|
ok(!handle, "get_Handle returned wrong handle %#x\n", handle);
|
|
|
|
|
|
|
|
IPicture_Release(pic);
|
|
|
|
}
|
2012-11-26 10:49:58 +01:00
|
|
|
IStream_Release(dst_stream);
|
|
|
|
|
2014-04-10 10:03:09 +02:00
|
|
|
/* again with non-statable and non-seekable stream */
|
|
|
|
stream = NoStatStream_Construct(hmem);
|
|
|
|
ok(stream != NULL, "failed to create empty image stream\n");
|
|
|
|
|
|
|
|
pic = NULL;
|
|
|
|
hr = pOleLoadPicture(stream, 0, FALSE, &IID_IPicture, (void **)&pic);
|
|
|
|
ok(hr == S_OK, "OleLoadPicture error %#x\n", hr);
|
|
|
|
ok(pic != NULL,"picture should not be not NULL\n");
|
|
|
|
if (pic != NULL)
|
|
|
|
{
|
|
|
|
type = -1;
|
|
|
|
hr = IPicture_get_Type(pic, &type);
|
|
|
|
ok(hr == S_OK,"get_Type error %#8x\n", hr);
|
|
|
|
ok(type == PICTYPE_NONE,"expected picture type PICTYPE_NONE, got %d\n", type);
|
|
|
|
|
|
|
|
handle = (OLE_HANDLE)0xdeadbeef;
|
|
|
|
hr = IPicture_get_Handle(pic, &handle);
|
|
|
|
ok(hr == S_OK,"get_Handle error %#8x\n", hr);
|
|
|
|
ok(!handle, "get_Handle returned wrong handle %#x\n", handle);
|
|
|
|
|
|
|
|
IPicture_Release(pic);
|
|
|
|
}
|
|
|
|
/* Non-statable impl always deletes on release */
|
|
|
|
IStream_Release(stream);
|
2012-11-26 10:49:58 +01:00
|
|
|
}
|
|
|
|
|
2005-06-06 12:03:58 +02:00
|
|
|
START_TEST(olepicture)
|
|
|
|
{
|
2012-01-09 09:59:55 +01:00
|
|
|
hOleaut32 = GetModuleHandleA("oleaut32.dll");
|
|
|
|
pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture");
|
2012-01-09 10:01:37 +01:00
|
|
|
pOleLoadPictureEx = (void*)GetProcAddress(hOleaut32, "OleLoadPictureEx");
|
2012-01-09 09:59:55 +01:00
|
|
|
if (!pOleLoadPicture)
|
|
|
|
{
|
|
|
|
win_skip("OleLoadPicture is not available\n");
|
|
|
|
return;
|
|
|
|
}
|
2005-06-06 12:03:58 +02:00
|
|
|
|
2012-01-09 09:59:55 +01:00
|
|
|
/* Test regular 1x1 pixel images of gif, jpg, bmp type */
|
|
|
|
test_pic(gifimage, sizeof(gifimage));
|
|
|
|
test_pic(jpgimage, sizeof(jpgimage));
|
|
|
|
test_pic(bmpimage, sizeof(bmpimage));
|
|
|
|
test_pic(gif4pixel, sizeof(gif4pixel));
|
|
|
|
/* FIXME: No PNG support in Windows... */
|
|
|
|
if (0) test_pic(pngimage, sizeof(pngimage));
|
|
|
|
test_empty_image();
|
|
|
|
test_empty_image_2();
|
2012-01-09 10:01:37 +01:00
|
|
|
if (pOleLoadPictureEx)
|
|
|
|
{
|
|
|
|
test_apm();
|
|
|
|
test_metafile();
|
|
|
|
test_enhmetafile();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
win_skip("OleLoadPictureEx is not available\n");
|
2010-05-20 05:26:15 +02:00
|
|
|
test_Invoke();
|
|
|
|
test_OleCreatePictureIndirect();
|
|
|
|
test_Render();
|
|
|
|
test_get_Attributes();
|
|
|
|
test_get_Handle();
|
|
|
|
test_get_Type();
|
|
|
|
test_OleLoadPicturePath();
|
2010-08-23 08:59:06 +02:00
|
|
|
test_himetric();
|
2012-05-17 11:30:44 +02:00
|
|
|
test_load_save_bmp();
|
2012-06-01 08:37:47 +02:00
|
|
|
test_load_save_icon();
|
2012-11-26 10:49:58 +01:00
|
|
|
test_load_save_empty_picture();
|
2005-06-06 12:03:58 +02:00
|
|
|
}
|
2005-11-07 12:09:10 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* Helper functions only ... */
|
|
|
|
|
|
|
|
|
2011-03-15 11:35:36 +01:00
|
|
|
static inline NoStatStreamImpl *impl_from_IStream(IStream *iface)
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, NoStatStreamImpl, IStream_iface);
|
|
|
|
}
|
|
|
|
|
2005-11-07 12:09:10 +01:00
|
|
|
static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This)
|
|
|
|
{
|
|
|
|
GlobalFree(This->supportHandle);
|
|
|
|
This->supportHandle=0;
|
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI NoStatStreamImpl_AddRef(
|
|
|
|
IStream* iface)
|
|
|
|
{
|
2011-03-15 11:35:36 +01:00
|
|
|
NoStatStreamImpl* const This = impl_from_IStream(iface);
|
2005-11-07 12:09:10 +01:00
|
|
|
return InterlockedIncrement(&This->ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
|
|
|
|
IStream* iface,
|
|
|
|
REFIID riid, /* [in] */
|
|
|
|
void** ppvObject) /* [iid_is][out] */
|
|
|
|
{
|
2011-03-15 11:35:36 +01:00
|
|
|
NoStatStreamImpl* const This = impl_from_IStream(iface);
|
2005-11-07 12:09:10 +01:00
|
|
|
if (ppvObject==0) return E_INVALIDARG;
|
|
|
|
*ppvObject = 0;
|
2017-02-05 17:54:44 +01:00
|
|
|
|
|
|
|
if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IStream, riid))
|
|
|
|
*ppvObject = &This->IStream_iface;
|
2005-11-07 12:09:10 +01:00
|
|
|
|
|
|
|
if ((*ppvObject)==0)
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
NoStatStreamImpl_AddRef(iface);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI NoStatStreamImpl_Release(
|
|
|
|
IStream* iface)
|
|
|
|
{
|
2011-03-15 11:35:36 +01:00
|
|
|
NoStatStreamImpl* const This = impl_from_IStream(iface);
|
2005-11-07 12:09:10 +01:00
|
|
|
ULONG newRef = InterlockedDecrement(&This->ref);
|
|
|
|
if (newRef==0)
|
|
|
|
NoStatStreamImpl_Destroy(This);
|
|
|
|
return newRef;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_Read(
|
|
|
|
IStream* iface,
|
|
|
|
void* pv, /* [length_is][size_is][out] */
|
|
|
|
ULONG cb, /* [in] */
|
|
|
|
ULONG* pcbRead) /* [out] */
|
|
|
|
{
|
2011-03-15 11:35:36 +01:00
|
|
|
NoStatStreamImpl* const This = impl_from_IStream(iface);
|
2005-11-07 12:09:10 +01:00
|
|
|
void* supportBuffer;
|
|
|
|
ULONG bytesReadBuffer;
|
|
|
|
ULONG bytesToReadFromBuffer;
|
|
|
|
|
|
|
|
if (pcbRead==0)
|
|
|
|
pcbRead = &bytesReadBuffer;
|
|
|
|
bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
|
|
|
|
supportBuffer = GlobalLock(This->supportHandle);
|
|
|
|
memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
|
|
|
|
This->currentPosition.u.LowPart+=bytesToReadFromBuffer;
|
|
|
|
*pcbRead = bytesToReadFromBuffer;
|
|
|
|
GlobalUnlock(This->supportHandle);
|
|
|
|
if(*pcbRead == cb)
|
|
|
|
return S_OK;
|
|
|
|
return S_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_Write(
|
|
|
|
IStream* iface,
|
|
|
|
const void* pv, /* [size_is][in] */
|
|
|
|
ULONG cb, /* [in] */
|
|
|
|
ULONG* pcbWritten) /* [out] */
|
|
|
|
{
|
2011-03-15 11:35:36 +01:00
|
|
|
NoStatStreamImpl* const This = impl_from_IStream(iface);
|
2005-11-07 12:09:10 +01:00
|
|
|
void* supportBuffer;
|
|
|
|
ULARGE_INTEGER newSize;
|
|
|
|
ULONG bytesWritten = 0;
|
|
|
|
|
|
|
|
if (pcbWritten == 0)
|
|
|
|
pcbWritten = &bytesWritten;
|
|
|
|
if (cb == 0)
|
|
|
|
return S_OK;
|
|
|
|
newSize.u.HighPart = 0;
|
|
|
|
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
|
|
|
|
if (newSize.u.LowPart > This->streamSize.u.LowPart)
|
|
|
|
IStream_SetSize(iface, newSize);
|
|
|
|
|
|
|
|
supportBuffer = GlobalLock(This->supportHandle);
|
|
|
|
memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);
|
|
|
|
This->currentPosition.u.LowPart+=cb;
|
|
|
|
*pcbWritten = cb;
|
|
|
|
GlobalUnlock(This->supportHandle);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_Seek(
|
|
|
|
IStream* iface,
|
|
|
|
LARGE_INTEGER dlibMove, /* [in] */
|
|
|
|
DWORD dwOrigin, /* [in] */
|
|
|
|
ULARGE_INTEGER* plibNewPosition) /* [out] */
|
|
|
|
{
|
2011-03-15 11:35:36 +01:00
|
|
|
NoStatStreamImpl* const This = impl_from_IStream(iface);
|
2005-11-07 12:09:10 +01:00
|
|
|
ULARGE_INTEGER newPosition;
|
|
|
|
switch (dwOrigin)
|
|
|
|
{
|
|
|
|
case STREAM_SEEK_SET:
|
|
|
|
newPosition.u.HighPart = 0;
|
|
|
|
newPosition.u.LowPart = 0;
|
|
|
|
break;
|
|
|
|
case STREAM_SEEK_CUR:
|
|
|
|
newPosition = This->currentPosition;
|
|
|
|
break;
|
|
|
|
case STREAM_SEEK_END:
|
|
|
|
newPosition = This->streamSize;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return STG_E_INVALIDFUNCTION;
|
|
|
|
}
|
|
|
|
if (dlibMove.QuadPart < 0 && newPosition.QuadPart < -dlibMove.QuadPart)
|
|
|
|
return STG_E_INVALIDFUNCTION;
|
|
|
|
newPosition.QuadPart += dlibMove.QuadPart;
|
|
|
|
if (plibNewPosition) *plibNewPosition = newPosition;
|
|
|
|
This->currentPosition = newPosition;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_SetSize(
|
|
|
|
IStream* iface,
|
|
|
|
ULARGE_INTEGER libNewSize) /* [in] */
|
|
|
|
{
|
2011-03-15 11:35:36 +01:00
|
|
|
NoStatStreamImpl* const This = impl_from_IStream(iface);
|
2005-11-07 12:09:10 +01:00
|
|
|
HGLOBAL supportHandle;
|
|
|
|
if (libNewSize.u.HighPart != 0)
|
|
|
|
return STG_E_INVALIDFUNCTION;
|
|
|
|
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
|
|
|
|
return S_OK;
|
|
|
|
supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
|
|
|
|
if (supportHandle == 0)
|
|
|
|
return STG_E_MEDIUMFULL;
|
|
|
|
This->supportHandle = supportHandle;
|
|
|
|
This->streamSize.u.LowPart = libNewSize.u.LowPart;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_CopyTo(
|
|
|
|
IStream* iface,
|
|
|
|
IStream* pstm, /* [unique][in] */
|
|
|
|
ULARGE_INTEGER cb, /* [in] */
|
|
|
|
ULARGE_INTEGER* pcbRead, /* [out] */
|
|
|
|
ULARGE_INTEGER* pcbWritten) /* [out] */
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
BYTE tmpBuffer[128];
|
|
|
|
ULONG bytesRead, bytesWritten, copySize;
|
|
|
|
ULARGE_INTEGER totalBytesRead;
|
|
|
|
ULARGE_INTEGER totalBytesWritten;
|
|
|
|
|
|
|
|
if ( pstm == 0 )
|
|
|
|
return STG_E_INVALIDPOINTER;
|
|
|
|
totalBytesRead.u.LowPart = totalBytesRead.u.HighPart = 0;
|
|
|
|
totalBytesWritten.u.LowPart = totalBytesWritten.u.HighPart = 0;
|
|
|
|
|
|
|
|
while ( cb.u.LowPart > 0 )
|
|
|
|
{
|
|
|
|
if ( cb.u.LowPart >= 128 )
|
|
|
|
copySize = 128;
|
|
|
|
else
|
|
|
|
copySize = cb.u.LowPart;
|
|
|
|
IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
|
|
|
|
totalBytesRead.u.LowPart += bytesRead;
|
|
|
|
IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
|
|
|
|
totalBytesWritten.u.LowPart += bytesWritten;
|
|
|
|
if (bytesRead != bytesWritten)
|
|
|
|
{
|
|
|
|
hr = STG_E_MEDIUMFULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (bytesRead!=copySize)
|
|
|
|
cb.u.LowPart = 0;
|
|
|
|
else
|
|
|
|
cb.u.LowPart -= bytesRead;
|
|
|
|
}
|
|
|
|
if (pcbRead)
|
|
|
|
{
|
|
|
|
pcbRead->u.LowPart = totalBytesRead.u.LowPart;
|
|
|
|
pcbRead->u.HighPart = totalBytesRead.u.HighPart;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pcbWritten)
|
|
|
|
{
|
|
|
|
pcbWritten->u.LowPart = totalBytesWritten.u.LowPart;
|
|
|
|
pcbWritten->u.HighPart = totalBytesWritten.u.HighPart;
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_Commit(IStream* iface,DWORD grfCommitFlags)
|
|
|
|
{
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_Revert(IStream* iface) { return S_OK; }
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_LockRegion(
|
|
|
|
IStream* iface,
|
|
|
|
ULARGE_INTEGER libOffset, /* [in] */
|
|
|
|
ULARGE_INTEGER cb, /* [in] */
|
|
|
|
DWORD dwLockType) /* [in] */
|
|
|
|
{
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_UnlockRegion(
|
|
|
|
IStream* iface,
|
|
|
|
ULARGE_INTEGER libOffset, /* [in] */
|
|
|
|
ULARGE_INTEGER cb, /* [in] */
|
|
|
|
DWORD dwLockType) /* [in] */
|
|
|
|
{
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_Stat(
|
|
|
|
IStream* iface,
|
|
|
|
STATSTG* pstatstg, /* [out] */
|
|
|
|
DWORD grfStatFlag) /* [in] */
|
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI NoStatStreamImpl_Clone(
|
|
|
|
IStream* iface,
|
|
|
|
IStream** ppstm) /* [out] */
|
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
static const IStreamVtbl NoStatStreamImpl_Vtbl;
|
|
|
|
|
2006-12-24 04:02:33 +01:00
|
|
|
/*
|
|
|
|
Build an object that implements IStream, without IStream_Stat capabilities.
|
|
|
|
Receives a memory handle with data buffer. If memory handle is non-null,
|
|
|
|
it is assumed to be unlocked, otherwise an internal memory handle is allocated.
|
|
|
|
In any case the object takes ownership of memory handle and will free it on
|
|
|
|
object release.
|
|
|
|
*/
|
2011-03-15 11:35:36 +01:00
|
|
|
static IStream* NoStatStream_Construct(HGLOBAL hGlobal)
|
2005-11-07 12:09:10 +01:00
|
|
|
{
|
|
|
|
NoStatStreamImpl* newStream;
|
|
|
|
|
|
|
|
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl));
|
|
|
|
if (newStream!=0)
|
|
|
|
{
|
2011-03-15 11:35:36 +01:00
|
|
|
newStream->IStream_iface.lpVtbl = &NoStatStreamImpl_Vtbl;
|
2006-12-24 04:02:33 +01:00
|
|
|
newStream->ref = 1;
|
2005-11-07 12:09:10 +01:00
|
|
|
newStream->supportHandle = hGlobal;
|
|
|
|
|
|
|
|
if (!newStream->supportHandle)
|
|
|
|
newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
|
|
|
|
GMEM_SHARE, 0);
|
|
|
|
newStream->currentPosition.u.HighPart = 0;
|
|
|
|
newStream->currentPosition.u.LowPart = 0;
|
|
|
|
newStream->streamSize.u.HighPart = 0;
|
|
|
|
newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
|
|
|
|
}
|
2011-03-15 11:35:36 +01:00
|
|
|
return &newStream->IStream_iface;
|
2005-11-07 12:09:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const IStreamVtbl NoStatStreamImpl_Vtbl =
|
|
|
|
{
|
|
|
|
NoStatStreamImpl_QueryInterface,
|
|
|
|
NoStatStreamImpl_AddRef,
|
|
|
|
NoStatStreamImpl_Release,
|
|
|
|
NoStatStreamImpl_Read,
|
|
|
|
NoStatStreamImpl_Write,
|
|
|
|
NoStatStreamImpl_Seek,
|
|
|
|
NoStatStreamImpl_SetSize,
|
|
|
|
NoStatStreamImpl_CopyTo,
|
|
|
|
NoStatStreamImpl_Commit,
|
|
|
|
NoStatStreamImpl_Revert,
|
|
|
|
NoStatStreamImpl_LockRegion,
|
|
|
|
NoStatStreamImpl_UnlockRegion,
|
|
|
|
NoStatStreamImpl_Stat,
|
|
|
|
NoStatStreamImpl_Clone
|
|
|
|
};
|