* Back out r57890 in favor of a complete upcoming sync.

svn path=/trunk/; revision=57891
This commit is contained in:
Amine Khaldi 2012-12-12 13:55:29 +00:00
parent fcbfe7f21b
commit 7e47495621
2 changed files with 205 additions and 498 deletions

View file

@ -51,14 +51,14 @@ static HMODULE hOleaut32;
static HRESULT (WINAPI *pOleCreateFontIndirect)(LPFONTDESC,REFIID,LPVOID*); static HRESULT (WINAPI *pOleCreateFontIndirect)(LPFONTDESC,REFIID,LPVOID*);
#define EXPECT_HR(hr,hr_exp) \ #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
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, */ /* Create a font with cySize given by lo_size, hi_size, */
/* SetRatio to ratio_logical, ratio_himetric, */ /* SetRatio to ratio_logical, ratio_himetric, */
/* check that resulting hfont has height hfont_height. */ /* check that resulting hfont has height hfont_height. */
/* Various checks along the way. */ /* Various checks along the way. */
static void test_ifont_size(LONG lo_size, LONG hi_size,
static void test_ifont_sizes(LONG lo_size, LONG hi_size,
LONG ratio_logical, LONG ratio_himetric, LONG ratio_logical, LONG ratio_himetric,
LONG hfont_height, const char * test_name) LONG hfont_height, const char * test_name)
{ {
@ -69,10 +69,9 @@ static void test_ifont_size(LONG lo_size, LONG hi_size,
LOGFONT lf; LOGFONT lf;
CY psize; CY psize;
HRESULT hres; HRESULT hres;
DWORD rtnval;
fd.cbSizeofstruct = sizeof(FONTDESC); fd.cbSizeofstruct = sizeof(FONTDESC);
fd.lpstrName = arial_font; /* using scalable instead of bitmap font reduces errors due to font realization */ fd.lpstrName = system_font;
S(fd.cySize).Lo = lo_size; S(fd.cySize).Lo = lo_size;
S(fd.cySize).Hi = hi_size; S(fd.cySize).Hi = hi_size;
fd.sWeight = 0; fd.sWeight = 0;
@ -88,33 +87,32 @@ static void test_ifont_size(LONG lo_size, LONG hi_size,
test_name, hres); test_name, hres);
ok(pvObj != NULL,"%s: OCFI returns NULL.\n", test_name); ok(pvObj != NULL,"%s: OCFI returns NULL.\n", test_name);
/* If scaling ration specified, change ratio. */ /* Read back size. Hi part was ignored. */
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); hres = IFont_get_Size(ifnt, &psize);
ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n", ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n",
test_name, hres); 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);
/* Check returned size - allow for errors due to rounding & font realization. */ /* Change ratio, check size unchanged. Standard is 72, 2540. */
ok((abs(S(psize).Lo - lo_size) < 10000) && S(psize).Hi == hi_size, hres = IFont_SetRatio(ifnt, ratio_logical, ratio_himetric);
"%s: IFont_get_Size: Lo=%d, Hi=%d; expected Lo=%d, Hi=%d.\n", ok(hres == S_OK,"%s: IFont_SR returns 0x%08x instead of S_OK.\n",
test_name, S(psize).Lo, S(psize).Hi, lo_size, hi_size); 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 hFont size. */ /* Check hFont size with this ratio. This tests an important */
/* conversion for which MSDN is very wrong. */
hres = IFont_get_hFont (ifnt, &hfont); hres = IFont_get_hFont (ifnt, &hfont);
ok(hres == S_OK, "%s: IFont_get_hFont returns 0x%08x instead of S_OK.\n", ok(hres == S_OK, "%s: IFont_get_hFont returns 0x%08x instead of S_OK.\n",
test_name, hres); test_name, hres);
rtnval = GetObject (hfont, sizeof(LOGFONT), &lf); hres = GetObject (hfont, sizeof(LOGFONT), &lf);
ok(rtnval > 0, "GetObject(hfont) failed\n"); ok(lf.lfHeight == hfont_height,
/* 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", "%s: hFont has lf.lfHeight=%d, expected %d.\n",
test_name, lf.lfHeight, hfont_height); test_name, lf.lfHeight, hfont_height);
@ -122,66 +120,33 @@ static void test_ifont_size(LONG lo_size, LONG hi_size,
IFont_Release(ifnt); 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) static void test_QueryInterface(void)
{ {
LPVOID pvObj = NULL; LPVOID pvObj = NULL;
HRESULT hr; HRESULT hres;
IFont* font = NULL; IFont* font = NULL;
LONG ref; LONG ret;
hr = pOleCreateFontIndirect(NULL, &IID_IFont, NULL); hres = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj);
EXPECT_HR(hr, E_POINTER);
hr = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj);
font = pvObj; font = pvObj;
EXPECT_HR(hr, S_OK); 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"); ok(font != NULL,"OCFI (NULL,..) returns NULL, instead of !NULL\n");
pvObj = NULL; pvObj = NULL;
hr = IFont_QueryInterface( font, &IID_IFont, &pvObj); hres = IFont_QueryInterface( font, &IID_IFont, &pvObj);
EXPECT_HR(hr, S_OK);
/* Test if QueryInterface increments ref counter for IFONTs */ /* Test if QueryInterface increments ref counter for IFONTs */
ref = IFont_AddRef(font); ret = IFont_AddRef(font);
ok(ref == 3 || ok(ret == 3 ||
broken(ref == 1), /* win95 */ broken(ret == 1), /* win95 */
"IFont_QI expected ref value 3 but instead got %d\n", ref); "IFont_QI expected ref value 3 but instead got %d\n",ret);
IFont_Release(font); 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);
} }
@ -236,7 +201,7 @@ static HRESULT WINAPI FontEventsDisp_QueryInterface(
{ {
if (IsEqualIID(riid, &IID_IFontEventsDisp) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch)) if (IsEqualIID(riid, &IID_IFontEventsDisp) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
{ {
IFontEventsDisp_AddRef(iface); IUnknown_AddRef(iface);
*ppvObject = iface; *ppvObject = iface;
return S_OK; return S_OK;
} }
@ -319,26 +284,26 @@ static void test_font_events_disp(void)
fontdesc.fStrikethrough = FALSE; fontdesc.fStrikethrough = FALSE;
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont); hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "OleCreateFontIndirect");
hr = IFont_QueryInterface(pFont, &IID_IConnectionPointContainer, (void **)&pCPC); hr = IFont_QueryInterface(pFont, &IID_IConnectionPointContainer, (void **)&pCPC);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "IFont_QueryInterface");
hr = IConnectionPointContainer_FindConnectionPoint(pCPC, &IID_IFontEventsDisp, &pCP); hr = IConnectionPointContainer_FindConnectionPoint(pCPC, &IID_IFontEventsDisp, &pCP);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "IConnectionPointContainer_FindConnectionPoint");
IConnectionPointContainer_Release(pCPC); IConnectionPointContainer_Release(pCPC);
hr = IConnectionPoint_Advise(pCP, (IUnknown *)&FontEventsDisp, &dwCookie); hr = IConnectionPoint_Advise(pCP, (IUnknown *)&FontEventsDisp, &dwCookie);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "IConnectionPoint_Advise");
IConnectionPoint_Release(pCP); IConnectionPoint_Release(pCP);
hr = IFont_put_Bold(pFont, TRUE); hr = IFont_put_Bold(pFont, TRUE);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "IFont_put_Bold");
ok(fonteventsdisp_invoke_called == 1, "IFontEventDisp::Invoke wasn't called once\n"); ok(fonteventsdisp_invoke_called == 1, "IFontEventDisp::Invoke wasn't called once\n");
hr = IFont_QueryInterface(pFont, &IID_IFontDisp, (void **)&pFontDisp); hr = IFont_QueryInterface(pFont, &IID_IFontDisp, (void **)&pFontDisp);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "IFont_QueryInterface");
V_VT(&vararg) = VT_BOOL; V_VT(&vararg) = VT_BOOL;
V_BOOL(&vararg) = VARIANT_FALSE; V_BOOL(&vararg) = VARIANT_FALSE;
@ -347,7 +312,6 @@ static void test_font_events_disp(void)
dispparams.cArgs = 1; dispparams.cArgs = 1;
dispparams.rgvarg = &vararg; dispparams.rgvarg = &vararg;
hr = IFontDisp_Invoke(pFontDisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL); hr = IFontDisp_Invoke(pFontDisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
EXPECT_HR(hr, S_OK);
IFontDisp_Release(pFontDisp); IFontDisp_Release(pFontDisp);
@ -355,11 +319,11 @@ static void test_font_events_disp(void)
fonteventsdisp_invoke_called); fonteventsdisp_invoke_called);
hr = IFont_Clone(pFont, &pFont2); hr = IFont_Clone(pFont, &pFont2);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "IFont_Clone");
IFont_Release(pFont); IFont_Release(pFont);
hr = IFont_put_Bold(pFont2, FALSE); hr = IFont_put_Bold(pFont2, FALSE);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "IFont_put_Bold");
/* this test shows that the notification routine isn't called again */ /* 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", ok(fonteventsdisp_invoke_called == 2, "IFontEventDisp::Invoke was called %d times instead of twice\n",
@ -486,7 +450,7 @@ static void test_Invoke(void)
VARIANT varresult; VARIANT varresult;
hr = pOleCreateFontIndirect(NULL, &IID_IFontDisp, (void **)&fontdisp); hr = pOleCreateFontIndirect(NULL, &IID_IFontDisp, (void **)&fontdisp);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "OleCreateFontIndirect");
V_VT(&vararg) = VT_BOOL; V_VT(&vararg) = VT_BOOL;
V_BOOL(&vararg) = VARIANT_FALSE; V_BOOL(&vararg) = VARIANT_FALSE;
@ -495,32 +459,32 @@ static void test_Invoke(void)
dispparams.cArgs = 1; dispparams.cArgs = 1;
dispparams.rgvarg = &vararg; dispparams.rgvarg = &vararg;
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_IFontDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_IFontDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
EXPECT_HR(hr, DISP_E_UNKNOWNINTERFACE); ok(hr == DISP_E_UNKNOWNINTERFACE, "IFontDisp_Invoke should have returned DISP_E_UNKNOWNINTERFACE instead of 0x%08x\n", hr);
dispparams.cArgs = 0; dispparams.cArgs = 0;
dispparams.rgvarg = NULL; dispparams.rgvarg = NULL;
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
EXPECT_HR(hr, DISP_E_BADPARAMCOUNT); ok(hr == DISP_E_BADPARAMCOUNT, "IFontDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
EXPECT_HR(hr, DISP_E_PARAMNOTOPTIONAL); ok(hr == DISP_E_PARAMNOTOPTIONAL, "IFontDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
EXPECT_HR(hr, DISP_E_PARAMNOTOPTIONAL); ok(hr == DISP_E_PARAMNOTOPTIONAL, "IFontDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "IFontDisp_Invoke");
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_METHOD, NULL, &varresult, NULL, NULL); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_METHOD, NULL, &varresult, NULL, NULL);
EXPECT_HR(hr, DISP_E_MEMBERNOTFOUND); ok(hr == DISP_E_MEMBERNOTFOUND, "IFontDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
hr = IFontDisp_Invoke(fontdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL); hr = IFontDisp_Invoke(fontdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
EXPECT_HR(hr, DISP_E_MEMBERNOTFOUND); ok(hr == DISP_E_MEMBERNOTFOUND, "IFontDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
dispparams.cArgs = 1; dispparams.cArgs = 1;
dispparams.rgvarg = &vararg; dispparams.rgvarg = &vararg;
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL); hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "IFontDisp_Invoke");
IFontDisp_Release(fontdisp); IFontDisp_Release(fontdisp);
} }
@ -848,19 +812,27 @@ static void test_returns(void)
fontdesc.fStrikethrough = FALSE; fontdesc.fStrikethrough = FALSE;
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont); hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "OleCreateFontIndirect");
hr = IFont_put_Name(pFont, NULL); hr = IFont_put_Name(pFont, NULL);
EXPECT_HR(hr, CTL_E_INVALIDPROPERTYVALUE); ok(hr == CTL_E_INVALIDPROPERTYVALUE,
"IFont::put_Name: Expected CTL_E_INVALIDPROPERTYVALUE got 0x%08x\n",
hr);
hr = IFont_get_Name(pFont, NULL); hr = IFont_get_Name(pFont, NULL);
EXPECT_HR(hr, E_POINTER); ok(hr == E_POINTER,
"IFont::get_Name: Expected E_POINTER got 0x%08x\n",
hr);
hr = IFont_get_Size(pFont, NULL); hr = IFont_get_Size(pFont, NULL);
EXPECT_HR(hr, E_POINTER); ok(hr == E_POINTER,
"IFont::get_Size: Expected E_POINTER got 0x%08x\n",
hr);
hr = IFont_get_Bold(pFont, NULL); hr = IFont_get_Bold(pFont, NULL);
EXPECT_HR(hr, E_POINTER); ok(hr == E_POINTER,
"IFont::get_Bold: Expected E_POINTER got 0x%08x\n",
hr);
IFont_Release(pFont); IFont_Release(pFont);
} }
@ -885,10 +857,10 @@ static void test_hfont_lifetime(void)
fontdesc.fStrikethrough = FALSE; fontdesc.fStrikethrough = FALSE;
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font); hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "OleCreateFontIndirect");
hr = IFont_get_hFont(font, &hfont); hr = IFont_get_hFont(font, &hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_hFont");
/* show that if the font is updated the old hfont is deleted when the /* show that if the font is updated the old hfont is deleted when the
new font is realized */ new font is realized */
@ -902,14 +874,14 @@ static void test_hfont_lifetime(void)
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_put_Size(font, size); hr = IFont_put_Size(font, size);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "put_Size");
/* put_Size doesn't cause the new font to be realized */ /* put_Size doesn't cause the new font to be realized */
obj_type = GetObjectType(last_hfont); obj_type = GetObjectType(last_hfont);
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_get_hFont(font, &hfont); hr = IFont_get_hFont(font, &hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_hFont");
obj_type = GetObjectType(last_hfont); obj_type = GetObjectType(last_hfont);
ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type); ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type);
@ -919,19 +891,20 @@ static void test_hfont_lifetime(void)
until the font object is released */ until the font object is released */
for(i = 0; i < 100; i++) for(i = 0; i < 100; i++)
{ {
size.int64 = (i + 10) * 20000; size.int64 = (i + 10) * 20000;
obj_type = GetObjectType(hfont); obj_type = GetObjectType(hfont);
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_put_Size(font, size); hr = IFont_put_Size(font, size);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "put_Size");
hr = IFont_get_hFont(font, &hfont); hr = IFont_get_hFont(font, &hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_hFont");
hr = IFont_AddRefHfont(font, hfont); hr = IFont_AddRefHfont(font, hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "AddRefHfont");
if(i == 0) first_hfont = hfont; if(i == 0) first_hfont = hfont;
obj_type = GetObjectType(first_hfont); obj_type = GetObjectType(first_hfont);
@ -947,10 +920,10 @@ static void test_hfont_lifetime(void)
through re-realization */ through re-realization */
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font); hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "OleCreateFontIndirect");
hr = IFont_get_hFont(font, &hfont); hr = IFont_get_hFont(font, &hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_hFont");
for(i = 0; i < 100; i++) for(i = 0; i < 100; i++)
{ {
@ -962,20 +935,20 @@ static void test_hfont_lifetime(void)
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_put_Size(font, size); hr = IFont_put_Size(font, size);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "put_Size");
/* put_Size doesn't cause the new font to be realized */ /* put_Size doesn't cause the new font to be realized */
obj_type = GetObjectType(last_hfont); obj_type = GetObjectType(last_hfont);
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_get_hFont(font, &hfont); hr = IFont_get_hFont(font, &hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_hFont");
hr = IFont_AddRefHfont(font, hfont); hr = IFont_AddRefHfont(font, hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "AddRefHfont");
hr = IFont_ReleaseHfont(font, hfont); hr = IFont_ReleaseHfont(font, hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "ReleaseHfont");
obj_type = GetObjectType(last_hfont); obj_type = GetObjectType(last_hfont);
ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type); ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type);
@ -992,13 +965,13 @@ static void test_hfont_lifetime(void)
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_put_Size(font, size); hr = IFont_put_Size(font, size);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "put_Size");
hr = IFont_get_hFont(font, &hfont); hr = IFont_get_hFont(font, &hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_hFont");
hr = IFont_ReleaseHfont(font, hfont); hr = IFont_ReleaseHfont(font, hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "ReleaseHfont");
if(i == 0) first_hfont = hfont; if(i == 0) first_hfont = hfont;
obj_type = GetObjectType(first_hfont); obj_type = GetObjectType(first_hfont);
@ -1015,23 +988,23 @@ static void test_hfont_lifetime(void)
that includes internal and external references */ that includes internal and external references */
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font); hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "OleCreateFontIndirect");
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font2); hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font2);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "OleCreateFontIndirect");
hr = IFont_get_hFont(font, &hfont); hr = IFont_get_hFont(font, &hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_hFont");
hr = IFont_get_hFont(font2, &first_hfont); hr = IFont_get_hFont(font2, &first_hfont);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_hFont");
todo_wine todo_wine
ok(hfont == first_hfont, "fonts differ\n"); ok(hfont == first_hfont, "fonts differ\n");
hr = IFont_ReleaseHfont(font, hfont); hr = IFont_ReleaseHfont(font, hfont);
EXPECT_HR(hr, S_OK); ok(hr == S_OK, "got %08x\n", hr);
hr = IFont_ReleaseHfont(font, hfont); hr = IFont_ReleaseHfont(font, hfont);
todo_wine todo_wine
EXPECT_HR(hr, S_OK); ok(hr == S_OK, "got %08x\n", hr);
hr = IFont_ReleaseHfont(font, hfont); hr = IFont_ReleaseHfont(font, hfont);
EXPECT_HR(hr, S_FALSE); ok(hr == S_FALSE, "got %08x\n", hr);
obj_type = GetObjectType(hfont); obj_type = GetObjectType(hfont);
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type); ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
@ -1068,10 +1041,10 @@ static void test_realization(void)
fontdesc.fStrikethrough = FALSE; fontdesc.fStrikethrough = FALSE;
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font); hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "OleCreateFontIndirect");
hr = IFont_get_Charset(font, &cs); hr = IFont_get_Charset(font, &cs);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_Charset");
ok(cs == ANSI_CHARSET, "got charset %d\n", cs); ok(cs == ANSI_CHARSET, "got charset %d\n", cs);
IFont_Release(font); IFont_Release(font);
@ -1081,65 +1054,29 @@ static void test_realization(void)
fontdesc.lpstrName = arial_font; fontdesc.lpstrName = arial_font;
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font); hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "OleCreateFontIndirect");
hr = IFont_get_Charset(font, &cs); hr = IFont_get_Charset(font, &cs);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_Charset");
ok(cs == ANSI_CHARSET, "got charset %d\n", cs); ok(cs == ANSI_CHARSET, "got charset %d\n", cs);
name = SysAllocString(marlett_font); name = SysAllocString(marlett_font);
hr = IFont_put_Name(font, name); hr = IFont_put_Name(font, name);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "put_Name");
SysFreeString(name); SysFreeString(name);
hr = IFont_get_Name(font, &name); hr = IFont_get_Name(font, &name);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_Name");
ok(!lstrcmpiW(name, marlett_font), "got name %s\n", wine_dbgstr_w(name)); ok(!lstrcmpiW(name, marlett_font), "got name %s\n", wine_dbgstr_w(name));
SysFreeString(name); SysFreeString(name);
hr = IFont_get_Charset(font, &cs); hr = IFont_get_Charset(font, &cs);
EXPECT_HR(hr, S_OK); ok_ole_success(hr, "get_Charset");
ok(cs == SYMBOL_CHARSET, "got charset %d\n", cs); ok(cs == SYMBOL_CHARSET, "got charset %d\n", cs);
IFont_Release(font); 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) START_TEST(olefont)
{ {
hOleaut32 = GetModuleHandleA("oleaut32.dll"); hOleaut32 = GetModuleHandleA("oleaut32.dll");
@ -1152,7 +1089,20 @@ START_TEST(olefont)
test_QueryInterface(); test_QueryInterface();
test_type_info(); test_type_info();
test_ifont_sizes();
/* 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_font_events_disp();
test_GetIDsOfNames(); test_GetIDsOfNames();
test_Invoke(); test_Invoke();
@ -1162,5 +1112,4 @@ START_TEST(olefont)
test_returns(); test_returns();
test_hfont_lifetime(); test_hfont_lifetime();
test_realization(); test_realization();
test_OleCreateFontIndirect();
} }

View file

@ -2,7 +2,7 @@
* OLEPICTURE test program * OLEPICTURE test program
* *
* Copyright 2005 Marcus Meissner * Copyright 2005 Marcus Meissner
* Copyright 2012 Dmitry Timoshkov *
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -25,7 +25,6 @@
#include <float.h> #include <float.h>
#define COBJMACROS #define COBJMACROS
#define CONST_VTABLE
#define NONAMELESSUNION #define NONAMELESSUNION
#include "wine/test.h" #include "wine/test.h"
@ -54,7 +53,7 @@
static HMODULE hOleaut32; static HMODULE hOleaut32;
static HRESULT (WINAPI *pOleLoadPicture)(LPSTREAM,LONG,BOOL,REFIID,LPVOID*); static HRESULT (WINAPI *pOleLoadPicture)(LPSTREAM,LONG,BOOL,REFIID,LPVOID*);
static HRESULT (WINAPI *pOleLoadPictureEx)(LPSTREAM,LONG,BOOL,REFIID,DWORD,DWORD,DWORD,LPVOID*); static HRESULT (WINAPI *pOleCreatePictureIndirect)(PICTDESC*,REFIID,BOOL,LPVOID*);
#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
@ -170,17 +169,17 @@ static const unsigned char enhmetafile[] = {
}; };
typedef struct NoStatStreamImpl struct NoStatStreamImpl
{ {
IStream IStream_iface; const IStreamVtbl *lpVtbl;
LONG ref; LONG ref;
HGLOBAL supportHandle; HGLOBAL supportHandle;
ULARGE_INTEGER streamSize; ULARGE_INTEGER streamSize;
ULARGE_INTEGER currentPosition; ULARGE_INTEGER currentPosition;
} NoStatStreamImpl; };
typedef struct NoStatStreamImpl NoStatStreamImpl;
static IStream* NoStatStream_Construct(HGLOBAL hGlobal); static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal);
static void static void
test_pic_with_stream(LPSTREAM stream, unsigned int imgsize) test_pic_with_stream(LPSTREAM stream, unsigned int imgsize)
@ -220,7 +219,7 @@ test_pic_with_stream(LPSTREAM stream, unsigned int imgsize)
if (handle) if (handle)
{ {
BITMAP bmp; BITMAP bmp;
GetObject(UlongToHandle(handle), sizeof(BITMAP), &bmp); GetObject((HGDIOBJ)handle, sizeof(BITMAP), &bmp);
todo_wine ok(bmp.bmBits != 0, "not a dib\n"); todo_wine ok(bmp.bmBits != 0, "not a dib\n");
} }
@ -283,7 +282,7 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize)
IStream_Release(stream); IStream_Release(stream);
/* again with Non Statable and Non Seekable stream */ /* again with Non Statable and Non Seekable stream */
stream = NoStatStream_Construct(hglob); stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
hglob = 0; /* Non-statable impl always deletes on release */ hglob = 0; /* Non-statable impl always deletes on release */
test_pic_with_stream(stream, 0); test_pic_with_stream(stream, 0);
@ -314,7 +313,7 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize)
IStream_Release(stream); IStream_Release(stream);
/* again with Non Statable and Non Seekable stream */ /* again with Non Statable and Non Seekable stream */
stream = NoStatStream_Construct(hglob); stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
hglob = 0; /* Non-statable impl always deletes on release */ hglob = 0; /* Non-statable impl always deletes on release */
test_pic_with_stream(stream, 0); test_pic_with_stream(stream, 0);
@ -482,26 +481,24 @@ static void test_Invoke(void)
static void test_OleCreatePictureIndirect(void) static void test_OleCreatePictureIndirect(void)
{ {
OLE_HANDLE handle;
IPicture *pict; IPicture *pict;
HRESULT hr; HRESULT hr;
short type; short type;
OLE_HANDLE handle;
if (0) if(!pOleCreatePictureIndirect)
{ {
/* crashes on native */ win_skip("Skipping OleCreatePictureIndirect tests\n");
OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, NULL); return;
} }
hr = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void**)&pict); hr = pOleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void**)&pict);
ok(hr == S_OK, "hr %08x\n", hr); ok(hr == S_OK, "hr %08x\n", hr);
type = PICTYPE_NONE;
hr = IPicture_get_Type(pict, &type); hr = IPicture_get_Type(pict, &type);
ok(hr == S_OK, "hr %08x\n", hr); ok(hr == S_OK, "hr %08x\n", hr);
ok(type == PICTYPE_UNINITIALIZED, "type %d\n", type); ok(type == PICTYPE_UNINITIALIZED, "type %d\n", type);
handle = 0xdeadbeef;
hr = IPicture_get_Handle(pict, &handle); hr = IPicture_get_Handle(pict, &handle);
ok(hr == S_OK, "hr %08x\n", hr); ok(hr == S_OK, "hr %08x\n", hr);
ok(handle == 0, "handle %08x\n", handle); ok(handle == 0, "handle %08x\n", handle);
@ -521,7 +518,7 @@ static void test_apm(void)
short type; short type;
if(!winetest_interactive) { if(!winetest_interactive) {
skip("ROSTESTS-2: oleaut_winetest:olepicture crashes with Page Fault.\n"); skip("Bug 5000: oleaut_winetest:olepicture crashes with Page Fault.\n");
return; return;
} }
@ -530,7 +527,7 @@ static void test_apm(void)
memcpy(data, apmdata, sizeof(apmdata)); memcpy(data, apmdata, sizeof(apmdata));
ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream)); ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
ole_check(pOleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict)); ole_check(OleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict));
ole_check(IPicture_get_Handle(pict, &handle)); ole_check(IPicture_get_Handle(pict, &handle));
ok(handle != 0, "handle is null\n"); ok(handle != 0, "handle is null\n");
@ -565,7 +562,7 @@ static void test_metafile(void)
ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream)); ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
/* Windows does not load simple metafiles */ /* Windows does not load simple metafiles */
ole_expect(pOleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL); ole_expect(OleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL);
IStream_Release(stream); IStream_Release(stream);
} }
@ -582,7 +579,7 @@ static void test_enhmetafile(void)
short type; short type;
if(!winetest_interactive) { if(!winetest_interactive) {
skip("ROSTESTS-2: oleaut_winetest:olepicture crashes with Page Fault.\n"); skip("Bug 5000: oleaut_winetest:olepicture crashes with Page Fault.\n");
return; return;
} }
@ -591,7 +588,7 @@ static void test_enhmetafile(void)
memcpy(data, enhmetafile, sizeof(enhmetafile)); memcpy(data, enhmetafile, sizeof(enhmetafile));
ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream)); ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
ole_check(pOleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict)); ole_check(OleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict));
ole_check(IPicture_get_Handle(pict, &handle)); ole_check(IPicture_get_Handle(pict, &handle));
ok(handle != 0, "handle is null\n"); ok(handle != 0, "handle is null\n");
@ -678,9 +675,9 @@ static void test_Render(void)
IPicture_get_Width(pic, &pWidth); IPicture_get_Width(pic, &pWidth);
IPicture_get_Height(pic, &pHeight); IPicture_get_Height(pic, &pHeight);
SetPixelV(hdc, 0, 0, 0x00223344); SetPixelV(hdc, 0, 0, 0x00F0F0F0);
SetPixelV(hdc, 5, 5, 0x00223344); SetPixelV(hdc, 5, 5, 0x00F0F0F0);
SetPixelV(hdc, 10, 10, 0x00223344); SetPixelV(hdc, 10, 10, 0x00F0F0F0);
expected = GetPixel(hdc, 0, 0); expected = GetPixel(hdc, 0, 0);
hres = IPicture_Render(pic, hdc, 1, 1, 9, 9, 0, 0, pWidth, -pHeight, NULL); hres = IPicture_Render(pic, hdc, 1, 1, 9, 9, 0, 0, pWidth, -pHeight, NULL);
@ -803,8 +800,9 @@ static void test_OleLoadPicturePath(void)
hres = OleLoadPicturePath(emptyW, NULL, 0, 0, NULL, (void **)&pic); hres = OleLoadPicturePath(emptyW, NULL, 0, 0, NULL, (void **)&pic);
todo_wine todo_wine
ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */ ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */
broken(hres == E_UNEXPECTED) || /* NT4 */ hres == E_UNEXPECTED || /* NT4/Win95 */
broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */ hres == E_FAIL || /* Win95 OSR2 */
hres == E_OUTOFMEMORY, /* Win98/Win2k/Win2k3 */
"Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres); "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres);
ok(pic == NULL, ok(pic == NULL,
"Expected the output interface pointer to be NULL, got %p\n", pic); "Expected the output interface pointer to be NULL, got %p\n", pic);
@ -813,8 +811,9 @@ static void test_OleLoadPicturePath(void)
hres = OleLoadPicturePath(emptyW, NULL, 0, 0, &IID_IPicture, (void **)&pic); hres = OleLoadPicturePath(emptyW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
todo_wine todo_wine
ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */ ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */
broken(hres == E_UNEXPECTED) || /* NT4 */ hres == E_UNEXPECTED || /* NT4/Win95 */
broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */ hres == E_FAIL || /* Win95 OSR2 */
hres == E_OUTOFMEMORY, /* Win98/Win2k/Win2k3 */
"Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres); "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres);
ok(pic == NULL, ok(pic == NULL,
"Expected the output interface pointer to be NULL, got %p\n", pic); "Expected the output interface pointer to be NULL, got %p\n", pic);
@ -832,7 +831,7 @@ static void test_OleLoadPicturePath(void)
/* Try a normal DOS path. */ /* Try a normal DOS path. */
hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic); hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == S_OK || ok(hres == S_OK ||
broken(hres == E_UNEXPECTED), /* NT4 */ broken(hres == E_UNEXPECTED), /* NT4/Win95 */
"Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres); "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
if (pic) if (pic)
IPicture_Release(pic); IPicture_Release(pic);
@ -840,7 +839,7 @@ static void test_OleLoadPicturePath(void)
/* Try a DOS path with tacked on "file:". */ /* Try a DOS path with tacked on "file:". */
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == S_OK || ok(hres == S_OK ||
broken(hres == E_UNEXPECTED), /* NT4 */ broken(hres == E_UNEXPECTED), /* NT4/Win95 */
"Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres); "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
if (pic) if (pic)
IPicture_Release(pic); IPicture_Release(pic);
@ -850,14 +849,14 @@ static void test_OleLoadPicturePath(void)
/* Try with a nonexistent file. */ /* Try with a nonexistent file. */
hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic); hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */ ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
broken(hres == E_UNEXPECTED) || /* NT4 */ hres == E_UNEXPECTED || /* NT4/Win95 */
broken(hres == E_FAIL), /*Win2k */ hres == E_FAIL, /* Win9x/Win2k */
"Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); "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); hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */ ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
broken(hres == E_UNEXPECTED) || /* NT4 */ hres == E_UNEXPECTED || /* NT4/Win95 */
broken(hres == E_FAIL), /* Win2k */ hres == E_FAIL, /* Win9x/Win2k */
"Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); "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 = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
@ -876,7 +875,7 @@ static void test_OleLoadPicturePath(void)
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == S_OK || ok(hres == S_OK ||
broken(hres == E_UNEXPECTED), /* NT4 */ broken(hres == E_UNEXPECTED), /* NT4/Win95 */
"Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres); "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
if (pic) if (pic)
IPicture_Release(pic); IPicture_Release(pic);
@ -886,244 +885,16 @@ static void test_OleLoadPicturePath(void)
/* Try with a nonexistent file. */ /* Try with a nonexistent file. */
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */ ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
broken(hres == E_UNEXPECTED) || /* NT4 */ hres == E_UNEXPECTED || /* NT4/Win95 */
broken(hres == E_FAIL), /* Win2k */ hres == E_FAIL, /* Win9x/Win2k */
"Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); "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) START_TEST(olepicture)
{ {
hOleaut32 = GetModuleHandleA("oleaut32.dll"); hOleaut32 = GetModuleHandleA("oleaut32.dll");
pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture"); pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture");
pOleLoadPictureEx = (void*)GetProcAddress(hOleaut32, "OleLoadPictureEx"); pOleCreatePictureIndirect = (void*)GetProcAddress(hOleaut32, "OleCreatePictureIndirect");
if (!pOleLoadPicture) if (!pOleLoadPicture)
{ {
win_skip("OleLoadPicture is not available\n"); win_skip("OleLoadPicture is not available\n");
@ -1139,14 +910,10 @@ START_TEST(olepicture)
if (0) test_pic(pngimage, sizeof(pngimage)); if (0) test_pic(pngimage, sizeof(pngimage));
test_empty_image(); test_empty_image();
test_empty_image_2(); test_empty_image_2();
if (pOleLoadPictureEx)
{
test_apm(); test_apm();
test_metafile(); test_metafile();
test_enhmetafile(); test_enhmetafile();
}
else
win_skip("OleLoadPictureEx is not available\n");
test_Invoke(); test_Invoke();
test_OleCreatePictureIndirect(); test_OleCreatePictureIndirect();
test_Render(); test_Render();
@ -1154,21 +921,12 @@ START_TEST(olepicture)
test_get_Handle(); test_get_Handle();
test_get_Type(); test_get_Type();
test_OleLoadPicturePath(); test_OleLoadPicturePath();
test_himetric();
test_load_save_bmp();
test_load_save_icon();
test_load_save_empty_picture();
} }
/* Helper functions only ... */ /* Helper functions only ... */
static inline NoStatStreamImpl *impl_from_IStream(IStream *iface)
{
return CONTAINING_RECORD(iface, NoStatStreamImpl, IStream_iface);
}
static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This) static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This)
{ {
GlobalFree(This->supportHandle); GlobalFree(This->supportHandle);
@ -1179,7 +937,7 @@ static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This)
static ULONG WINAPI NoStatStreamImpl_AddRef( static ULONG WINAPI NoStatStreamImpl_AddRef(
IStream* iface) IStream* iface)
{ {
NoStatStreamImpl* const This = impl_from_IStream(iface); NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
return InterlockedIncrement(&This->ref); return InterlockedIncrement(&This->ref);
} }
@ -1188,7 +946,7 @@ static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
REFIID riid, /* [in] */ REFIID riid, /* [in] */
void** ppvObject) /* [iid_is][out] */ void** ppvObject) /* [iid_is][out] */
{ {
NoStatStreamImpl* const This = impl_from_IStream(iface); NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
if (ppvObject==0) return E_INVALIDARG; if (ppvObject==0) return E_INVALIDARG;
*ppvObject = 0; *ppvObject = 0;
if (IsEqualIID(&IID_IUnknown, riid)) if (IsEqualIID(&IID_IUnknown, riid))
@ -1209,7 +967,7 @@ static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
static ULONG WINAPI NoStatStreamImpl_Release( static ULONG WINAPI NoStatStreamImpl_Release(
IStream* iface) IStream* iface)
{ {
NoStatStreamImpl* const This = impl_from_IStream(iface); NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
ULONG newRef = InterlockedDecrement(&This->ref); ULONG newRef = InterlockedDecrement(&This->ref);
if (newRef==0) if (newRef==0)
NoStatStreamImpl_Destroy(This); NoStatStreamImpl_Destroy(This);
@ -1222,7 +980,7 @@ static HRESULT WINAPI NoStatStreamImpl_Read(
ULONG cb, /* [in] */ ULONG cb, /* [in] */
ULONG* pcbRead) /* [out] */ ULONG* pcbRead) /* [out] */
{ {
NoStatStreamImpl* const This = impl_from_IStream(iface); NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
void* supportBuffer; void* supportBuffer;
ULONG bytesReadBuffer; ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer; ULONG bytesToReadFromBuffer;
@ -1246,7 +1004,7 @@ static HRESULT WINAPI NoStatStreamImpl_Write(
ULONG cb, /* [in] */ ULONG cb, /* [in] */
ULONG* pcbWritten) /* [out] */ ULONG* pcbWritten) /* [out] */
{ {
NoStatStreamImpl* const This = impl_from_IStream(iface); NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
void* supportBuffer; void* supportBuffer;
ULARGE_INTEGER newSize; ULARGE_INTEGER newSize;
ULONG bytesWritten = 0; ULONG bytesWritten = 0;
@ -1274,7 +1032,7 @@ static HRESULT WINAPI NoStatStreamImpl_Seek(
DWORD dwOrigin, /* [in] */ DWORD dwOrigin, /* [in] */
ULARGE_INTEGER* plibNewPosition) /* [out] */ ULARGE_INTEGER* plibNewPosition) /* [out] */
{ {
NoStatStreamImpl* const This = impl_from_IStream(iface); NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
ULARGE_INTEGER newPosition; ULARGE_INTEGER newPosition;
switch (dwOrigin) switch (dwOrigin)
{ {
@ -1303,7 +1061,7 @@ static HRESULT WINAPI NoStatStreamImpl_SetSize(
IStream* iface, IStream* iface,
ULARGE_INTEGER libNewSize) /* [in] */ ULARGE_INTEGER libNewSize) /* [in] */
{ {
NoStatStreamImpl* const This = impl_from_IStream(iface); NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
HGLOBAL supportHandle; HGLOBAL supportHandle;
if (libNewSize.u.HighPart != 0) if (libNewSize.u.HighPart != 0)
return STG_E_INVALIDFUNCTION; return STG_E_INVALIDFUNCTION;
@ -1416,14 +1174,14 @@ static const IStreamVtbl NoStatStreamImpl_Vtbl;
In any case the object takes ownership of memory handle and will free it on In any case the object takes ownership of memory handle and will free it on
object release. object release.
*/ */
static IStream* NoStatStream_Construct(HGLOBAL hGlobal) static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal)
{ {
NoStatStreamImpl* newStream; NoStatStreamImpl* newStream;
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl)); newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl));
if (newStream!=0) if (newStream!=0)
{ {
newStream->IStream_iface.lpVtbl = &NoStatStreamImpl_Vtbl; newStream->lpVtbl = &NoStatStreamImpl_Vtbl;
newStream->ref = 1; newStream->ref = 1;
newStream->supportHandle = hGlobal; newStream->supportHandle = hGlobal;
@ -1435,7 +1193,7 @@ static IStream* NoStatStream_Construct(HGLOBAL hGlobal)
newStream->streamSize.u.HighPart = 0; newStream->streamSize.u.HighPart = 0;
newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle); newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
} }
return &newStream->IStream_iface; return newStream;
} }