From: Amine Khaldi Date: Wed, 12 Dec 2012 13:53:12 +0000 (+0000) Subject: [OLEAUT32_WINETEST] X-Git-Tag: backups/ros-csrss@60644~104^2~142 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=fcbfe7f21bf43b5561cc806822808c1596589853 [OLEAUT32_WINETEST] * Sync with Wine 1.5.19. svn path=/trunk/; revision=57890 --- diff --git a/rostests/winetests/oleaut32/olefont.c b/rostests/winetests/oleaut32/olefont.c index 7c0a11221cf..24825540ec1 100644 --- a/rostests/winetests/oleaut32/olefont.c +++ b/rostests/winetests/oleaut32/olefont.c @@ -51,14 +51,14 @@ static HMODULE hOleaut32; static HRESULT (WINAPI *pOleCreateFontIndirect)(LPFONTDESC,REFIID,LPVOID*); -#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) +#define EXPECT_HR(hr,hr_exp) \ + ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp) /* Create a font with cySize given by lo_size, hi_size, */ /* SetRatio to ratio_logical, ratio_himetric, */ /* check that resulting hfont has height hfont_height. */ /* Various checks along the way. */ - -static void test_ifont_sizes(LONG lo_size, LONG hi_size, +static void test_ifont_size(LONG lo_size, LONG hi_size, LONG ratio_logical, LONG ratio_himetric, LONG hfont_height, const char * test_name) { @@ -69,9 +69,10 @@ static void test_ifont_sizes(LONG lo_size, LONG hi_size, LOGFONT lf; CY psize; HRESULT hres; + DWORD rtnval; fd.cbSizeofstruct = sizeof(FONTDESC); - fd.lpstrName = system_font; + fd.lpstrName = arial_font; /* using scalable instead of bitmap font reduces errors due to font realization */ S(fd.cySize).Lo = lo_size; S(fd.cySize).Hi = hi_size; fd.sWeight = 0; @@ -87,32 +88,33 @@ static void test_ifont_sizes(LONG lo_size, LONG hi_size, test_name, hres); ok(pvObj != NULL,"%s: OCFI returns NULL.\n", test_name); - /* Read back size. Hi part was ignored. */ + /* If scaling ration specified, change ratio. */ + if(ratio_logical && ratio_himetric) + { + hres = IFont_SetRatio(ifnt, ratio_logical, ratio_himetric); + ok(hres == S_OK,"%s: IFont_SetRatio returns 0x%08x instead of S_OK.\n", + test_name, hres); + } + + /* Read back size. */ hres = IFont_get_Size(ifnt, &psize); ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n", test_name, hres); - ok(S(psize).Lo == lo_size && S(psize).Hi == 0, - "%s: get_Size: Lo=%d, Hi=%d; expected Lo=%d, Hi=0.\n", - test_name, S(psize).Lo, S(psize).Hi, lo_size); - /* Change ratio, check size unchanged. Standard is 72, 2540. */ - hres = IFont_SetRatio(ifnt, ratio_logical, ratio_himetric); - ok(hres == S_OK,"%s: IFont_SR returns 0x%08x instead of S_OK.\n", - test_name, hres); - hres = IFont_get_Size(ifnt, &psize); - ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n", - test_name, hres); - ok(S(psize).Lo == lo_size && S(psize).Hi == 0, - "%s: gS after SR: Lo=%d, Hi=%d; expected Lo=%d, Hi=0.\n", - test_name, S(psize).Lo, S(psize).Hi, lo_size); + /* Check returned size - allow for errors due to rounding & font realization. */ + ok((abs(S(psize).Lo - lo_size) < 10000) && S(psize).Hi == hi_size, + "%s: IFont_get_Size: Lo=%d, Hi=%d; expected Lo=%d, Hi=%d.\n", + test_name, S(psize).Lo, S(psize).Hi, lo_size, hi_size); - /* Check hFont size with this ratio. This tests an important */ - /* conversion for which MSDN is very wrong. */ + /* Check hFont size. */ hres = IFont_get_hFont (ifnt, &hfont); ok(hres == S_OK, "%s: IFont_get_hFont returns 0x%08x instead of S_OK.\n", test_name, hres); - hres = GetObject (hfont, sizeof(LOGFONT), &lf); - ok(lf.lfHeight == hfont_height, + rtnval = GetObject (hfont, sizeof(LOGFONT), &lf); + ok(rtnval > 0, "GetObject(hfont) failed\n"); + + /* Since font scaling may encounter rounding errors, allow 1 pixel deviation. */ + ok(abs(lf.lfHeight - hfont_height) <= 1, "%s: hFont has lf.lfHeight=%d, expected %d.\n", test_name, lf.lfHeight, hfont_height); @@ -120,35 +122,68 @@ static void test_ifont_sizes(LONG lo_size, LONG hi_size, IFont_Release(ifnt); } +static void test_ifont_sizes(void) +{ + /* Test various size operations and conversions. */ + /* Add more as needed. */ + + /* Results of first 2 tests depend on display resolution. */ + HDC hdc = GetDC(0); + LONG dpi = GetDeviceCaps(hdc, LOGPIXELSY); /* expected results depend on display DPI */ + ReleaseDC(0, hdc); + if(dpi == 96) /* normal resolution display */ + { + test_ifont_size(180000, 0, 0, 0, -24, "default"); /* normal font */ + test_ifont_size(186000, 0, 0, 0, -25, "rounding"); /* test rounding */ + } else if(dpi == 72) /* low resolution display */ + { + test_ifont_size(180000, 0, 0, 0, -18, "default"); /* normal font */ + test_ifont_size(186000, 0, 0, 0, -19, "rounding"); /* test rounding */ + } else if(dpi == 120) /* high resolution display */ + { + test_ifont_size(180000, 0, 0, 0, -30, "default"); /* normal font */ + test_ifont_size(186000, 0, 0, 0, -31, "rounding"); /* test rounding */ + } else + skip("Skipping resolution dependent font size tests - display resolution is %d\n", dpi); + + /* Next 4 tests specify a scaling ratio, so display resolution is not a factor. */ + test_ifont_size(180000, 0, 72, 2540, -18, "ratio1"); /* change ratio */ + test_ifont_size(180000, 0, 144, 2540, -36, "ratio2"); /* another ratio */ + test_ifont_size(180000, 0, 72, 1270, -36, "ratio3"); /* yet another ratio */ + test_ifont_size(186000, 0, 72, 2540, -19, "rounding+ratio"); /* test rounding with ratio */ +} + static void test_QueryInterface(void) { - LPVOID pvObj = NULL; - HRESULT hres; - IFont* font = NULL; - LONG ret; + LPVOID pvObj = NULL; + HRESULT hr; + IFont* font = NULL; + LONG ref; + + hr = pOleCreateFontIndirect(NULL, &IID_IFont, NULL); + EXPECT_HR(hr, E_POINTER); - hres = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj); - font = pvObj; + hr = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj); + font = pvObj; - ok(hres == S_OK,"OCFI (NULL,..) does not return 0, but 0x%08x\n",hres); - ok(font != NULL,"OCFI (NULL,..) returns NULL, instead of !NULL\n"); + EXPECT_HR(hr, S_OK); + ok(font != NULL,"OCFI (NULL,..) returns NULL, instead of !NULL\n"); - pvObj = NULL; - hres = IFont_QueryInterface( font, &IID_IFont, &pvObj); + pvObj = NULL; + hr = IFont_QueryInterface( font, &IID_IFont, &pvObj); + EXPECT_HR(hr, S_OK); - /* Test if QueryInterface increments ref counter for IFONTs */ - ret = IFont_AddRef(font); - ok(ret == 3 || - broken(ret == 1), /* win95 */ - "IFont_QI expected ref value 3 but instead got %d\n",ret); - IFont_Release(font); + /* Test if QueryInterface increments ref counter for IFONTs */ + ref = IFont_AddRef(font); + ok(ref == 3 || + broken(ref == 1), /* win95 */ + "IFont_QI expected ref value 3 but instead got %d\n", ref); + IFont_Release(font); - ok(hres == S_OK,"IFont_QI does not return S_OK, but 0x%08x\n", hres); - ok(pvObj != NULL,"IFont_QI does return NULL, instead of a ptr\n"); + ok(pvObj != NULL,"IFont_QI does return NULL, instead of a ptr\n"); - /* Original ref and QueryInterface ref both have to be released */ - IFont_Release(font); - IFont_Release(font); + IFont_Release(font); + IFont_Release(font); } static void test_type_info(void) @@ -201,7 +236,7 @@ static HRESULT WINAPI FontEventsDisp_QueryInterface( { if (IsEqualIID(riid, &IID_IFontEventsDisp) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch)) { - IUnknown_AddRef(iface); + IFontEventsDisp_AddRef(iface); *ppvObject = iface; return S_OK; } @@ -284,26 +319,26 @@ static void test_font_events_disp(void) fontdesc.fStrikethrough = FALSE; hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont); - ok_ole_success(hr, "OleCreateFontIndirect"); + EXPECT_HR(hr, S_OK); hr = IFont_QueryInterface(pFont, &IID_IConnectionPointContainer, (void **)&pCPC); - ok_ole_success(hr, "IFont_QueryInterface"); + EXPECT_HR(hr, S_OK); hr = IConnectionPointContainer_FindConnectionPoint(pCPC, &IID_IFontEventsDisp, &pCP); - ok_ole_success(hr, "IConnectionPointContainer_FindConnectionPoint"); + EXPECT_HR(hr, S_OK); IConnectionPointContainer_Release(pCPC); hr = IConnectionPoint_Advise(pCP, (IUnknown *)&FontEventsDisp, &dwCookie); - ok_ole_success(hr, "IConnectionPoint_Advise"); + EXPECT_HR(hr, S_OK); IConnectionPoint_Release(pCP); hr = IFont_put_Bold(pFont, TRUE); - ok_ole_success(hr, "IFont_put_Bold"); + EXPECT_HR(hr, S_OK); ok(fonteventsdisp_invoke_called == 1, "IFontEventDisp::Invoke wasn't called once\n"); hr = IFont_QueryInterface(pFont, &IID_IFontDisp, (void **)&pFontDisp); - ok_ole_success(hr, "IFont_QueryInterface"); + EXPECT_HR(hr, S_OK); V_VT(&vararg) = VT_BOOL; V_BOOL(&vararg) = VARIANT_FALSE; @@ -312,6 +347,7 @@ static void test_font_events_disp(void) dispparams.cArgs = 1; dispparams.rgvarg = &vararg; hr = IFontDisp_Invoke(pFontDisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL); + EXPECT_HR(hr, S_OK); IFontDisp_Release(pFontDisp); @@ -319,11 +355,11 @@ static void test_font_events_disp(void) fonteventsdisp_invoke_called); hr = IFont_Clone(pFont, &pFont2); - ok_ole_success(hr, "IFont_Clone"); + EXPECT_HR(hr, S_OK); IFont_Release(pFont); hr = IFont_put_Bold(pFont2, FALSE); - ok_ole_success(hr, "IFont_put_Bold"); + EXPECT_HR(hr, S_OK); /* this test shows that the notification routine isn't called again */ ok(fonteventsdisp_invoke_called == 2, "IFontEventDisp::Invoke was called %d times instead of twice\n", @@ -450,7 +486,7 @@ static void test_Invoke(void) VARIANT varresult; hr = pOleCreateFontIndirect(NULL, &IID_IFontDisp, (void **)&fontdisp); - ok_ole_success(hr, "OleCreateFontIndirect"); + EXPECT_HR(hr, S_OK); V_VT(&vararg) = VT_BOOL; V_BOOL(&vararg) = VARIANT_FALSE; @@ -459,32 +495,32 @@ static void test_Invoke(void) dispparams.cArgs = 1; dispparams.rgvarg = &vararg; hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_IFontDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL); - ok(hr == DISP_E_UNKNOWNINTERFACE, "IFontDisp_Invoke should have returned DISP_E_UNKNOWNINTERFACE instead of 0x%08x\n", hr); + EXPECT_HR(hr, DISP_E_UNKNOWNINTERFACE); dispparams.cArgs = 0; dispparams.rgvarg = NULL; hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL); - ok(hr == DISP_E_BADPARAMCOUNT, "IFontDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr); + EXPECT_HR(hr, DISP_E_BADPARAMCOUNT); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL); - ok(hr == DISP_E_PARAMNOTOPTIONAL, "IFontDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr); + EXPECT_HR(hr, DISP_E_PARAMNOTOPTIONAL); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL); - ok(hr == DISP_E_PARAMNOTOPTIONAL, "IFontDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr); + EXPECT_HR(hr, DISP_E_PARAMNOTOPTIONAL); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL); - ok_ole_success(hr, "IFontDisp_Invoke"); + EXPECT_HR(hr, S_OK); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_METHOD, NULL, &varresult, NULL, NULL); - ok(hr == DISP_E_MEMBERNOTFOUND, "IFontDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr); + EXPECT_HR(hr, DISP_E_MEMBERNOTFOUND); hr = IFontDisp_Invoke(fontdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL); - ok(hr == DISP_E_MEMBERNOTFOUND, "IFontDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr); + EXPECT_HR(hr, DISP_E_MEMBERNOTFOUND); dispparams.cArgs = 1; dispparams.rgvarg = &vararg; hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL); - ok_ole_success(hr, "IFontDisp_Invoke"); + EXPECT_HR(hr, S_OK); IFontDisp_Release(fontdisp); } @@ -812,27 +848,19 @@ static void test_returns(void) fontdesc.fStrikethrough = FALSE; hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont); - ok_ole_success(hr, "OleCreateFontIndirect"); + EXPECT_HR(hr, S_OK); hr = IFont_put_Name(pFont, NULL); - ok(hr == CTL_E_INVALIDPROPERTYVALUE, - "IFont::put_Name: Expected CTL_E_INVALIDPROPERTYVALUE got 0x%08x\n", - hr); + EXPECT_HR(hr, CTL_E_INVALIDPROPERTYVALUE); hr = IFont_get_Name(pFont, NULL); - ok(hr == E_POINTER, - "IFont::get_Name: Expected E_POINTER got 0x%08x\n", - hr); + EXPECT_HR(hr, E_POINTER); hr = IFont_get_Size(pFont, NULL); - ok(hr == E_POINTER, - "IFont::get_Size: Expected E_POINTER got 0x%08x\n", - hr); + EXPECT_HR(hr, E_POINTER); hr = IFont_get_Bold(pFont, NULL); - ok(hr == E_POINTER, - "IFont::get_Bold: Expected E_POINTER got 0x%08x\n", - hr); + EXPECT_HR(hr, E_POINTER); IFont_Release(pFont); } @@ -857,10 +885,10 @@ static void test_hfont_lifetime(void) fontdesc.fStrikethrough = FALSE; hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font); - ok_ole_success(hr, "OleCreateFontIndirect"); + EXPECT_HR(hr, S_OK); hr = IFont_get_hFont(font, &hfont); - ok_ole_success(hr, "get_hFont"); + EXPECT_HR(hr, S_OK); /* show that if the font is updated the old hfont is deleted when the new font is realized */ @@ -874,14 +902,14 @@ static void test_hfont_lifetime(void) ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); hr = IFont_put_Size(font, size); - ok_ole_success(hr, "put_Size"); + EXPECT_HR(hr, S_OK); /* put_Size doesn't cause the new font to be realized */ obj_type = GetObjectType(last_hfont); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); hr = IFont_get_hFont(font, &hfont); - ok_ole_success(hr, "get_hFont"); + EXPECT_HR(hr, S_OK); obj_type = GetObjectType(last_hfont); ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type); @@ -891,20 +919,19 @@ static void test_hfont_lifetime(void) until the font object is released */ for(i = 0; i < 100; i++) { - size.int64 = (i + 10) * 20000; obj_type = GetObjectType(hfont); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); hr = IFont_put_Size(font, size); - ok_ole_success(hr, "put_Size"); + EXPECT_HR(hr, S_OK); hr = IFont_get_hFont(font, &hfont); - ok_ole_success(hr, "get_hFont"); + EXPECT_HR(hr, S_OK); hr = IFont_AddRefHfont(font, hfont); - ok_ole_success(hr, "AddRefHfont"); + EXPECT_HR(hr, S_OK); if(i == 0) first_hfont = hfont; obj_type = GetObjectType(first_hfont); @@ -920,10 +947,10 @@ static void test_hfont_lifetime(void) through re-realization */ hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font); - ok_ole_success(hr, "OleCreateFontIndirect"); + EXPECT_HR(hr, S_OK); hr = IFont_get_hFont(font, &hfont); - ok_ole_success(hr, "get_hFont"); + EXPECT_HR(hr, S_OK); for(i = 0; i < 100; i++) { @@ -935,20 +962,20 @@ static void test_hfont_lifetime(void) ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); hr = IFont_put_Size(font, size); - ok_ole_success(hr, "put_Size"); + EXPECT_HR(hr, S_OK); /* put_Size doesn't cause the new font to be realized */ obj_type = GetObjectType(last_hfont); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); hr = IFont_get_hFont(font, &hfont); - ok_ole_success(hr, "get_hFont"); + EXPECT_HR(hr, S_OK); hr = IFont_AddRefHfont(font, hfont); - ok_ole_success(hr, "AddRefHfont"); + EXPECT_HR(hr, S_OK); hr = IFont_ReleaseHfont(font, hfont); - ok_ole_success(hr, "ReleaseHfont"); + EXPECT_HR(hr, S_OK); obj_type = GetObjectType(last_hfont); ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type); @@ -965,13 +992,13 @@ static void test_hfont_lifetime(void) ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); hr = IFont_put_Size(font, size); - ok_ole_success(hr, "put_Size"); + EXPECT_HR(hr, S_OK); hr = IFont_get_hFont(font, &hfont); - ok_ole_success(hr, "get_hFont"); + EXPECT_HR(hr, S_OK); hr = IFont_ReleaseHfont(font, hfont); - ok_ole_success(hr, "ReleaseHfont"); + EXPECT_HR(hr, S_OK); if(i == 0) first_hfont = hfont; obj_type = GetObjectType(first_hfont); @@ -988,23 +1015,23 @@ static void test_hfont_lifetime(void) that includes internal and external references */ hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font); - ok_ole_success(hr, "OleCreateFontIndirect"); + EXPECT_HR(hr, S_OK); hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font2); - ok_ole_success(hr, "OleCreateFontIndirect"); + EXPECT_HR(hr, S_OK); hr = IFont_get_hFont(font, &hfont); - ok_ole_success(hr, "get_hFont"); + EXPECT_HR(hr, S_OK); hr = IFont_get_hFont(font2, &first_hfont); - ok_ole_success(hr, "get_hFont"); + EXPECT_HR(hr, S_OK); todo_wine ok(hfont == first_hfont, "fonts differ\n"); hr = IFont_ReleaseHfont(font, hfont); - ok(hr == S_OK, "got %08x\n", hr); + EXPECT_HR(hr, S_OK); hr = IFont_ReleaseHfont(font, hfont); todo_wine - ok(hr == S_OK, "got %08x\n", hr); + EXPECT_HR(hr, S_OK); hr = IFont_ReleaseHfont(font, hfont); - ok(hr == S_FALSE, "got %08x\n", hr); + EXPECT_HR(hr, S_FALSE); obj_type = GetObjectType(hfont); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); @@ -1041,10 +1068,10 @@ static void test_realization(void) fontdesc.fStrikethrough = FALSE; hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font); - ok_ole_success(hr, "OleCreateFontIndirect"); + EXPECT_HR(hr, S_OK); hr = IFont_get_Charset(font, &cs); - ok_ole_success(hr, "get_Charset"); + EXPECT_HR(hr, S_OK); ok(cs == ANSI_CHARSET, "got charset %d\n", cs); IFont_Release(font); @@ -1054,62 +1081,86 @@ static void test_realization(void) fontdesc.lpstrName = arial_font; hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font); - ok_ole_success(hr, "OleCreateFontIndirect"); + EXPECT_HR(hr, S_OK); hr = IFont_get_Charset(font, &cs); - ok_ole_success(hr, "get_Charset"); + EXPECT_HR(hr, S_OK); ok(cs == ANSI_CHARSET, "got charset %d\n", cs); name = SysAllocString(marlett_font); hr = IFont_put_Name(font, name); - ok_ole_success(hr, "put_Name"); + EXPECT_HR(hr, S_OK); SysFreeString(name); hr = IFont_get_Name(font, &name); - ok_ole_success(hr, "get_Name"); + EXPECT_HR(hr, S_OK); ok(!lstrcmpiW(name, marlett_font), "got name %s\n", wine_dbgstr_w(name)); SysFreeString(name); hr = IFont_get_Charset(font, &cs); - ok_ole_success(hr, "get_Charset"); + EXPECT_HR(hr, S_OK); ok(cs == SYMBOL_CHARSET, "got charset %d\n", cs); IFont_Release(font); } +static void test_OleCreateFontIndirect(void) +{ + FONTDESC fontdesc; + IFont *font; + HRESULT hr; + + fontdesc.cbSizeofstruct = sizeof(fontdesc); + fontdesc.lpstrName = arial_font; + fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */ + fontdesc.sWeight = FW_NORMAL; + fontdesc.sCharset = ANSI_CHARSET; + fontdesc.fItalic = FALSE; + fontdesc.fUnderline = FALSE; + fontdesc.fStrikethrough = FALSE; + + hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font); + EXPECT_HR(hr, S_OK); + IFont_Release(font); + + /* play with cbSizeofstruct value */ + fontdesc.cbSizeofstruct = sizeof(fontdesc)-1; + hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font); + EXPECT_HR(hr, S_OK); + IFont_Release(font); + + fontdesc.cbSizeofstruct = sizeof(fontdesc)+1; + hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font); + EXPECT_HR(hr, S_OK); + IFont_Release(font); + + fontdesc.cbSizeofstruct = 0; + hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font); + EXPECT_HR(hr, S_OK); + IFont_Release(font); +} + START_TEST(olefont) { - hOleaut32 = GetModuleHandleA("oleaut32.dll"); - pOleCreateFontIndirect = (void*)GetProcAddress(hOleaut32, "OleCreateFontIndirect"); - if (!pOleCreateFontIndirect) - { - win_skip("OleCreateFontIndirect not available\n"); - return; - } - - test_QueryInterface(); - test_type_info(); - - /* Test various size operations and conversions. */ - /* Add more as needed. */ - if (0) /* FIXME: failing tests */ - { - test_ifont_sizes(180000, 0, 72, 2540, -18, "default"); - test_ifont_sizes(180000, 0, 144, 2540, -36, "ratio1"); /* change ratio */ - test_ifont_sizes(180000, 0, 72, 1270, -36, "ratio2"); /* 2nd part of ratio */ - - /* These depend on details of how IFont rounds sizes internally. */ - test_ifont_sizes(0, 0, 72, 2540, 0, "zero size"); /* zero size */ - test_ifont_sizes(186000, 0, 72, 2540, -19, "rounding"); /* test rounding */ - } - - test_font_events_disp(); - test_GetIDsOfNames(); - test_Invoke(); - test_IsEqual(); - test_ReleaseHfont(); - test_AddRefHfont(); - test_returns(); - test_hfont_lifetime(); - test_realization(); + hOleaut32 = GetModuleHandleA("oleaut32.dll"); + pOleCreateFontIndirect = (void*)GetProcAddress(hOleaut32, "OleCreateFontIndirect"); + if (!pOleCreateFontIndirect) + { + win_skip("OleCreateFontIndirect not available\n"); + return; + } + + test_QueryInterface(); + test_type_info(); + test_ifont_sizes(); + test_font_events_disp(); + test_GetIDsOfNames(); + test_Invoke(); + test_IsEqual(); + test_ReleaseHfont(); + test_AddRefHfont(); + test_returns(); + test_hfont_lifetime(); + test_realization(); + test_OleCreateFontIndirect(); } diff --git a/rostests/winetests/oleaut32/olepicture.c b/rostests/winetests/oleaut32/olepicture.c index 9ed87008544..3f64c67e3fd 100644 --- a/rostests/winetests/oleaut32/olepicture.c +++ b/rostests/winetests/oleaut32/olepicture.c @@ -2,7 +2,7 @@ * OLEPICTURE test program * * Copyright 2005 Marcus Meissner - * + * Copyright 2012 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,6 +25,7 @@ #include #define COBJMACROS +#define CONST_VTABLE #define NONAMELESSUNION #include "wine/test.h" @@ -53,7 +54,7 @@ static HMODULE hOleaut32; static HRESULT (WINAPI *pOleLoadPicture)(LPSTREAM,LONG,BOOL,REFIID,LPVOID*); -static HRESULT (WINAPI *pOleCreatePictureIndirect)(PICTDESC*,REFIID,BOOL,LPVOID*); +static HRESULT (WINAPI *pOleLoadPictureEx)(LPSTREAM,LONG,BOOL,REFIID,DWORD,DWORD,DWORD,LPVOID*); #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) @@ -169,17 +170,17 @@ static const unsigned char enhmetafile[] = { }; -struct NoStatStreamImpl +typedef struct NoStatStreamImpl { - const IStreamVtbl *lpVtbl; + IStream IStream_iface; LONG ref; HGLOBAL supportHandle; ULARGE_INTEGER streamSize; ULARGE_INTEGER currentPosition; -}; -typedef struct NoStatStreamImpl NoStatStreamImpl; -static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal); +} NoStatStreamImpl; + +static IStream* NoStatStream_Construct(HGLOBAL hGlobal); static void test_pic_with_stream(LPSTREAM stream, unsigned int imgsize) @@ -219,7 +220,7 @@ test_pic_with_stream(LPSTREAM stream, unsigned int imgsize) if (handle) { BITMAP bmp; - GetObject((HGDIOBJ)handle, sizeof(BITMAP), &bmp); + GetObject(UlongToHandle(handle), sizeof(BITMAP), &bmp); todo_wine ok(bmp.bmBits != 0, "not a dib\n"); } @@ -282,7 +283,7 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize) IStream_Release(stream); /* again with Non Statable and Non Seekable stream */ - stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob); + stream = NoStatStream_Construct(hglob); hglob = 0; /* Non-statable impl always deletes on release */ test_pic_with_stream(stream, 0); @@ -313,7 +314,7 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize) IStream_Release(stream); /* again with Non Statable and Non Seekable stream */ - stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob); + stream = NoStatStream_Construct(hglob); hglob = 0; /* Non-statable impl always deletes on release */ test_pic_with_stream(stream, 0); @@ -481,24 +482,26 @@ static void test_Invoke(void) static void test_OleCreatePictureIndirect(void) { + OLE_HANDLE handle; IPicture *pict; HRESULT hr; short type; - OLE_HANDLE handle; - if(!pOleCreatePictureIndirect) - { - win_skip("Skipping OleCreatePictureIndirect tests\n"); - return; - } +if (0) +{ + /* crashes on native */ + OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, NULL); +} - hr = pOleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void**)&pict); + hr = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void**)&pict); ok(hr == S_OK, "hr %08x\n", hr); + type = PICTYPE_NONE; hr = IPicture_get_Type(pict, &type); ok(hr == S_OK, "hr %08x\n", hr); ok(type == PICTYPE_UNINITIALIZED, "type %d\n", type); + handle = 0xdeadbeef; hr = IPicture_get_Handle(pict, &handle); ok(hr == S_OK, "hr %08x\n", hr); ok(handle == 0, "handle %08x\n", handle); @@ -518,7 +521,7 @@ static void test_apm(void) short type; if(!winetest_interactive) { - skip("Bug 5000: oleaut_winetest:olepicture crashes with Page Fault.\n"); + skip("ROSTESTS-2: oleaut_winetest:olepicture crashes with Page Fault.\n"); return; } @@ -527,7 +530,7 @@ static void test_apm(void) memcpy(data, apmdata, sizeof(apmdata)); ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream)); - ole_check(OleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict)); + ole_check(pOleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict)); ole_check(IPicture_get_Handle(pict, &handle)); ok(handle != 0, "handle is null\n"); @@ -562,7 +565,7 @@ static void test_metafile(void) ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream)); /* Windows does not load simple metafiles */ - ole_expect(OleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL); + ole_expect(pOleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL); IStream_Release(stream); } @@ -579,7 +582,7 @@ static void test_enhmetafile(void) short type; if(!winetest_interactive) { - skip("Bug 5000: oleaut_winetest:olepicture crashes with Page Fault.\n"); + skip("ROSTESTS-2: oleaut_winetest:olepicture crashes with Page Fault.\n"); return; } @@ -588,7 +591,7 @@ static void test_enhmetafile(void) memcpy(data, enhmetafile, sizeof(enhmetafile)); ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream)); - ole_check(OleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict)); + ole_check(pOleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict)); ole_check(IPicture_get_Handle(pict, &handle)); ok(handle != 0, "handle is null\n"); @@ -675,9 +678,9 @@ static void test_Render(void) IPicture_get_Width(pic, &pWidth); IPicture_get_Height(pic, &pHeight); - SetPixelV(hdc, 0, 0, 0x00F0F0F0); - SetPixelV(hdc, 5, 5, 0x00F0F0F0); - SetPixelV(hdc, 10, 10, 0x00F0F0F0); + SetPixelV(hdc, 0, 0, 0x00223344); + SetPixelV(hdc, 5, 5, 0x00223344); + SetPixelV(hdc, 10, 10, 0x00223344); expected = GetPixel(hdc, 0, 0); hres = IPicture_Render(pic, hdc, 1, 1, 9, 9, 0, 0, pWidth, -pHeight, NULL); @@ -800,9 +803,8 @@ static void test_OleLoadPicturePath(void) hres = OleLoadPicturePath(emptyW, NULL, 0, 0, NULL, (void **)&pic); todo_wine ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */ - hres == E_UNEXPECTED || /* NT4/Win95 */ - hres == E_FAIL || /* Win95 OSR2 */ - hres == E_OUTOFMEMORY, /* Win98/Win2k/Win2k3 */ + broken(hres == E_UNEXPECTED) || /* NT4 */ + broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */ "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); @@ -811,9 +813,8 @@ static void test_OleLoadPicturePath(void) hres = OleLoadPicturePath(emptyW, NULL, 0, 0, &IID_IPicture, (void **)&pic); todo_wine ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */ - hres == E_UNEXPECTED || /* NT4/Win95 */ - hres == E_FAIL || /* Win95 OSR2 */ - hres == E_OUTOFMEMORY, /* Win98/Win2k/Win2k3 */ + broken(hres == E_UNEXPECTED) || /* NT4 */ + broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */ "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); @@ -831,7 +832,7 @@ static void test_OleLoadPicturePath(void) /* Try a normal DOS path. */ hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == S_OK || - broken(hres == E_UNEXPECTED), /* NT4/Win95 */ + broken(hres == E_UNEXPECTED), /* NT4 */ "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres); if (pic) IPicture_Release(pic); @@ -839,7 +840,7 @@ static void test_OleLoadPicturePath(void) /* Try a DOS path with tacked on "file:". */ hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == S_OK || - broken(hres == E_UNEXPECTED), /* NT4/Win95 */ + broken(hres == E_UNEXPECTED), /* NT4 */ "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres); if (pic) IPicture_Release(pic); @@ -849,14 +850,14 @@ static void test_OleLoadPicturePath(void) /* Try with a nonexistent file. */ hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */ - hres == E_UNEXPECTED || /* NT4/Win95 */ - hres == E_FAIL, /* Win9x/Win2k */ + broken(hres == E_UNEXPECTED) || /* NT4 */ + broken(hres == E_FAIL), /*Win2k */ "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); ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */ - hres == E_UNEXPECTED || /* NT4/Win95 */ - hres == E_FAIL, /* Win9x/Win2k */ + broken(hres == E_UNEXPECTED) || /* NT4 */ + broken(hres == E_FAIL), /* Win2k */ "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, @@ -875,7 +876,7 @@ static void test_OleLoadPicturePath(void) hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == S_OK || - broken(hres == E_UNEXPECTED), /* NT4/Win95 */ + broken(hres == E_UNEXPECTED), /* NT4 */ "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres); if (pic) IPicture_Release(pic); @@ -885,35 +886,267 @@ static void test_OleLoadPicturePath(void) /* Try with a nonexistent file. */ hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */ - hres == E_UNEXPECTED || /* NT4/Win95 */ - hres == E_FAIL, /* Win9x/Win2k */ + broken(hres == E_UNEXPECTED) || /* NT4 */ + broken(hres == E_FAIL), /* Win2k */ "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); } +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 */ + hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic); + 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; + + hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic); + 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); +} + +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; + HRESULT hr; + + 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); + ok(IntToPtr(handle) == desc.u.bmp.hbitmap, "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); + + 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); +} + +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; + HRESULT hr; + + desc.cbSizeofstruct = sizeof(desc); + desc.picType = PICTYPE_ICON; + desc.u.icon.hicon = LoadIcon(0, IDI_APPLICATION); + 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); + + 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); + + DestroyIcon(desc.u.icon.hicon); + IPicture_Release(pic); +} + +static void test_load_save_empty_picture(void) +{ + IPicture *pic; + PICTDESC desc; + short type; + OLE_HANDLE handle; + HGLOBAL hmem; + DWORD *mem; + IPersistStream *src_stream; + IStream *dst_stream; + HRESULT hr; + + 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); + 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); + + hmem = GlobalAlloc(GMEM_ZEROINIT, 4096); + hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream); + ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr); + + 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); + IStream_Release(dst_stream); + + GlobalFree(hmem); + IPicture_Release(pic); +} + START_TEST(olepicture) { - hOleaut32 = GetModuleHandleA("oleaut32.dll"); - pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture"); - pOleCreatePictureIndirect = (void*)GetProcAddress(hOleaut32, "OleCreatePictureIndirect"); - if (!pOleLoadPicture) - { - win_skip("OleLoadPicture is not available\n"); - return; - } + hOleaut32 = GetModuleHandleA("oleaut32.dll"); + pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture"); + pOleLoadPictureEx = (void*)GetProcAddress(hOleaut32, "OleLoadPictureEx"); + if (!pOleLoadPicture) + { + win_skip("OleLoadPicture is not available\n"); + return; + } - /* 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(); + /* 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(); + if (pOleLoadPictureEx) + { test_apm(); test_metafile(); test_enhmetafile(); - + } + else + win_skip("OleLoadPictureEx is not available\n"); test_Invoke(); test_OleCreatePictureIndirect(); test_Render(); @@ -921,12 +1154,21 @@ START_TEST(olepicture) test_get_Handle(); test_get_Type(); test_OleLoadPicturePath(); + test_himetric(); + test_load_save_bmp(); + test_load_save_icon(); + test_load_save_empty_picture(); } /* Helper functions only ... */ +static inline NoStatStreamImpl *impl_from_IStream(IStream *iface) +{ + return CONTAINING_RECORD(iface, NoStatStreamImpl, IStream_iface); +} + static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This) { GlobalFree(This->supportHandle); @@ -937,7 +1179,7 @@ static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This) static ULONG WINAPI NoStatStreamImpl_AddRef( IStream* iface) { - NoStatStreamImpl* const This=(NoStatStreamImpl*)iface; + NoStatStreamImpl* const This = impl_from_IStream(iface); return InterlockedIncrement(&This->ref); } @@ -946,7 +1188,7 @@ static HRESULT WINAPI NoStatStreamImpl_QueryInterface( REFIID riid, /* [in] */ void** ppvObject) /* [iid_is][out] */ { - NoStatStreamImpl* const This=(NoStatStreamImpl*)iface; + NoStatStreamImpl* const This = impl_from_IStream(iface); if (ppvObject==0) return E_INVALIDARG; *ppvObject = 0; if (IsEqualIID(&IID_IUnknown, riid)) @@ -967,7 +1209,7 @@ static HRESULT WINAPI NoStatStreamImpl_QueryInterface( static ULONG WINAPI NoStatStreamImpl_Release( IStream* iface) { - NoStatStreamImpl* const This=(NoStatStreamImpl*)iface; + NoStatStreamImpl* const This = impl_from_IStream(iface); ULONG newRef = InterlockedDecrement(&This->ref); if (newRef==0) NoStatStreamImpl_Destroy(This); @@ -980,7 +1222,7 @@ static HRESULT WINAPI NoStatStreamImpl_Read( ULONG cb, /* [in] */ ULONG* pcbRead) /* [out] */ { - NoStatStreamImpl* const This=(NoStatStreamImpl*)iface; + NoStatStreamImpl* const This = impl_from_IStream(iface); void* supportBuffer; ULONG bytesReadBuffer; ULONG bytesToReadFromBuffer; @@ -1004,7 +1246,7 @@ static HRESULT WINAPI NoStatStreamImpl_Write( ULONG cb, /* [in] */ ULONG* pcbWritten) /* [out] */ { - NoStatStreamImpl* const This=(NoStatStreamImpl*)iface; + NoStatStreamImpl* const This = impl_from_IStream(iface); void* supportBuffer; ULARGE_INTEGER newSize; ULONG bytesWritten = 0; @@ -1032,7 +1274,7 @@ static HRESULT WINAPI NoStatStreamImpl_Seek( DWORD dwOrigin, /* [in] */ ULARGE_INTEGER* plibNewPosition) /* [out] */ { - NoStatStreamImpl* const This=(NoStatStreamImpl*)iface; + NoStatStreamImpl* const This = impl_from_IStream(iface); ULARGE_INTEGER newPosition; switch (dwOrigin) { @@ -1061,7 +1303,7 @@ static HRESULT WINAPI NoStatStreamImpl_SetSize( IStream* iface, ULARGE_INTEGER libNewSize) /* [in] */ { - NoStatStreamImpl* const This=(NoStatStreamImpl*)iface; + NoStatStreamImpl* const This = impl_from_IStream(iface); HGLOBAL supportHandle; if (libNewSize.u.HighPart != 0) return STG_E_INVALIDFUNCTION; @@ -1174,14 +1416,14 @@ static const IStreamVtbl NoStatStreamImpl_Vtbl; In any case the object takes ownership of memory handle and will free it on object release. */ -static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal) +static IStream* NoStatStream_Construct(HGLOBAL hGlobal) { NoStatStreamImpl* newStream; newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl)); if (newStream!=0) { - newStream->lpVtbl = &NoStatStreamImpl_Vtbl; + newStream->IStream_iface.lpVtbl = &NoStatStreamImpl_Vtbl; newStream->ref = 1; newStream->supportHandle = hGlobal; @@ -1193,7 +1435,7 @@ static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal) newStream->streamSize.u.HighPart = 0; newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle); } - return newStream; + return &newStream->IStream_iface; }