oleaut32: Fix OLEFontImpl_SetRatio return when either cyLogical or cyHimetric are 0.
[wine.git] / dlls / oleaut32 / tests / olefont.c
blob0eab729d910f5138f89b70c8ae68192b6f260f6d
1 /*
2 * OLEFONT test program
4 * Copyright 2003 Marcus Meissner
5 * Copyright 2006 (Google) Benjamin Arai
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <math.h>
26 #include <float.h>
28 #define COBJMACROS
30 #include <wine/test.h>
31 #include <windef.h>
32 #include <winbase.h>
33 #include <winuser.h>
34 #include <wingdi.h>
35 #include <winnls.h>
36 #include <winerror.h>
37 #include <winnt.h>
38 #include <initguid.h>
39 #include <wtypes.h>
40 #include <olectl.h>
41 #include <ocidl.h>
43 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
45 static WCHAR MSSansSerif_font[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f',0};
46 static WCHAR system_font[] = { 'S','y','s','t','e','m',0 };
47 static WCHAR arial_font[] = { 'A','r','i','a','l',0 };
48 static WCHAR marlett_font[] = { 'M','a','r','l','e','t','t',0 };
50 static HMODULE hOleaut32;
52 static HRESULT (WINAPI *pOleCreateFontIndirect)(LPFONTDESC,REFIID,LPVOID*);
54 #define EXPECT_HR(hr,hr_exp) \
55 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
57 /* Create a font with cySize given by lo_size, hi_size, */
58 /* SetRatio to ratio_logical, ratio_himetric, */
59 /* check that resulting hfont has height hfont_height. */
60 /* Various checks along the way. */
61 static void test_ifont_size(LONG lo_size, LONG hi_size,
62 LONG ratio_logical, LONG ratio_himetric,
63 LONG hfont_height, const char * test_name)
65 FONTDESC fd;
66 LPVOID pvObj = NULL;
67 IFont* ifnt = NULL;
68 HFONT hfont;
69 LOGFONTA lf;
70 CY psize;
71 HRESULT hres;
72 DWORD rtnval;
74 fd.cbSizeofstruct = sizeof(FONTDESC);
75 fd.lpstrName = arial_font; /* using scalable instead of bitmap font reduces errors due to font realization */
76 S(fd.cySize).Lo = lo_size;
77 S(fd.cySize).Hi = hi_size;
78 fd.sWeight = 0;
79 fd.sCharset = 0;
80 fd.fItalic = FALSE;
81 fd.fUnderline = FALSE;
82 fd.fStrikethrough = FALSE;
84 /* Create font, test that it worked. */
85 hres = pOleCreateFontIndirect(&fd, &IID_IFont, &pvObj);
86 ifnt = pvObj;
87 ok(hres == S_OK,"%s: OCFI returns 0x%08x instead of S_OK.\n",
88 test_name, hres);
89 ok(pvObj != NULL,"%s: OCFI returns NULL.\n", test_name);
91 /* Change the scaling ratio */
92 hres = IFont_SetRatio(ifnt, ratio_logical, ratio_himetric);
93 ok((ratio_logical && ratio_himetric) ? hres == S_OK : hres == E_FAIL,
94 "%s: IFont_SetRatio unexpectedly returned 0x%08x.\n", test_name, hres);
96 /* Read back size. */
97 hres = IFont_get_Size(ifnt, &psize);
98 ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n",
99 test_name, hres);
101 /* Check returned size - allow for errors due to rounding & font realization. */
102 ok((abs(S(psize).Lo - lo_size) < 10000) && S(psize).Hi == hi_size,
103 "%s: IFont_get_Size: Lo=%d, Hi=%d; expected Lo=%d, Hi=%d.\n",
104 test_name, S(psize).Lo, S(psize).Hi, lo_size, hi_size);
106 /* Check hFont size. */
107 hres = IFont_get_hFont (ifnt, &hfont);
108 ok(hres == S_OK, "%s: IFont_get_hFont returns 0x%08x instead of S_OK.\n",
109 test_name, hres);
110 rtnval = GetObjectA(hfont, sizeof(LOGFONTA), &lf);
111 ok(rtnval > 0, "GetObject(hfont) failed\n");
113 /* Since font scaling may encounter rounding errors, allow 1 pixel deviation. */
114 ok(abs(lf.lfHeight - hfont_height) <= 1,
115 "%s: hFont has lf.lfHeight=%d, expected %d.\n",
116 test_name, lf.lfHeight, hfont_height);
118 /* Free IFont. */
119 IFont_Release(ifnt);
122 static void test_ifont_sizes(void)
124 /* Test various size operations and conversions. */
125 /* Add more as needed. */
127 /* Results of first 2 tests depend on display resolution. */
128 HDC hdc = GetDC(0);
129 LONG dpi = GetDeviceCaps(hdc, LOGPIXELSY); /* expected results depend on display DPI */
130 ReleaseDC(0, hdc);
131 if(dpi == 96) /* normal resolution display */
133 test_ifont_size(180000, 0, 0, 0, -24, "default"); /* normal font */
134 test_ifont_size(186000, 0, 0, 0, -25, "rounding"); /* test rounding */
135 } else if(dpi == 72) /* low resolution display */
137 test_ifont_size(180000, 0, 0, 0, -18, "default"); /* normal font */
138 test_ifont_size(186000, 0, 0, 0, -19, "rounding"); /* test rounding */
139 } else if(dpi == 120) /* high resolution display */
141 test_ifont_size(180000, 0, 0, 0, -30, "default"); /* normal font */
142 test_ifont_size(186000, 0, 0, 0, -31, "rounding"); /* test rounding */
143 } else
144 skip("Skipping resolution dependent font size tests - display resolution is %d\n", dpi);
146 /* Next 4 tests specify a scaling ratio, so display resolution is not a factor. */
147 test_ifont_size(180000, 0, 72, 2540, -18, "ratio1"); /* change ratio */
148 test_ifont_size(180000, 0, 144, 2540, -36, "ratio2"); /* another ratio */
149 test_ifont_size(180000, 0, 72, 1270, -36, "ratio3"); /* yet another ratio */
150 test_ifont_size(186000, 0, 72, 2540, -19, "rounding+ratio"); /* test rounding with ratio */
152 /* test various combinations of logical == himetric */
153 test_ifont_size(180000, 0, 10, 10, -635, "identical ratio 1");
154 test_ifont_size(240000, 0, 10, 10, -848, "identical ratio 2");
155 test_ifont_size(300000, 0, 10, 10, -1058, "identical ratio 3");
157 /* test various combinations of logical and himetric both set to 1 */
158 test_ifont_size(180000, 0, 1, 1, -24, "1:1 ratio 1");
159 test_ifont_size(240000, 0, 1, 1, -32, "1:1 ratio 2");
160 test_ifont_size(300000, 0, 1, 1, -40, "1:1 ratio 3");
162 /* test various combinations of logical set to 1 */
163 test_ifont_size(180000, 0, 1, 0, -24, "1:0 ratio 1");
164 test_ifont_size(240000, 0, 1, 0, -32, "1:0 ratio 2");
165 test_ifont_size(300000, 0, 1, 0, -40, "1:0 ratio 3");
167 /* test various combinations of himetric set to 1 */
168 test_ifont_size(180000, 0, 0, 1, -24, "0:1 ratio 1");
169 test_ifont_size(240000, 0, 0, 1, -32, "0:1 ratio 2");
170 test_ifont_size(300000, 0, 0, 1, -40, "0:1 ratio 3");
172 /* test various combinations of 2:1 logical:himetric */
173 test_ifont_size(180000, 0, 2, 1, -1270, "2:1 ratio 1");
174 test_ifont_size(240000, 0, 2, 1, -1694, "2:1 ratio 2");
175 test_ifont_size(300000, 0, 2, 1, -2117, "2:1 ratio 3");
177 /* test various combinations of 1:2 logical:himetric */
178 test_ifont_size(180000, 0, 1, 2, -318, "1:2 ratio 1");
179 test_ifont_size(240000, 0, 1, 2, -424, "1:2 ratio 2");
180 test_ifont_size(300000, 0, 1, 2, -529, "1:2 ratio 3");
182 /* test various combinations of logical and himetric both set to 2 */
183 test_ifont_size(180000, 0, 2, 2, -635, "2:2 ratio 1");
184 test_ifont_size(240000, 0, 2, 2, -848, "2:2 ratio 2");
185 test_ifont_size(300000, 0, 2, 2, -1058, "2:2 ratio 3");
188 static void test_QueryInterface(void)
190 LPVOID pvObj = NULL;
191 HRESULT hr;
192 IFont* font = NULL;
193 LONG ref;
195 hr = pOleCreateFontIndirect(NULL, &IID_IFont, NULL);
196 EXPECT_HR(hr, E_POINTER);
198 hr = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj);
199 font = pvObj;
201 EXPECT_HR(hr, S_OK);
202 ok(font != NULL,"OCFI (NULL,..) returns NULL, instead of !NULL\n");
204 pvObj = NULL;
205 hr = IFont_QueryInterface( font, &IID_IFont, &pvObj);
206 EXPECT_HR(hr, S_OK);
208 /* Test if QueryInterface increments ref counter for IFONTs */
209 ref = IFont_AddRef(font);
210 ok(ref == 3 ||
211 broken(ref == 1), /* win95 */
212 "IFont_QI expected ref value 3 but instead got %d\n", ref);
213 IFont_Release(font);
215 ok(pvObj != NULL,"IFont_QI does return NULL, instead of a ptr\n");
217 IFont_Release(font);
218 IFont_Release(font);
221 static void test_type_info(void)
223 LPVOID pvObj = NULL;
224 HRESULT hres;
225 IFontDisp* fontdisp = NULL;
226 ITypeInfo* pTInfo;
227 WCHAR name_Name[] = {'N','a','m','e',0};
228 BSTR names[3];
229 UINT n;
230 LCID en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
231 SORT_DEFAULT);
232 DISPPARAMS dispparams;
233 VARIANT varresult;
235 pOleCreateFontIndirect(NULL, &IID_IFontDisp, &pvObj);
236 fontdisp = pvObj;
238 hres = IFontDisp_GetTypeInfo(fontdisp, 0, en_us, &pTInfo);
239 ok(hres == S_OK, "GTI returned 0x%08x instead of S_OK.\n", hres);
240 ok(pTInfo != NULL, "GTI returned NULL.\n");
242 hres = ITypeInfo_GetNames(pTInfo, DISPID_FONT_NAME, names, 3, &n);
243 ok(hres == S_OK, "GetNames returned 0x%08x instead of S_OK.\n", hres);
244 ok(n == 1, "GetNames returned %d names instead of 1.\n", n);
245 ok(!lstrcmpiW(names[0],name_Name), "DISPID_FONT_NAME doesn't get 'Names'.\n");
246 SysFreeString(names[0]);
248 ITypeInfo_Release(pTInfo);
250 dispparams.cNamedArgs = 0;
251 dispparams.rgdispidNamedArgs = NULL;
252 dispparams.cArgs = 0;
253 dispparams.rgvarg = NULL;
254 VariantInit(&varresult);
255 hres = IFontDisp_Invoke(fontdisp, DISPID_FONT_NAME, &IID_NULL,
256 LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult,
257 NULL, NULL);
258 ok(hres == S_OK, "IFontDisp_Invoke return 0x%08x instead of S_OK.\n", hres);
259 VariantClear(&varresult);
261 IFontDisp_Release(fontdisp);
264 static HRESULT WINAPI FontEventsDisp_QueryInterface(
265 IFontEventsDisp *iface,
266 /* [in] */ REFIID riid,
267 /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
269 if (IsEqualIID(riid, &IID_IFontEventsDisp) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
271 IFontEventsDisp_AddRef(iface);
272 *ppvObject = iface;
273 return S_OK;
275 else
277 *ppvObject = NULL;
278 return E_NOINTERFACE;
282 static ULONG WINAPI FontEventsDisp_AddRef(
283 IFontEventsDisp *iface)
285 return 2;
288 static ULONG WINAPI FontEventsDisp_Release(
289 IFontEventsDisp *iface)
291 return 1;
294 static int fonteventsdisp_invoke_called = 0;
296 static HRESULT WINAPI FontEventsDisp_Invoke(
297 IFontEventsDisp __RPC_FAR * iface,
298 /* [in] */ DISPID dispIdMember,
299 /* [in] */ REFIID riid,
300 /* [in] */ LCID lcid,
301 /* [in] */ WORD wFlags,
302 /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
303 /* [out] */ VARIANT __RPC_FAR *pVarResult,
304 /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
305 /* [out] */ UINT __RPC_FAR *puArgErr)
307 static const WCHAR wszBold[] = {'B','o','l','d',0};
308 ok(wFlags == INVOKE_FUNC, "invoke flags should have been INVOKE_FUNC instead of 0x%x\n", wFlags);
309 ok(dispIdMember == DISPID_FONT_CHANGED, "dispIdMember should have been DISPID_FONT_CHANGED instead of 0x%x\n", dispIdMember);
310 ok(pDispParams->cArgs == 1, "pDispParams->cArgs should have been 1 instead of %d\n", pDispParams->cArgs);
311 ok(V_VT(&pDispParams->rgvarg[0]) == VT_BSTR, "VT of first param should have been VT_BSTR instead of %d\n", V_VT(&pDispParams->rgvarg[0]));
312 ok(!lstrcmpW(V_BSTR(&pDispParams->rgvarg[0]), wszBold), "String in first param should have been \"Bold\"\n");
314 fonteventsdisp_invoke_called++;
315 return S_OK;
318 static IFontEventsDispVtbl FontEventsDisp_Vtbl =
320 FontEventsDisp_QueryInterface,
321 FontEventsDisp_AddRef,
322 FontEventsDisp_Release,
323 NULL,
324 NULL,
325 NULL,
326 FontEventsDisp_Invoke
329 static IFontEventsDisp FontEventsDisp = { &FontEventsDisp_Vtbl };
331 static void test_font_events_disp(void)
333 IFont *pFont;
334 IFont *pFont2;
335 IConnectionPointContainer *pCPC;
336 IConnectionPoint *pCP;
337 FONTDESC fontdesc;
338 HRESULT hr;
339 DWORD dwCookie;
340 IFontDisp *pFontDisp;
341 DISPPARAMS dispparams;
342 VARIANTARG vararg;
344 fontdesc.cbSizeofstruct = sizeof(fontdesc);
345 fontdesc.lpstrName = MSSansSerif_font;
346 fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
347 fontdesc.sWeight = FW_NORMAL;
348 fontdesc.sCharset = 0;
349 fontdesc.fItalic = FALSE;
350 fontdesc.fUnderline = FALSE;
351 fontdesc.fStrikethrough = FALSE;
353 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont);
354 EXPECT_HR(hr, S_OK);
356 hr = IFont_QueryInterface(pFont, &IID_IConnectionPointContainer, (void **)&pCPC);
357 EXPECT_HR(hr, S_OK);
359 hr = IConnectionPointContainer_FindConnectionPoint(pCPC, &IID_IFontEventsDisp, &pCP);
360 EXPECT_HR(hr, S_OK);
361 IConnectionPointContainer_Release(pCPC);
363 hr = IConnectionPoint_Advise(pCP, (IUnknown *)&FontEventsDisp, &dwCookie);
364 EXPECT_HR(hr, S_OK);
365 IConnectionPoint_Release(pCP);
367 hr = IFont_put_Bold(pFont, TRUE);
368 EXPECT_HR(hr, S_OK);
370 ok(fonteventsdisp_invoke_called == 1, "IFontEventDisp::Invoke wasn't called once\n");
372 hr = IFont_QueryInterface(pFont, &IID_IFontDisp, (void **)&pFontDisp);
373 EXPECT_HR(hr, S_OK);
375 V_VT(&vararg) = VT_BOOL;
376 V_BOOL(&vararg) = VARIANT_FALSE;
377 dispparams.cNamedArgs = 0;
378 dispparams.rgdispidNamedArgs = NULL;
379 dispparams.cArgs = 1;
380 dispparams.rgvarg = &vararg;
381 hr = IFontDisp_Invoke(pFontDisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
382 EXPECT_HR(hr, S_OK);
384 IFontDisp_Release(pFontDisp);
386 ok(fonteventsdisp_invoke_called == 2, "IFontEventDisp::Invoke was called %d times instead of twice\n",
387 fonteventsdisp_invoke_called);
389 hr = IFont_Clone(pFont, &pFont2);
390 EXPECT_HR(hr, S_OK);
391 IFont_Release(pFont);
393 hr = IFont_put_Bold(pFont2, FALSE);
394 EXPECT_HR(hr, S_OK);
396 /* this test shows that the notification routine isn't called again */
397 ok(fonteventsdisp_invoke_called == 2, "IFontEventDisp::Invoke was called %d times instead of twice\n",
398 fonteventsdisp_invoke_called);
400 IFont_Release(pFont2);
403 static void test_names_ids(WCHAR* w_name_1, const char* a_name_1,
404 WCHAR* w_name_2, const char* a_name_2,
405 LCID lcid, DISPID id_1, DISPID id_2,
406 HRESULT hres_expect, int numnames)
408 LPVOID pvObj = NULL;
409 IFontDisp *fontdisp = NULL;
410 HRESULT hres;
411 DISPID rgDispId[2] = {0xdeadbeef, 0xdeadbeef};
412 LPOLESTR names[2] = {w_name_1, w_name_2};
414 pOleCreateFontIndirect(NULL, &IID_IFontDisp, &pvObj);
415 fontdisp = pvObj;
417 hres = IFontDisp_GetIDsOfNames(fontdisp, &IID_NULL, names, numnames,
418 lcid, rgDispId);
420 /* test hres */
421 ok(hres == hres_expect,
422 "GetIDsOfNames: \"%s\", \"%s\" returns 0x%08x, expected 0x%08x.\n",
423 a_name_1, a_name_2, hres, hres_expect);
425 /* test first DISPID */
426 ok(rgDispId[0]==id_1,
427 "GetIDsOfNames: \"%s\" gets DISPID 0x%08x, expected 0x%08x.\n",
428 a_name_1, rgDispId[0], id_1);
430 /* test second DISPID is present */
431 if (numnames == 2)
433 ok(rgDispId[1]==id_2,
434 "GetIDsOfNames: ..., \"%s\" gets DISPID 0x%08x, expected 0x%08x.\n",
435 a_name_2, rgDispId[1], id_2);
438 IFontDisp_Release(fontdisp);
441 static void test_GetIDsOfNames(void)
443 WCHAR name_Name[] = {'N','a','m','e',0};
444 WCHAR name_Italic[] = {'I','t','a','l','i','c',0};
445 WCHAR name_Size[] = {'S','i','z','e',0};
446 WCHAR name_Bold[] = {'B','o','l','d',0};
447 WCHAR name_Underline[] = {'U','n','d','e','r','l','i','n','e',0};
448 WCHAR name_Strikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
449 WCHAR name_Weight[] = {'W','e','i','g','h','t',0};
450 WCHAR name_Charset[] = {'C','h','a','r','s','e','t',0};
451 WCHAR name_Foo[] = {'F','o','o',0};
452 WCHAR name_nAmE[] = {'n','A','m','E',0};
453 WCHAR name_Nom[] = {'N','o','m',0};
455 LCID en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
456 SORT_DEFAULT);
457 LCID fr_fr = MAKELCID(MAKELANGID(LANG_FRENCH,SUBLANG_FRENCH),
458 SORT_DEFAULT);
460 /* Test DISPID_FONTs for the various properties. */
461 test_names_ids(name_Name, "Name", NULL, "", en_us,
462 DISPID_FONT_NAME, 0, S_OK,1);
463 test_names_ids(name_Size, "Size", NULL, "", en_us,
464 DISPID_FONT_SIZE, 0, S_OK,1);
465 test_names_ids(name_Bold, "Bold", NULL, "", en_us,
466 DISPID_FONT_BOLD, 0, S_OK,1);
467 test_names_ids(name_Italic, "Italic", NULL, "", en_us,
468 DISPID_FONT_ITALIC, 0, S_OK,1);
469 test_names_ids(name_Underline, "Underline", NULL, "", en_us,
470 DISPID_FONT_UNDER, 0, S_OK,1);
471 test_names_ids(name_Strikethrough, "Strikethrough", NULL, "", en_us,
472 DISPID_FONT_STRIKE, 0, S_OK,1);
473 test_names_ids(name_Weight, "Weight", NULL, "", en_us,
474 DISPID_FONT_WEIGHT, 0, S_OK,1);
475 test_names_ids(name_Charset, "Charset", NULL, "", en_us,
476 DISPID_FONT_CHARSET, 0, S_OK,1);
478 /* Capitalization doesn't matter. */
479 test_names_ids(name_nAmE, "nAmE", NULL, "", en_us,
480 DISPID_FONT_NAME, 0, S_OK,1);
482 /* Unknown name. */
483 test_names_ids(name_Foo, "Foo", NULL, "", en_us,
484 DISPID_UNKNOWN, 0, DISP_E_UNKNOWNNAME,1);
486 /* Pass several names: first is processed, */
487 /* second gets DISPID_UNKNOWN and doesn't affect retval. */
488 test_names_ids(name_Italic, "Italic", name_Name, "Name", en_us,
489 DISPID_FONT_ITALIC, DISPID_UNKNOWN, S_OK,2);
490 test_names_ids(name_Italic, "Italic", name_Foo, "Foo", en_us,
491 DISPID_FONT_ITALIC, DISPID_UNKNOWN, S_OK,2);
493 /* Locale ID has no effect. */
494 test_names_ids(name_Name, "Name", NULL, "", fr_fr,
495 DISPID_FONT_NAME, 0, S_OK,1);
496 test_names_ids(name_Nom, "This is not a font", NULL, "", fr_fr,
497 DISPID_UNKNOWN, 0, DISP_E_UNKNOWNNAME,1);
499 /* One of the arguments are invalid */
500 test_names_ids(name_Name, "Name", NULL, "", en_us,
501 0xdeadbeef, 0xdeadbeef, E_INVALIDARG,0);
502 test_names_ids(name_Italic, "Italic", NULL, "", en_us,
503 0xdeadbeef, 0xdeadbeef, E_INVALIDARG,0);
504 test_names_ids(name_Foo, "Foo", NULL, "", en_us,
505 0xdeadbeef, 0xdeadbeef, E_INVALIDARG,0);
507 /* Crazy locale ID? */
508 test_names_ids(name_Name, "Name", NULL, "", -1,
509 DISPID_FONT_NAME, 0, S_OK,1);
512 static void test_Invoke(void)
514 IFontDisp *fontdisp;
515 HRESULT hr;
516 VARIANTARG vararg;
517 DISPPARAMS dispparams;
518 VARIANT varresult;
520 hr = pOleCreateFontIndirect(NULL, &IID_IFontDisp, (void **)&fontdisp);
521 EXPECT_HR(hr, S_OK);
523 V_VT(&vararg) = VT_BOOL;
524 V_BOOL(&vararg) = VARIANT_FALSE;
525 dispparams.cNamedArgs = 0;
526 dispparams.rgdispidNamedArgs = NULL;
527 dispparams.cArgs = 1;
528 dispparams.rgvarg = &vararg;
529 hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_IFontDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
530 EXPECT_HR(hr, DISP_E_UNKNOWNINTERFACE);
532 dispparams.cArgs = 0;
533 dispparams.rgvarg = NULL;
534 hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
535 EXPECT_HR(hr, DISP_E_BADPARAMCOUNT);
537 hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
538 EXPECT_HR(hr, DISP_E_PARAMNOTOPTIONAL);
540 hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
541 EXPECT_HR(hr, DISP_E_PARAMNOTOPTIONAL);
543 hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
544 EXPECT_HR(hr, S_OK);
546 hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_METHOD, NULL, &varresult, NULL, NULL);
547 EXPECT_HR(hr, DISP_E_MEMBERNOTFOUND);
549 hr = IFontDisp_Invoke(fontdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
550 EXPECT_HR(hr, DISP_E_MEMBERNOTFOUND);
552 dispparams.cArgs = 1;
553 dispparams.rgvarg = &vararg;
554 hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
555 EXPECT_HR(hr, S_OK);
557 IFontDisp_Release(fontdisp);
560 static void test_IsEqual(void)
562 FONTDESC fd;
563 IFont* ifnt = NULL;
564 IFont* ifnt2 = NULL;
565 HRESULT hres;
567 /* Basic font description */
568 fd.cbSizeofstruct = sizeof(FONTDESC);
569 fd.lpstrName = system_font;
570 S(fd.cySize).Lo = 100;
571 S(fd.cySize).Hi = 100;
572 fd.sWeight = 0;
573 fd.sCharset = 0;
574 fd.fItalic = FALSE;
575 fd.fUnderline = FALSE;
576 fd.fStrikethrough = FALSE;
578 /* Create font */
579 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt);
581 /* Test equal fonts */
582 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
583 hres = IFont_IsEqual(ifnt,ifnt2);
584 ok(hres == S_OK,
585 "IFont_IsEqual: (EQUAL) Expected S_OK but got 0x%08x\n",hres);
586 IFont_Release(ifnt2);
588 /* Check for bad pointer */
589 hres = IFont_IsEqual(ifnt,NULL);
590 ok(hres == E_POINTER,
591 "IFont_IsEqual: (NULL) Expected 0x80004003 but got 0x%08x\n",hres);
593 /* Test strName */
594 fd.lpstrName = arial_font;
595 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
596 hres = IFont_IsEqual(ifnt,ifnt2);
597 ok(hres == S_FALSE,
598 "IFont_IsEqual: (strName) Expected S_FALSE but got 0x%08x\n",hres);
599 fd.lpstrName = system_font;
600 IFont_Release(ifnt2);
602 /* Test lo font size */
603 S(fd.cySize).Lo = 10000;
604 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
605 hres = IFont_IsEqual(ifnt,ifnt2);
606 ok(hres == S_FALSE,
607 "IFont_IsEqual: (Lo font size) Expected S_FALSE but got 0x%08x\n",hres);
608 S(fd.cySize).Lo = 100;
609 IFont_Release(ifnt2);
611 /* Test hi font size */
612 S(fd.cySize).Hi = 10000;
613 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
614 hres = IFont_IsEqual(ifnt,ifnt2);
615 ok(hres == S_FALSE,
616 "IFont_IsEqual: (Hi font size) Expected S_FALSE but got 0x%08x\n",hres);
617 S(fd.cySize).Hi = 100;
618 IFont_Release(ifnt2);
620 /* Test font weight */
621 fd.sWeight = 100;
622 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
623 hres = IFont_IsEqual(ifnt,ifnt2);
624 ok(hres == S_FALSE,
625 "IFont_IsEqual: (Weight) Expected S_FALSE but got 0x%08x\n",hres);
626 fd.sWeight = 0;
627 IFont_Release(ifnt2);
629 /* Test charset */
630 fd.sCharset = 1;
631 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
632 hres = IFont_IsEqual(ifnt,ifnt2);
633 ok(hres == S_FALSE,
634 "IFont_IsEqual: (Charset) Expected S_FALSE but got 0x%08x\n",hres);
635 fd.sCharset = 0;
636 IFont_Release(ifnt2);
638 /* Test italic setting */
639 fd.fItalic = TRUE;
640 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
641 hres = IFont_IsEqual(ifnt,ifnt2);
642 ok(hres == S_FALSE,
643 "IFont_IsEqual: (Italic) Expected S_FALSE but got 0x%08x\n",hres);
644 fd.fItalic = FALSE;
645 IFont_Release(ifnt2);
647 /* Test underline setting */
648 fd.fUnderline = TRUE;
649 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
650 hres = IFont_IsEqual(ifnt,ifnt2);
651 ok(hres == S_FALSE,
652 "IFont_IsEqual: (Underline) Expected S_FALSE but got 0x%08x\n",hres);
653 fd.fUnderline = FALSE;
654 IFont_Release(ifnt2);
656 /* Test strikethrough setting */
657 fd.fStrikethrough = TRUE;
658 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
659 hres = IFont_IsEqual(ifnt,ifnt2);
660 ok(hres == S_FALSE,
661 "IFont_IsEqual: (Strikethrough) Expected S_FALSE but got 0x%08x\n",hres);
662 fd.fStrikethrough = FALSE;
663 IFont_Release(ifnt2);
665 /* Free IFont. */
666 IFont_Release(ifnt);
669 static void test_ReleaseHfont(void)
671 FONTDESC fd;
672 LPVOID pvObj1 = NULL;
673 LPVOID pvObj2 = NULL;
674 IFont* ifnt1 = NULL;
675 IFont* ifnt2 = NULL;
676 HFONT hfnt1 = 0;
677 HFONT hfnt2 = 0;
678 HRESULT hres;
680 /* Basic font description */
681 fd.cbSizeofstruct = sizeof(FONTDESC);
682 fd.lpstrName = system_font;
683 S(fd.cySize).Lo = 100;
684 S(fd.cySize).Hi = 100;
685 fd.sWeight = 0;
686 fd.sCharset = 0;
687 fd.fItalic = FALSE;
688 fd.fUnderline = FALSE;
689 fd.fStrikethrough = FALSE;
691 /* Create HFONTs and IFONTs */
692 pOleCreateFontIndirect(&fd, &IID_IFont, &pvObj1);
693 ifnt1 = pvObj1;
694 IFont_get_hFont(ifnt1,&hfnt1);
695 fd.lpstrName = arial_font;
696 pOleCreateFontIndirect(&fd, &IID_IFont, &pvObj2);
697 ifnt2 = pvObj2;
698 IFont_get_hFont(ifnt2,&hfnt2);
700 /* Try invalid HFONT */
701 hres = IFont_ReleaseHfont(ifnt1,NULL);
702 ok(hres == E_INVALIDARG,
703 "IFont_ReleaseHfont: (Bad HFONT) Expected E_INVALIDARG but got 0x%08x\n",
704 hres);
706 /* Try to add a bad HFONT */
707 hres = IFont_ReleaseHfont(ifnt1,(HFONT)32);
708 ok(hres == S_FALSE,
709 "IFont_ReleaseHfont: (Bad HFONT) Expected S_FALSE but got 0x%08x\n",
710 hres);
712 /* Release all refs */
713 hres = IFont_ReleaseHfont(ifnt1,hfnt1);
714 ok(hres == S_OK,
715 "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
716 hres);
718 hres = IFont_ReleaseHfont(ifnt2,hfnt2);
719 ok(hres == S_OK,
720 "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
721 hres);
723 /* Check that both lists are empty */
724 hres = IFont_ReleaseHfont(ifnt1,hfnt1);
725 ok(hres == S_FALSE,
726 "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
727 hres);
729 /* The list should be empty */
730 hres = IFont_ReleaseHfont(ifnt2,hfnt2);
731 ok(hres == S_FALSE,
732 "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
733 hres);
735 IFont_Release(ifnt1);
736 IFont_Release(ifnt2);
739 static void test_AddRefHfont(void)
741 FONTDESC fd;
742 IFont* ifnt1 = NULL;
743 IFont* ifnt2 = NULL;
744 IFont* ifnt3 = NULL;
745 HFONT hfnt1 = 0;
746 HFONT hfnt2 = 0;
747 HFONT hfnt3 = 0;
748 HRESULT hres;
750 /* Basic font description */
751 fd.cbSizeofstruct = sizeof(FONTDESC);
752 fd.lpstrName = system_font;
753 S(fd.cySize).Lo = 100;
754 S(fd.cySize).Hi = 100;
755 fd.sWeight = 0;
756 fd.sCharset = 0;
757 fd.fItalic = FALSE;
758 fd.fUnderline = FALSE;
759 fd.fStrikethrough = FALSE;
761 /* Create HFONTs and IFONTs */
762 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt1);
763 IFont_get_hFont(ifnt1,&hfnt1);
764 fd.lpstrName = arial_font;
765 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
766 IFont_get_hFont(ifnt2,&hfnt2);
768 /* Try invalid HFONT */
769 hres = IFont_AddRefHfont(ifnt1,NULL);
770 ok(hres == E_INVALIDARG,
771 "IFont_AddRefHfont: (Bad HFONT) Expected E_INVALIDARG but got 0x%08x\n",
772 hres);
774 /* Try to add a bad HFONT */
775 hres = IFont_AddRefHfont(ifnt1,(HFONT)32);
776 ok(hres == S_FALSE,
777 "IFont_AddRefHfont: (Bad HFONT) Expected S_FALSE but got 0x%08x\n",
778 hres);
780 /* Add simple IFONT HFONT pair */
781 hres = IFont_AddRefHfont(ifnt1,hfnt1);
782 ok(hres == S_OK,
783 "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
784 hres);
786 /* IFONT and HFONT do not have to be the same (always looks at HFONT) */
787 hres = IFont_AddRefHfont(ifnt2,hfnt1);
788 ok(hres == S_OK,
789 "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
790 hres);
792 /* Release all hfnt1 refs */
793 hres = IFont_ReleaseHfont(ifnt1,hfnt1);
794 ok(hres == S_OK,
795 "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
796 hres);
798 hres = IFont_ReleaseHfont(ifnt1,hfnt1);
799 ok(hres == S_OK,
800 "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
801 hres);
803 hres = IFont_ReleaseHfont(ifnt1,hfnt1);
804 ok(hres == S_OK,
805 "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
806 hres);
808 /* Check if hfnt1 is empty */
809 hres = IFont_ReleaseHfont(ifnt1,hfnt1);
810 ok(hres == S_FALSE,
811 "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
812 hres);
814 /* Release all hfnt2 refs */
815 hres = IFont_ReleaseHfont(ifnt2,hfnt2);
816 ok(hres == S_OK,
817 "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
818 hres);
820 /* Check if hfnt2 is empty */
821 hres = IFont_ReleaseHfont(ifnt2,hfnt2);
822 ok(hres == S_FALSE,
823 "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
824 hres);
826 /* Show that releasing an IFONT does not always release it from the HFONT cache. */
828 IFont_Release(ifnt1);
830 /* Add a reference for destroyed hfnt1 */
831 hres = IFont_AddRefHfont(ifnt2,hfnt1);
832 ok(hres == S_OK,
833 "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
834 hres);
836 /* Decrement reference for destroyed hfnt1 */
837 hres = IFont_ReleaseHfont(ifnt2,hfnt1);
838 ok(hres == S_OK ||
839 hres == S_FALSE, /* <= win2k */
840 "IFont_AddRefHfont: (Release ref) Expected S_OK or S_FALSE but got 0x%08x\n",
841 hres);
843 /* Shows that releasing all IFONT's does clear the HFONT cache. */
845 IFont_Release(ifnt2);
847 /* Need to make a new IFONT for testing */
848 fd.fUnderline = TRUE;
849 pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt3);
850 IFont_get_hFont(ifnt3,&hfnt3);
852 /* Add a reference for destroyed hfnt1 */
853 hres = IFont_AddRefHfont(ifnt3,hfnt1);
854 ok(hres == S_FALSE,
855 "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
856 hres);
858 /* Decrement reference for destroyed hfnt1 */
859 hres = IFont_ReleaseHfont(ifnt3,hfnt1);
860 ok(hres == S_FALSE,
861 "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
862 hres);
864 IFont_Release(ifnt3);
867 static void test_returns(void)
869 IFont *pFont;
870 FONTDESC fontdesc;
871 HRESULT hr;
873 fontdesc.cbSizeofstruct = sizeof(fontdesc);
874 fontdesc.lpstrName = MSSansSerif_font;
875 fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
876 fontdesc.sWeight = FW_NORMAL;
877 fontdesc.sCharset = 0;
878 fontdesc.fItalic = FALSE;
879 fontdesc.fUnderline = FALSE;
880 fontdesc.fStrikethrough = FALSE;
882 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont);
883 EXPECT_HR(hr, S_OK);
885 hr = IFont_put_Name(pFont, NULL);
886 EXPECT_HR(hr, CTL_E_INVALIDPROPERTYVALUE);
888 hr = IFont_get_Name(pFont, NULL);
889 EXPECT_HR(hr, E_POINTER);
891 hr = IFont_get_Size(pFont, NULL);
892 EXPECT_HR(hr, E_POINTER);
894 hr = IFont_get_Bold(pFont, NULL);
895 EXPECT_HR(hr, E_POINTER);
897 IFont_Release(pFont);
900 static void test_hfont_lifetime(void)
902 IFont *font, *font2;
903 FONTDESC fontdesc;
904 HRESULT hr;
905 HFONT hfont, first_hfont = NULL;
906 CY size;
907 DWORD obj_type;
908 int i;
910 fontdesc.cbSizeofstruct = sizeof(fontdesc);
911 fontdesc.lpstrName = arial_font;
912 fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
913 fontdesc.sWeight = FW_NORMAL;
914 fontdesc.sCharset = ANSI_CHARSET;
915 fontdesc.fItalic = FALSE;
916 fontdesc.fUnderline = FALSE;
917 fontdesc.fStrikethrough = FALSE;
919 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
920 EXPECT_HR(hr, S_OK);
922 hr = IFont_get_hFont(font, &hfont);
923 EXPECT_HR(hr, S_OK);
925 /* show that if the font is updated the old hfont is deleted when the
926 new font is realized */
927 for(i = 0; i < 100; i++)
929 HFONT last_hfont = hfont;
931 size.int64 = (i + 10) * 20000;
933 obj_type = GetObjectType(hfont);
934 ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
936 hr = IFont_put_Size(font, size);
937 EXPECT_HR(hr, S_OK);
939 /* put_Size doesn't cause the new font to be realized */
940 obj_type = GetObjectType(last_hfont);
941 ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
943 hr = IFont_get_hFont(font, &hfont);
944 EXPECT_HR(hr, S_OK);
946 obj_type = GetObjectType(last_hfont);
947 ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type);
950 /* now show that if we take a reference on the hfont, it persists
951 until the font object is released */
952 for(i = 0; i < 100; i++)
954 size.int64 = (i + 10) * 20000;
956 obj_type = GetObjectType(hfont);
957 ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
959 hr = IFont_put_Size(font, size);
960 EXPECT_HR(hr, S_OK);
962 hr = IFont_get_hFont(font, &hfont);
963 EXPECT_HR(hr, S_OK);
965 hr = IFont_AddRefHfont(font, hfont);
966 EXPECT_HR(hr, S_OK);
968 if(i == 0) first_hfont = hfont;
969 obj_type = GetObjectType(first_hfont);
970 ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
973 IFont_Release(font);
975 obj_type = GetObjectType(first_hfont);
976 ok(obj_type == 0, "got obj type %d\n", obj_type);
978 /* An AddRefHfont followed by a ReleaseHfont means the font doesn't not persist
979 through re-realization */
981 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
982 EXPECT_HR(hr, S_OK);
984 hr = IFont_get_hFont(font, &hfont);
985 EXPECT_HR(hr, S_OK);
987 for(i = 0; i < 100; i++)
989 HFONT last_hfont = hfont;
991 size.int64 = (i + 10) * 20000;
993 obj_type = GetObjectType(hfont);
994 ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
996 hr = IFont_put_Size(font, size);
997 EXPECT_HR(hr, S_OK);
999 /* put_Size doesn't cause the new font to be realized */
1000 obj_type = GetObjectType(last_hfont);
1001 ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1003 hr = IFont_get_hFont(font, &hfont);
1004 EXPECT_HR(hr, S_OK);
1006 hr = IFont_AddRefHfont(font, hfont);
1007 EXPECT_HR(hr, S_OK);
1009 hr = IFont_ReleaseHfont(font, hfont);
1010 EXPECT_HR(hr, S_OK);
1012 obj_type = GetObjectType(last_hfont);
1013 ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type);
1016 /* Interestingly if we release a nonexistent reference on the hfont,
1017 * it persists until the font object is released
1019 for(i = 0; i < 100; i++)
1021 size.int64 = (i + 10) * 20000;
1023 obj_type = GetObjectType(hfont);
1024 ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1026 hr = IFont_put_Size(font, size);
1027 EXPECT_HR(hr, S_OK);
1029 hr = IFont_get_hFont(font, &hfont);
1030 EXPECT_HR(hr, S_OK);
1032 hr = IFont_ReleaseHfont(font, hfont);
1033 EXPECT_HR(hr, S_OK);
1035 if(i == 0) first_hfont = hfont;
1036 obj_type = GetObjectType(first_hfont);
1037 ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1040 IFont_Release(font);
1042 obj_type = GetObjectType(first_hfont);
1043 ok(obj_type == 0, "got obj type %d\n", obj_type);
1045 /* If we take two internal references on a hfont then we can release
1046 it twice. So it looks like there's a total reference count
1047 that includes internal and external references */
1049 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
1050 EXPECT_HR(hr, S_OK);
1051 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font2);
1052 EXPECT_HR(hr, S_OK);
1054 hr = IFont_get_hFont(font, &hfont);
1055 EXPECT_HR(hr, S_OK);
1056 hr = IFont_get_hFont(font2, &first_hfont);
1057 EXPECT_HR(hr, S_OK);
1058 todo_wine
1059 ok(hfont == first_hfont, "fonts differ\n");
1060 hr = IFont_ReleaseHfont(font, hfont);
1061 EXPECT_HR(hr, S_OK);
1062 hr = IFont_ReleaseHfont(font, hfont);
1063 todo_wine
1064 EXPECT_HR(hr, S_OK);
1065 hr = IFont_ReleaseHfont(font, hfont);
1066 EXPECT_HR(hr, S_FALSE);
1068 obj_type = GetObjectType(hfont);
1069 ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1071 IFont_Release(font);
1073 obj_type = GetObjectType(hfont);
1074 ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1076 IFont_Release(font2);
1078 obj_type = GetObjectType(hfont);
1079 ok(obj_type == 0, "got obj type %d\n", obj_type);
1082 static void test_realization(void)
1084 IFont *font;
1085 FONTDESC fontdesc;
1086 HRESULT hr;
1087 BSTR name;
1088 SHORT cs;
1090 /* Try to create a symbol only font (marlett) with charset
1091 set to ANSI. This will result in another, ANSI, font
1092 being selected */
1093 fontdesc.cbSizeofstruct = sizeof(fontdesc);
1094 fontdesc.lpstrName = marlett_font;
1095 fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
1096 fontdesc.sWeight = FW_NORMAL;
1097 fontdesc.sCharset = ANSI_CHARSET;
1098 fontdesc.fItalic = FALSE;
1099 fontdesc.fUnderline = FALSE;
1100 fontdesc.fStrikethrough = FALSE;
1102 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
1103 EXPECT_HR(hr, S_OK);
1105 hr = IFont_get_Charset(font, &cs);
1106 EXPECT_HR(hr, S_OK);
1107 ok(cs == ANSI_CHARSET, "got charset %d\n", cs);
1109 IFont_Release(font);
1111 /* Now create an ANSI font and change the name to marlett */
1113 fontdesc.lpstrName = arial_font;
1115 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
1116 EXPECT_HR(hr, S_OK);
1118 hr = IFont_get_Charset(font, &cs);
1119 EXPECT_HR(hr, S_OK);
1120 ok(cs == ANSI_CHARSET, "got charset %d\n", cs);
1122 name = SysAllocString(marlett_font);
1123 hr = IFont_put_Name(font, name);
1124 EXPECT_HR(hr, S_OK);
1125 SysFreeString(name);
1127 hr = IFont_get_Name(font, &name);
1128 EXPECT_HR(hr, S_OK);
1129 ok(!lstrcmpiW(name, marlett_font), "got name %s\n", wine_dbgstr_w(name));
1130 SysFreeString(name);
1132 hr = IFont_get_Charset(font, &cs);
1133 EXPECT_HR(hr, S_OK);
1134 ok(cs == SYMBOL_CHARSET, "got charset %d\n", cs);
1136 IFont_Release(font);
1139 static void test_OleCreateFontIndirect(void)
1141 FONTDESC fontdesc;
1142 IFont *font;
1143 HRESULT hr;
1145 fontdesc.cbSizeofstruct = sizeof(fontdesc);
1146 fontdesc.lpstrName = arial_font;
1147 fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
1148 fontdesc.sWeight = FW_NORMAL;
1149 fontdesc.sCharset = ANSI_CHARSET;
1150 fontdesc.fItalic = FALSE;
1151 fontdesc.fUnderline = FALSE;
1152 fontdesc.fStrikethrough = FALSE;
1154 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
1155 EXPECT_HR(hr, S_OK);
1156 IFont_Release(font);
1158 /* play with cbSizeofstruct value */
1159 fontdesc.cbSizeofstruct = sizeof(fontdesc)-1;
1160 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
1161 EXPECT_HR(hr, S_OK);
1162 IFont_Release(font);
1164 fontdesc.cbSizeofstruct = sizeof(fontdesc)+1;
1165 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
1166 EXPECT_HR(hr, S_OK);
1167 IFont_Release(font);
1169 fontdesc.cbSizeofstruct = 0;
1170 hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
1171 EXPECT_HR(hr, S_OK);
1172 IFont_Release(font);
1175 START_TEST(olefont)
1177 hOleaut32 = GetModuleHandleA("oleaut32.dll");
1178 pOleCreateFontIndirect = (void*)GetProcAddress(hOleaut32, "OleCreateFontIndirect");
1179 if (!pOleCreateFontIndirect)
1181 win_skip("OleCreateFontIndirect not available\n");
1182 return;
1185 test_QueryInterface();
1186 test_type_info();
1187 test_ifont_sizes();
1188 test_font_events_disp();
1189 test_GetIDsOfNames();
1190 test_Invoke();
1191 test_IsEqual();
1192 test_ReleaseHfont();
1193 test_AddRefHfont();
1194 test_returns();
1195 test_hfont_lifetime();
1196 test_realization();
1197 test_OleCreateFontIndirect();