From bc50be98c9c983545966d6c490c129651e0c56d6 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 28 Feb 2014 16:57:19 +0400 Subject: [PATCH] oleaut32: Implement DISPID_PICT_RENDER dispid. --- dlls/oleaut32/olepicture.c | 37 +++++++++- dlls/oleaut32/tests/olepicture.c | 123 ++++++++++++++++++++++++++----- 2 files changed, 142 insertions(+), 18 deletions(-) diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index 2139fde49d7..6e4a737263a 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -1995,6 +1995,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( UINT* puArgErr) { OLEPictureImpl *This = impl_from_IDispatch(iface); + HRESULT hr; /* validate parameters */ @@ -2052,7 +2053,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( else if (wFlags & DISPATCH_PROPERTYPUT) { VARIANTARG vararg; - HRESULT hr; + TRACE("DISPID_PICT_HPAL\n"); VariantInit(&vararg); @@ -2090,6 +2091,40 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( return IPicture_get_Height(&This->IPicture_iface, &V_I4(pVarResult)); } break; + case DISPID_PICT_RENDER: + if (wFlags & DISPATCH_METHOD) + { + VARIANTARG *args = pDispParams->rgvarg; + int i; + + TRACE("DISPID_PICT_RENDER\n"); + + if (pDispParams->cArgs != 10) + return DISP_E_BADPARAMCOUNT; + + /* All parameters are supposed to be VT_I4 (on 64 bits too). */ + for (i = 0; i < pDispParams->cArgs; i++) + if (V_VT(&args[i]) != VT_I4) + { + ERR("DISPID_PICT_RENDER: wrong argument type %d:%d\n", i, V_VT(&args[i])); + return DISP_E_TYPEMISMATCH; + } + + /* FIXME: rectangle pointer argument handling seems broken on 64 bits, + currently Render() doesn't use it at all so for now NULL is passed. */ + return IPicture_Render(&This->IPicture_iface, + LongToHandle(V_I4(&args[9])), + V_I4(&args[8]), + V_I4(&args[7]), + V_I4(&args[6]), + V_I4(&args[5]), + V_I4(&args[4]), + V_I4(&args[3]), + V_I4(&args[2]), + V_I4(&args[1]), + NULL); + } + break; } ERR("invalid dispid 0x%x or wFlags 0x%x\n", dispIdMember, wFlags); diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c index de373221495..26395b932c1 100644 --- a/dlls/oleaut32/tests/olepicture.c +++ b/dlls/oleaut32/tests/olepicture.c @@ -412,12 +412,14 @@ static void test_Invoke(void) { IPictureDisp *picdisp; HRESULT hr; - VARIANTARG vararg; + VARIANTARG vararg, args[10]; DISPPARAMS dispparams; VARIANT varresult; IStream *stream; HGLOBAL hglob; void *data; + HDC hdc; + int i; hglob = GlobalAlloc (0, sizeof(gifimage)); data = GlobalLock(hglob); @@ -477,6 +479,44 @@ static void test_Invoke(void) hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL); ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr); + /* DISPID_PICT_RENDER */ + hdc = GetDC(0); + + for (i = 0; i < sizeof(args)/sizeof(args[0]); i++) + 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); + + ReleaseDC(NULL, hdc); IPictureDisp_Release(picdisp); } @@ -602,6 +642,55 @@ static void test_enhmetafile(void) IStream_Release(stream); } +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 */ + for (i = 0; i < sizeof(args)/sizeof(args[0]); i++) + 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; +} + static void test_Render(void) { IPicture *pic; @@ -619,22 +708,22 @@ static void test_Render(void) 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 */ - hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL); + hres = picture_render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL); + hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL); + hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL); + hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL); + hres = picture_render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL); + hres = picture_render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL); + hres = picture_render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); /* nonzero dimensions, PICTYPE_UNINITIALIZED */ - hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 10, NULL); + hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 10, NULL); ole_expect(hres, S_OK); IPicture_Release(pic); @@ -649,19 +738,19 @@ static void test_Render(void) OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (VOID**)&pic); /* zero dimensions, PICTYPE_ICON */ - hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL); + hres = picture_render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL); + hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL); + hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL); + hres = picture_render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL); + hres = picture_render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL); + hres = picture_render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); - hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL); + hres = picture_render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); /* Check if target size and position is respected */ @@ -673,7 +762,7 @@ static void test_Render(void) SetPixelV(hdc, 10, 10, 0x00223344); expected = GetPixel(hdc, 0, 0); - hres = IPicture_Render(pic, hdc, 1, 1, 9, 9, 0, 0, pWidth, -pHeight, NULL); + hres = picture_render(pic, hdc, 1, 1, 9, 9, 0, 0, pWidth, -pHeight, NULL); ole_expect(hres, S_OK); if(hres != S_OK) {