ReactOS  0.4.14-dev-342-gdc047f9
olefont.c
Go to the documentation of this file.
1 /*
2  * OLEFONT test program
3  *
4  * Copyright 2003 Marcus Meissner
5  * Copyright 2006 (Google) Benjamin Arai
6  *
7  *
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.
12  *
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.
17  *
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
21  */
22 
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <math.h>
26 #include <float.h>
27 
28 #define COBJMACROS
29 
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>
42 
43 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
44 
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 };
49 
51 
52 static HRESULT (WINAPI *pOleCreateFontIndirect)(LPFONTDESC,REFIID,LPVOID*);
53 
54 #define EXPECT_HR(hr,hr_exp) \
55  ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
56 
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(LONGLONG size, LONG ratio_logical, LONG ratio_himetric,
62  LONG hfont_height, const char * test_name)
63 {
64  FONTDESC fd;
65  LPVOID pvObj = NULL;
66  IFont* ifnt = NULL;
67  HFONT hfont;
68  LOGFONTA lf;
69  CY psize;
70  HRESULT hres;
71  DWORD rtnval;
72 
73  fd.cbSizeofstruct = sizeof(FONTDESC);
74  fd.lpstrName = arial_font; /* using scalable instead of bitmap font reduces errors due to font realization */
75  fd.cySize.int64 = size;
76  fd.sWeight = 0;
77  fd.sCharset = 0;
78  fd.fItalic = FALSE;
79  fd.fUnderline = FALSE;
80  fd.fStrikethrough = FALSE;
81 
82  /* Create font, test that it worked. */
83  hres = pOleCreateFontIndirect(&fd, &IID_IFont, &pvObj);
84  ifnt = pvObj;
85  ok(hres == S_OK,"%s: OCFI returns 0x%08x instead of S_OK.\n",
86  test_name, hres);
87  ok(pvObj != NULL,"%s: OCFI returns NULL.\n", test_name);
88 
89  /* Change the scaling ratio */
90  hres = IFont_SetRatio(ifnt, ratio_logical, ratio_himetric);
91  ok((ratio_logical && ratio_himetric) ? hres == S_OK : hres == E_FAIL,
92  "%s: IFont_SetRatio unexpectedly returned 0x%08x.\n", test_name, hres);
93 
94  /* Read back size. */
95  hres = IFont_get_Size(ifnt, &psize);
96  ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n",
97  test_name, hres);
98 
99  /* Check returned size - allow for errors due to rounding & font realization. */
100  ok((psize.int64 - size) < 10000 && (psize.int64 - size) > -10000,
101  "%s: IFont_get_Size: Lo=%d, Hi=%d; expected Lo=%d, Hi=%d.\n",
102  test_name, S(psize).Lo, S(psize).Hi, fd.cySize.Lo, fd.cySize.Hi);
103 
104  /* Check hFont size. */
105  hres = IFont_get_hFont (ifnt, &hfont);
106  ok(hres == S_OK, "%s: IFont_get_hFont returns 0x%08x instead of S_OK.\n",
107  test_name, hres);
108  rtnval = GetObjectA(hfont, sizeof(LOGFONTA), &lf);
109  ok(rtnval > 0, "GetObject(hfont) failed\n");
110 
111  /* Since font scaling may encounter rounding errors, allow 1 pixel deviation. */
112  ok(abs(lf.lfHeight - hfont_height) <= 1,
113  "%s: hFont has lf.lfHeight=%d, expected %d.\n",
114  test_name, lf.lfHeight, hfont_height);
115 
116  /* Free IFont. */
117  IFont_Release(ifnt);
118 }
119 
120 static void test_ifont_sizes(void)
121 {
122  /* Test various size operations and conversions. */
123  /* Add more as needed. */
124 
125  /* Results of first 2 tests depend on display resolution. */
126  HDC hdc = GetDC(0);
127  LONG dpi = GetDeviceCaps(hdc, LOGPIXELSY); /* expected results depend on display DPI */
128  ReleaseDC(0, hdc);
129  if(dpi == 96) /* normal resolution display */
130  {
131  test_ifont_size(180000, 0, 0, -24, "default"); /* normal font */
132  test_ifont_size(186000, 0, 0, -25, "rounding"); /* test rounding */
133  } else if(dpi == 72) /* low resolution display */
134  {
135  test_ifont_size(180000, 0, 0, -18, "default"); /* normal font */
136  test_ifont_size(186000, 0, 0, -19, "rounding"); /* test rounding */
137  } else if(dpi == 120) /* high resolution display */
138  {
139  test_ifont_size(180000, 0, 0, -30, "default"); /* normal font */
140  test_ifont_size(186000, 0, 0, -31, "rounding"); /* test rounding */
141  } else
142  skip("Skipping resolution dependent font size tests - display resolution is %d\n", dpi);
143 
144  /* Next 4 tests specify a scaling ratio, so display resolution is not a factor. */
145  test_ifont_size(180000, 72, 2540, -18, "ratio1"); /* change ratio */
146  test_ifont_size(180000, 144, 2540, -36, "ratio2"); /* another ratio */
147  test_ifont_size(180000, 72, 1270, -36, "ratio3"); /* yet another ratio */
148  test_ifont_size(186000, 72, 2540, -19, "rounding+ratio"); /* test rounding with ratio */
149 
150  /* test various combinations of logical == himetric */
151  test_ifont_size(180000, 10, 10, -635, "identical ratio 1");
152  test_ifont_size(240000, 10, 10, -848, "identical ratio 2");
153  test_ifont_size(300000, 10, 10, -1058, "identical ratio 3");
154 
155  /* test various combinations of logical and himetric both set to 1 */
156  test_ifont_size(180000, 1, 1, -24, "1:1 ratio 1");
157  test_ifont_size(240000, 1, 1, -32, "1:1 ratio 2");
158  test_ifont_size(300000, 1, 1, -40, "1:1 ratio 3");
159 
160  /* test various combinations of logical set to 1 */
161  test_ifont_size(180000, 1, 0, -24, "1:0 ratio 1");
162  test_ifont_size(240000, 1, 0, -32, "1:0 ratio 2");
163  test_ifont_size(300000, 1, 0, -40, "1:0 ratio 3");
164 
165  /* test various combinations of himetric set to 1 */
166  test_ifont_size(180000, 0, 1, -24, "0:1 ratio 1");
167  test_ifont_size(240000, 0, 1, -32, "0:1 ratio 2");
168  test_ifont_size(300000, 0, 1, -40, "0:1 ratio 3");
169 
170  /* test various combinations of 2:1 logical:himetric */
171  test_ifont_size(180000, 2, 1, -1270, "2:1 ratio 1");
172  test_ifont_size(240000, 2, 1, -1694, "2:1 ratio 2");
173  test_ifont_size(300000, 2, 1, -2117, "2:1 ratio 3");
174 
175  /* test various combinations of 1:2 logical:himetric */
176  test_ifont_size(180000, 1, 2, -318, "1:2 ratio 1");
177  test_ifont_size(240000, 1, 2, -424, "1:2 ratio 2");
178  test_ifont_size(300000, 1, 2, -529, "1:2 ratio 3");
179 
180  /* test various combinations of logical and himetric both set to 2 */
181  test_ifont_size(180000, 2, 2, -635, "2:2 ratio 1");
182  test_ifont_size(240000, 2, 2, -848, "2:2 ratio 2");
183  test_ifont_size(300000, 2, 2, -1058, "2:2 ratio 3");
184 }
185 
186 static void test_QueryInterface(void)
187 {
188  LPVOID pvObj = NULL;
189  HRESULT hr;
190  IFont* font = NULL;
191  LONG ref;
192 
193  hr = pOleCreateFontIndirect(NULL, &IID_IFont, NULL);
195 
196  hr = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj);
197  font = pvObj;
198 
199  EXPECT_HR(hr, S_OK);
200  ok(font != NULL,"OCFI (NULL,..) returns NULL, instead of !NULL\n");
201 
202  pvObj = NULL;
203  hr = IFont_QueryInterface( font, &IID_IFont, &pvObj);
204  EXPECT_HR(hr, S_OK);
205 
206  /* Test if QueryInterface increments ref counter for IFONTs */
207  ref = IFont_AddRef(font);
208  ok(ref == 3 ||
209  broken(ref == 1), /* win95 */
210  "IFont_QI expected ref value 3 but instead got %d\n", ref);
211  IFont_Release(font);
212 
213  ok(pvObj != NULL,"IFont_QI does return NULL, instead of a ptr\n");
214 
215  IFont_Release(font);
216  IFont_Release(font);
217 }
218 
219 static void test_type_info(void)
220 {
221  LPVOID pvObj = NULL;
222  HRESULT hres;
223  IFontDisp* fontdisp = NULL;
224  ITypeInfo* pTInfo;
225  WCHAR name_Name[] = {'N','a','m','e',0};
226  BSTR names[3];
227  UINT n;
229  SORT_DEFAULT);
230  DISPPARAMS dispparams;
231  VARIANT varresult;
232 
233  pOleCreateFontIndirect(NULL, &IID_IFontDisp, &pvObj);
234  fontdisp = pvObj;
235 
236  hres = IFontDisp_GetTypeInfo(fontdisp, 0, en_us, &pTInfo);
237  ok(hres == S_OK, "GTI returned 0x%08x instead of S_OK.\n", hres);
238  ok(pTInfo != NULL, "GTI returned NULL.\n");
239 
240  hres = ITypeInfo_GetNames(pTInfo, DISPID_FONT_NAME, names, 3, &n);
241  ok(hres == S_OK, "GetNames returned 0x%08x instead of S_OK.\n", hres);
242  ok(n == 1, "GetNames returned %d names instead of 1.\n", n);
243  ok(!lstrcmpiW(names[0],name_Name), "DISPID_FONT_NAME doesn't get 'Names'.\n");
244  SysFreeString(names[0]);
245 
246  ITypeInfo_Release(pTInfo);
247 
248  dispparams.cNamedArgs = 0;
249  dispparams.rgdispidNamedArgs = NULL;
250  dispparams.cArgs = 0;
251  dispparams.rgvarg = NULL;
252  VariantInit(&varresult);
253  hres = IFontDisp_Invoke(fontdisp, DISPID_FONT_NAME, &IID_NULL,
254  LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult,
255  NULL, NULL);
256  ok(hres == S_OK, "IFontDisp_Invoke return 0x%08x instead of S_OK.\n", hres);
257  VariantClear(&varresult);
258 
259  IFontDisp_Release(fontdisp);
260 }
261 
263 {
265  {
266  IFontEventsDisp_AddRef(iface);
267  *ppvObject = iface;
268  return S_OK;
269  }
270  else
271  {
272  *ppvObject = NULL;
273  return E_NOINTERFACE;
274  }
275 }
276 
278  IFontEventsDisp *iface)
279 {
280  return 2;
281 }
282 
284  IFontEventsDisp *iface)
285 {
286  return 1;
287 }
288 
290 {
291  ok(0, "unexpected call\n");
292  return E_NOTIMPL;
293 }
294 
296 {
297  ok(0, "unexpected call\n");
298  return E_NOTIMPL;
299 }
300 
302  DISPID *dispid)
303 {
304  ok(0, "unexpected call\n");
305  return E_NOTIMPL;
306 }
307 
310 
312  IFontEventsDisp *iface,
313  DISPID dispid,
314  REFIID riid,
315  LCID lcid,
316  WORD wFlags,
317  DISPPARAMS *pDispParams,
318  VARIANT *pVarResult,
319  EXCEPINFO *pExcepInfo,
320  UINT *puArgErr)
321 {
322  VARIANTARG *arg0 = &pDispParams->rgvarg[0];
323 
324  ok(dispid == DISPID_FONT_CHANGED, "expected DISPID_FONT_CHANGED instead of 0x%x\n", dispid);
325  ok(IsEqualGUID(riid, &GUID_NULL), "got riid %s\n", wine_dbgstr_guid(riid));
326  ok(wFlags == INVOKE_FUNC, "expected INVOKE_FUNC instead of 0x%x\n", wFlags);
327  ok(pDispParams->cArgs == 1, "expected arg count 1, got %d\n", pDispParams->cArgs);
328  ok(V_VT(arg0) == VT_BSTR, "expected VT_BSTR, got %d\n", V_VT(arg0));
329 
332  return S_OK;
333 }
334 
335 static IFontEventsDispVtbl FontEventsDisp_Vtbl =
336 {
344 };
345 
347 
348  struct font_dispid
349  {
351  const WCHAR *name;
352  };
353 
354 static void test_font_events_disp(void)
355 {
356  static const WCHAR nameW[] = {'N','a','m','e',0};
357  static const WCHAR sizeW[] = {'S','i','z','e',0};
358  static const WCHAR boldW[] = {'B','o','l','d',0};
359  static const WCHAR italicW[] = {'I','t','a','l','i','c',0};
360  static const WCHAR underlineW[] = {'U','n','d','e','r','l','i','n','e',0};
361  static const WCHAR strikeW[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
362  static const WCHAR weightW[] = {'W','e','i','g','h','t',0};
363  static const WCHAR charsetW[] = {'C','h','a','r','s','e','t',0};
364 
365  static const struct font_dispid font_dispids[] =
366  {
367  { DISPID_FONT_NAME, nameW },
368  { DISPID_FONT_SIZE, sizeW },
369  { DISPID_FONT_BOLD, boldW },
370  { DISPID_FONT_ITALIC, italicW },
371  { DISPID_FONT_UNDER, underlineW },
373  { DISPID_FONT_WEIGHT, weightW },
375  };
376 
377  IFont *pFont;
378  IFont *pFont2;
380  IConnectionPoint *pCP;
381  FONTDESC fontdesc;
382  HRESULT hr;
383  DWORD dwCookie;
384  IFontDisp *pFontDisp;
385  DISPPARAMS dispparams;
386  VARIANTARG vararg;
387  INT i;
388 
389  fontdesc.cbSizeofstruct = sizeof(fontdesc);
390  fontdesc.lpstrName = MSSansSerif_font;
391  fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
392  fontdesc.sWeight = FW_NORMAL;
393  fontdesc.sCharset = 0;
394  fontdesc.fItalic = FALSE;
395  fontdesc.fUnderline = FALSE;
396  fontdesc.fStrikethrough = FALSE;
397 
398  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont);
399  EXPECT_HR(hr, S_OK);
400 
401  hr = IFont_QueryInterface(pFont, &IID_IConnectionPointContainer, (void **)&pCPC);
402  EXPECT_HR(hr, S_OK);
403 
404  hr = IConnectionPointContainer_FindConnectionPoint(pCPC, &IID_IFontEventsDisp, &pCP);
405  EXPECT_HR(hr, S_OK);
406  IConnectionPointContainer_Release(pCPC);
407 
408  hr = IConnectionPoint_Advise(pCP, (IUnknown *)&FontEventsDisp, &dwCookie);
409  EXPECT_HR(hr, S_OK);
410  IConnectionPoint_Release(pCP);
411 
414  hr = IFont_put_Bold(pFont, TRUE);
415  EXPECT_HR(hr, S_OK);
416 
417  ok(fonteventsdisp_invoke_called == 1, "IFontEventDisp::Invoke wasn't called once\n");
419 
420  hr = IFont_QueryInterface(pFont, &IID_IFontDisp, (void **)&pFontDisp);
421  EXPECT_HR(hr, S_OK);
422 
423  for (i = 0; i < ARRAY_SIZE(font_dispids); i++)
424  {
425  switch (font_dispids[i].dispid)
426  {
427  case DISPID_FONT_NAME:
428  {
429  static const WCHAR arialW[] = {'A','r','i','a','l',0};
430  V_VT(&vararg) = VT_BSTR;
431  V_BSTR(&vararg) = SysAllocString(arialW);
432  break;
433  }
434  case DISPID_FONT_SIZE:
435  V_VT(&vararg) = VT_CY;
436  S(V_CY(&vararg)).Lo = 25;
437  S(V_CY(&vararg)).Hi = 0;
438  break;
439  case DISPID_FONT_BOLD:
440  V_VT(&vararg) = VT_BOOL;
441  V_BOOL(&vararg) = VARIANT_FALSE;
442  break;
443  case DISPID_FONT_ITALIC:
444  case DISPID_FONT_UNDER:
445  case DISPID_FONT_STRIKE:
446  V_VT(&vararg) = VT_BOOL;
447  V_BOOL(&vararg) = VARIANT_TRUE;
448  break;
449  case DISPID_FONT_WEIGHT:
450  V_VT(&vararg) = VT_I2;
451  V_I2(&vararg) = FW_BLACK;
452  break;
453  case DISPID_FONT_CHARSET:
454  V_VT(&vararg) = VT_I2;
455  V_I2(&vararg) = 1;
456  break;
457  default:
458  ;
459  }
460 
461  dispparams.cNamedArgs = 0;
462  dispparams.rgdispidNamedArgs = NULL;
463  dispparams.cArgs = 1;
464  dispparams.rgvarg = &vararg;
466  hr = IFontDisp_Invoke(pFontDisp, font_dispids[i].dispid, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
467  ok(hr == S_OK, "dispid=%d, got 0x%08x\n", font_dispids[i].dispid, hr);
468  ok(fonteventsdisp_invoke_called == 1, "dispid=%d, DISPID_FONT_CHANGED not called, got %d\n", font_dispids[i].dispid,
470  if (hr == S_OK)
471  {
472  ok(!lstrcmpW(font_dispids[i].name, fonteventsdisp_invoke_arg0), "dispid=%d, got %s, expected %s\n",
473  font_dispids[i].dispid, wine_dbgstr_w(fonteventsdisp_invoke_arg0), wine_dbgstr_w(font_dispids[i].name));
475  }
476  VariantClear(&vararg);
477  }
478 
479  IFontDisp_Release(pFontDisp);
480 
481  hr = IFont_Clone(pFont, &pFont2);
482  EXPECT_HR(hr, S_OK);
483  IFont_Release(pFont);
484 
485  /* this test shows that the notification routine isn't called again */
487  hr = IFont_put_Bold(pFont2, FALSE);
488  EXPECT_HR(hr, S_OK);
490 
491  IFont_Release(pFont2);
492 }
493 
494 static void test_names_ids(WCHAR* w_name_1, const char* a_name_1,
495  WCHAR* w_name_2, const char* a_name_2,
496  LCID lcid, DISPID id_1, DISPID id_2,
497  HRESULT hres_expect, int numnames)
498 {
499  LPVOID pvObj = NULL;
500  IFontDisp *fontdisp = NULL;
501  HRESULT hres;
502  DISPID rgDispId[2] = {0xdeadbeef, 0xdeadbeef};
503  LPOLESTR names[2] = {w_name_1, w_name_2};
504 
505  pOleCreateFontIndirect(NULL, &IID_IFontDisp, &pvObj);
506  fontdisp = pvObj;
507 
508  hres = IFontDisp_GetIDsOfNames(fontdisp, &IID_NULL, names, numnames,
509  lcid, rgDispId);
510 
511  /* test hres */
512  ok(hres == hres_expect,
513  "GetIDsOfNames: \"%s\", \"%s\" returns 0x%08x, expected 0x%08x.\n",
514  a_name_1, a_name_2, hres, hres_expect);
515 
516  /* test first DISPID */
517  ok(rgDispId[0]==id_1,
518  "GetIDsOfNames: \"%s\" gets DISPID 0x%08x, expected 0x%08x.\n",
519  a_name_1, rgDispId[0], id_1);
520 
521  /* test second DISPID is present */
522  if (numnames == 2)
523  {
524  ok(rgDispId[1]==id_2,
525  "GetIDsOfNames: ..., \"%s\" gets DISPID 0x%08x, expected 0x%08x.\n",
526  a_name_2, rgDispId[1], id_2);
527  }
528 
529  IFontDisp_Release(fontdisp);
530 }
531 
532 static void test_GetIDsOfNames(void)
533 {
534  WCHAR name_Name[] = {'N','a','m','e',0};
535  WCHAR name_Italic[] = {'I','t','a','l','i','c',0};
536  WCHAR name_Size[] = {'S','i','z','e',0};
537  WCHAR name_Bold[] = {'B','o','l','d',0};
538  WCHAR name_Underline[] = {'U','n','d','e','r','l','i','n','e',0};
539  WCHAR name_Strikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
540  WCHAR name_Weight[] = {'W','e','i','g','h','t',0};
541  WCHAR name_Charset[] = {'C','h','a','r','s','e','t',0};
542  WCHAR name_Foo[] = {'F','o','o',0};
543  WCHAR name_nAmE[] = {'n','A','m','E',0};
544  WCHAR name_Nom[] = {'N','o','m',0};
545 
547  SORT_DEFAULT);
549  SORT_DEFAULT);
550 
551  /* Test DISPID_FONTs for the various properties. */
552  test_names_ids(name_Name, "Name", NULL, "", en_us,
553  DISPID_FONT_NAME, 0, S_OK,1);
554  test_names_ids(name_Size, "Size", NULL, "", en_us,
555  DISPID_FONT_SIZE, 0, S_OK,1);
556  test_names_ids(name_Bold, "Bold", NULL, "", en_us,
557  DISPID_FONT_BOLD, 0, S_OK,1);
558  test_names_ids(name_Italic, "Italic", NULL, "", en_us,
559  DISPID_FONT_ITALIC, 0, S_OK,1);
560  test_names_ids(name_Underline, "Underline", NULL, "", en_us,
561  DISPID_FONT_UNDER, 0, S_OK,1);
562  test_names_ids(name_Strikethrough, "Strikethrough", NULL, "", en_us,
563  DISPID_FONT_STRIKE, 0, S_OK,1);
564  test_names_ids(name_Weight, "Weight", NULL, "", en_us,
565  DISPID_FONT_WEIGHT, 0, S_OK,1);
566  test_names_ids(name_Charset, "Charset", NULL, "", en_us,
567  DISPID_FONT_CHARSET, 0, S_OK,1);
568 
569  /* Capitalization doesn't matter. */
570  test_names_ids(name_nAmE, "nAmE", NULL, "", en_us,
571  DISPID_FONT_NAME, 0, S_OK,1);
572 
573  /* Unknown name. */
574  test_names_ids(name_Foo, "Foo", NULL, "", en_us,
575  DISPID_UNKNOWN, 0, DISP_E_UNKNOWNNAME,1);
576 
577  /* Pass several names: first is processed, */
578  /* second gets DISPID_UNKNOWN and doesn't affect retval. */
579  test_names_ids(name_Italic, "Italic", name_Name, "Name", en_us,
580  DISPID_FONT_ITALIC, DISPID_UNKNOWN, S_OK,2);
581  test_names_ids(name_Italic, "Italic", name_Foo, "Foo", en_us,
582  DISPID_FONT_ITALIC, DISPID_UNKNOWN, S_OK,2);
583 
584  /* Locale ID has no effect. */
585  test_names_ids(name_Name, "Name", NULL, "", fr_fr,
586  DISPID_FONT_NAME, 0, S_OK,1);
587  test_names_ids(name_Nom, "This is not a font", NULL, "", fr_fr,
588  DISPID_UNKNOWN, 0, DISP_E_UNKNOWNNAME,1);
589 
590  /* One of the arguments are invalid */
591  test_names_ids(name_Name, "Name", NULL, "", en_us,
592  0xdeadbeef, 0xdeadbeef, E_INVALIDARG,0);
593  test_names_ids(name_Italic, "Italic", NULL, "", en_us,
594  0xdeadbeef, 0xdeadbeef, E_INVALIDARG,0);
595  test_names_ids(name_Foo, "Foo", NULL, "", en_us,
596  0xdeadbeef, 0xdeadbeef, E_INVALIDARG,0);
597 
598  /* Crazy locale ID? */
599  test_names_ids(name_Name, "Name", NULL, "", -1,
600  DISPID_FONT_NAME, 0, S_OK,1);
601 }
602 
603 static void test_Invoke(void)
604 {
605  IFontDisp *fontdisp;
606  HRESULT hr;
607  VARIANTARG vararg;
608  DISPPARAMS dispparams;
609  VARIANT varresult;
610 
611  hr = pOleCreateFontIndirect(NULL, &IID_IFontDisp, (void **)&fontdisp);
612  EXPECT_HR(hr, S_OK);
613 
614  V_VT(&vararg) = VT_BOOL;
615  V_BOOL(&vararg) = VARIANT_FALSE;
616  dispparams.cNamedArgs = 0;
617  dispparams.rgdispidNamedArgs = NULL;
618  dispparams.cArgs = 1;
619  dispparams.rgvarg = &vararg;
620  hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_IFontDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
622 
623  dispparams.cArgs = 0;
624  dispparams.rgvarg = NULL;
625  hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
627 
628  hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
630 
631  hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
633 
634  hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
635  EXPECT_HR(hr, S_OK);
636 
637  hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_METHOD, NULL, &varresult, NULL, NULL);
639 
640  hr = IFontDisp_Invoke(fontdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
642 
643  dispparams.cArgs = 1;
644  dispparams.rgvarg = &vararg;
645  hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
646  EXPECT_HR(hr, S_OK);
647 
648  IFontDisp_Release(fontdisp);
649 }
650 
651 static void test_IsEqual(void)
652 {
653  FONTDESC fd;
654  IFont* ifnt = NULL;
655  IFont* ifnt2 = NULL;
656  HRESULT hres;
657 
658  /* Basic font description */
659  fd.cbSizeofstruct = sizeof(FONTDESC);
660  fd.lpstrName = system_font;
661  S(fd.cySize).Lo = 100;
662  S(fd.cySize).Hi = 100;
663  fd.sWeight = 0;
664  fd.sCharset = 0;
665  fd.fItalic = FALSE;
666  fd.fUnderline = FALSE;
667  fd.fStrikethrough = FALSE;
668 
669  /* Create font */
670  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt);
671 
672  /* Test equal fonts */
673  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
674  hres = IFont_IsEqual(ifnt,ifnt2);
675  ok(hres == S_OK,
676  "IFont_IsEqual: (EQUAL) Expected S_OK but got 0x%08x\n",hres);
677  IFont_Release(ifnt2);
678 
679  /* Check for bad pointer */
680  hres = IFont_IsEqual(ifnt,NULL);
681  ok(hres == E_POINTER,
682  "IFont_IsEqual: (NULL) Expected 0x80004003 but got 0x%08x\n",hres);
683 
684  /* Test strName */
685  fd.lpstrName = arial_font;
686  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
687  hres = IFont_IsEqual(ifnt,ifnt2);
688  ok(hres == S_FALSE,
689  "IFont_IsEqual: (strName) Expected S_FALSE but got 0x%08x\n",hres);
690  fd.lpstrName = system_font;
691  IFont_Release(ifnt2);
692 
693  /* Test lo font size */
694  S(fd.cySize).Lo = 10000;
695  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
696  hres = IFont_IsEqual(ifnt,ifnt2);
697  ok(hres == S_FALSE,
698  "IFont_IsEqual: (Lo font size) Expected S_FALSE but got 0x%08x\n",hres);
699  S(fd.cySize).Lo = 100;
700  IFont_Release(ifnt2);
701 
702  /* Test hi font size */
703  S(fd.cySize).Hi = 10000;
704  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
705  hres = IFont_IsEqual(ifnt,ifnt2);
706  ok(hres == S_FALSE,
707  "IFont_IsEqual: (Hi font size) Expected S_FALSE but got 0x%08x\n",hres);
708  S(fd.cySize).Hi = 100;
709  IFont_Release(ifnt2);
710 
711  /* Test font weight */
712  fd.sWeight = 100;
713  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
714  hres = IFont_IsEqual(ifnt,ifnt2);
715  ok(hres == S_FALSE,
716  "IFont_IsEqual: (Weight) Expected S_FALSE but got 0x%08x\n",hres);
717  fd.sWeight = 0;
718  IFont_Release(ifnt2);
719 
720  /* Test charset */
721  fd.sCharset = 1;
722  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
723  hres = IFont_IsEqual(ifnt,ifnt2);
724  ok(hres == S_FALSE,
725  "IFont_IsEqual: (Charset) Expected S_FALSE but got 0x%08x\n",hres);
726  fd.sCharset = 0;
727  IFont_Release(ifnt2);
728 
729  /* Test italic setting */
730  fd.fItalic = TRUE;
731  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
732  hres = IFont_IsEqual(ifnt,ifnt2);
733  ok(hres == S_FALSE,
734  "IFont_IsEqual: (Italic) Expected S_FALSE but got 0x%08x\n",hres);
735  fd.fItalic = FALSE;
736  IFont_Release(ifnt2);
737 
738  /* Test underline setting */
739  fd.fUnderline = TRUE;
740  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
741  hres = IFont_IsEqual(ifnt,ifnt2);
742  ok(hres == S_FALSE,
743  "IFont_IsEqual: (Underline) Expected S_FALSE but got 0x%08x\n",hres);
744  fd.fUnderline = FALSE;
745  IFont_Release(ifnt2);
746 
747  /* Test strikethrough setting */
748  fd.fStrikethrough = TRUE;
749  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
750  hres = IFont_IsEqual(ifnt,ifnt2);
751  ok(hres == S_FALSE,
752  "IFont_IsEqual: (Strikethrough) Expected S_FALSE but got 0x%08x\n",hres);
753  fd.fStrikethrough = FALSE;
754  IFont_Release(ifnt2);
755 
756  /* Free IFont. */
757  IFont_Release(ifnt);
758 }
759 
760 static void test_ReleaseHfont(void)
761 {
762  FONTDESC fd;
763  LPVOID pvObj1 = NULL;
764  LPVOID pvObj2 = NULL;
765  IFont* ifnt1 = NULL;
766  IFont* ifnt2 = NULL;
767  HFONT hfnt1 = 0;
768  HFONT hfnt2 = 0;
769  HRESULT hres;
770 
771  /* Basic font description */
772  fd.cbSizeofstruct = sizeof(FONTDESC);
773  fd.lpstrName = system_font;
774  S(fd.cySize).Lo = 100;
775  S(fd.cySize).Hi = 100;
776  fd.sWeight = 0;
777  fd.sCharset = 0;
778  fd.fItalic = FALSE;
779  fd.fUnderline = FALSE;
780  fd.fStrikethrough = FALSE;
781 
782  /* Create HFONTs and IFONTs */
783  pOleCreateFontIndirect(&fd, &IID_IFont, &pvObj1);
784  ifnt1 = pvObj1;
785  IFont_get_hFont(ifnt1,&hfnt1);
786  fd.lpstrName = arial_font;
787  pOleCreateFontIndirect(&fd, &IID_IFont, &pvObj2);
788  ifnt2 = pvObj2;
789  IFont_get_hFont(ifnt2,&hfnt2);
790 
791  /* Try invalid HFONT */
792  hres = IFont_ReleaseHfont(ifnt1,NULL);
793  ok(hres == E_INVALIDARG,
794  "IFont_ReleaseHfont: (Bad HFONT) Expected E_INVALIDARG but got 0x%08x\n",
795  hres);
796 
797  /* Try to add a bad HFONT */
798  hres = IFont_ReleaseHfont(ifnt1,(HFONT)32);
799  ok(hres == S_FALSE,
800  "IFont_ReleaseHfont: (Bad HFONT) Expected S_FALSE but got 0x%08x\n",
801  hres);
802 
803  /* Release all refs */
804  hres = IFont_ReleaseHfont(ifnt1,hfnt1);
805  ok(hres == S_OK,
806  "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
807  hres);
808 
809  hres = IFont_ReleaseHfont(ifnt2,hfnt2);
810  ok(hres == S_OK,
811  "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
812  hres);
813 
814  /* Check that both lists are empty */
815  hres = IFont_ReleaseHfont(ifnt1,hfnt1);
816  ok(hres == S_FALSE,
817  "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
818  hres);
819 
820  /* The list should be 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);
825 
826  IFont_Release(ifnt1);
827  IFont_Release(ifnt2);
828 }
829 
830 static void test_AddRefHfont(void)
831 {
832  FONTDESC fd;
833  IFont* ifnt1 = NULL;
834  IFont* ifnt2 = NULL;
835  IFont* ifnt3 = NULL;
836  HFONT hfnt1 = 0;
837  HFONT hfnt2 = 0;
838  HFONT hfnt3 = 0;
839  HRESULT hres;
840 
841  /* Basic font description */
842  fd.cbSizeofstruct = sizeof(FONTDESC);
843  fd.lpstrName = system_font;
844  S(fd.cySize).Lo = 100;
845  S(fd.cySize).Hi = 100;
846  fd.sWeight = 0;
847  fd.sCharset = 0;
848  fd.fItalic = FALSE;
849  fd.fUnderline = FALSE;
850  fd.fStrikethrough = FALSE;
851 
852  /* Create HFONTs and IFONTs */
853  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt1);
854  IFont_get_hFont(ifnt1,&hfnt1);
855  fd.lpstrName = arial_font;
856  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
857  IFont_get_hFont(ifnt2,&hfnt2);
858 
859  /* Try invalid HFONT */
860  hres = IFont_AddRefHfont(ifnt1,NULL);
861  ok(hres == E_INVALIDARG,
862  "IFont_AddRefHfont: (Bad HFONT) Expected E_INVALIDARG but got 0x%08x\n",
863  hres);
864 
865  /* Try to add a bad HFONT */
866  hres = IFont_AddRefHfont(ifnt1,(HFONT)32);
867  ok(hres == S_FALSE,
868  "IFont_AddRefHfont: (Bad HFONT) Expected S_FALSE but got 0x%08x\n",
869  hres);
870 
871  /* Add simple IFONT HFONT pair */
872  hres = IFont_AddRefHfont(ifnt1,hfnt1);
873  ok(hres == S_OK,
874  "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
875  hres);
876 
877  /* IFONT and HFONT do not have to be the same (always looks at HFONT) */
878  hres = IFont_AddRefHfont(ifnt2,hfnt1);
879  ok(hres == S_OK,
880  "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
881  hres);
882 
883  /* Release all hfnt1 refs */
884  hres = IFont_ReleaseHfont(ifnt1,hfnt1);
885  ok(hres == S_OK,
886  "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
887  hres);
888 
889  hres = IFont_ReleaseHfont(ifnt1,hfnt1);
890  ok(hres == S_OK,
891  "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
892  hres);
893 
894  hres = IFont_ReleaseHfont(ifnt1,hfnt1);
895  ok(hres == S_OK,
896  "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
897  hres);
898 
899  /* Check if hfnt1 is empty */
900  hres = IFont_ReleaseHfont(ifnt1,hfnt1);
901  ok(hres == S_FALSE,
902  "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
903  hres);
904 
905  /* Release all hfnt2 refs */
906  hres = IFont_ReleaseHfont(ifnt2,hfnt2);
907  ok(hres == S_OK,
908  "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
909  hres);
910 
911  /* Check if hfnt2 is empty */
912  hres = IFont_ReleaseHfont(ifnt2,hfnt2);
913  ok(hres == S_FALSE,
914  "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
915  hres);
916 
917  /* Show that releasing an IFONT does not always release it from the HFONT cache. */
918 
919  IFont_Release(ifnt1);
920 
921  /* Add a reference for destroyed hfnt1 */
922  hres = IFont_AddRefHfont(ifnt2,hfnt1);
923  ok(hres == S_OK,
924  "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
925  hres);
926 
927  /* Decrement reference for destroyed hfnt1 */
928  hres = IFont_ReleaseHfont(ifnt2,hfnt1);
929  ok(hres == S_OK ||
930  hres == S_FALSE, /* <= win2k */
931  "IFont_AddRefHfont: (Release ref) Expected S_OK or S_FALSE but got 0x%08x\n",
932  hres);
933 
934  /* Shows that releasing all IFONT's does clear the HFONT cache. */
935 
936  IFont_Release(ifnt2);
937 
938  /* Need to make a new IFONT for testing */
939  fd.fUnderline = TRUE;
940  pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt3);
941  IFont_get_hFont(ifnt3,&hfnt3);
942 
943  /* Add a reference for destroyed hfnt1 */
944  hres = IFont_AddRefHfont(ifnt3,hfnt1);
945  ok(hres == S_FALSE,
946  "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
947  hres);
948 
949  /* Decrement reference for destroyed hfnt1 */
950  hres = IFont_ReleaseHfont(ifnt3,hfnt1);
951  ok(hres == S_FALSE,
952  "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
953  hres);
954 
955  IFont_Release(ifnt3);
956 }
957 
958 static void test_returns(void)
959 {
960  IFont *pFont;
961  FONTDESC fontdesc;
962  HRESULT hr;
963 
964  fontdesc.cbSizeofstruct = sizeof(fontdesc);
965  fontdesc.lpstrName = MSSansSerif_font;
966  fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
967  fontdesc.sWeight = FW_NORMAL;
968  fontdesc.sCharset = 0;
969  fontdesc.fItalic = FALSE;
970  fontdesc.fUnderline = FALSE;
971  fontdesc.fStrikethrough = FALSE;
972 
973  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont);
974  EXPECT_HR(hr, S_OK);
975 
976  hr = IFont_put_Name(pFont, NULL);
978 
979  hr = IFont_get_Name(pFont, NULL);
981 
982  hr = IFont_get_Size(pFont, NULL);
984 
985  hr = IFont_get_Bold(pFont, NULL);
987 
988  IFont_Release(pFont);
989 }
990 
991 static void test_hfont_lifetime(void)
992 {
993  IFont *font, *font2;
994  FONTDESC fontdesc;
995  HRESULT hr;
996  HFONT hfont, first_hfont = NULL;
997  CY size;
998  DWORD obj_type;
999  int i;
1000 
1001  fontdesc.cbSizeofstruct = sizeof(fontdesc);
1002  fontdesc.lpstrName = arial_font;
1003  fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
1004  fontdesc.sWeight = FW_NORMAL;
1005  fontdesc.sCharset = ANSI_CHARSET;
1006  fontdesc.fItalic = FALSE;
1007  fontdesc.fUnderline = FALSE;
1008  fontdesc.fStrikethrough = FALSE;
1009 
1010  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
1011  EXPECT_HR(hr, S_OK);
1012 
1013  hr = IFont_get_hFont(font, &hfont);
1014  EXPECT_HR(hr, S_OK);
1015 
1016  /* show that if the font is updated the old hfont is deleted when the
1017  new font is realized */
1018  for(i = 0; i < 100; i++)
1019  {
1020  HFONT last_hfont = hfont;
1021 
1022  size.int64 = (i + 10) * 20000;
1023 
1024  obj_type = GetObjectType(hfont);
1025  ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1026 
1027  hr = IFont_put_Size(font, size);
1028  EXPECT_HR(hr, S_OK);
1029 
1030  /* put_Size doesn't cause the new font to be realized */
1031  obj_type = GetObjectType(last_hfont);
1032  ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1033 
1034  hr = IFont_get_hFont(font, &hfont);
1035  EXPECT_HR(hr, S_OK);
1036 
1037  obj_type = GetObjectType(last_hfont);
1038  ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type);
1039  }
1040 
1041  /* now show that if we take a reference on the hfont, it persists
1042  until the font object is released */
1043  for(i = 0; i < 100; i++)
1044  {
1045  size.int64 = (i + 10) * 20000;
1046 
1047  obj_type = GetObjectType(hfont);
1048  ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1049 
1050  hr = IFont_put_Size(font, size);
1051  EXPECT_HR(hr, S_OK);
1052 
1053  hr = IFont_get_hFont(font, &hfont);
1054  EXPECT_HR(hr, S_OK);
1055 
1056  hr = IFont_AddRefHfont(font, hfont);
1057  EXPECT_HR(hr, S_OK);
1058 
1059  if(i == 0) first_hfont = hfont;
1060  obj_type = GetObjectType(first_hfont);
1061  ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1062  }
1063 
1064  IFont_Release(font);
1065 
1066  obj_type = GetObjectType(first_hfont);
1067  ok(obj_type == 0, "got obj type %d\n", obj_type);
1068 
1069  /* An AddRefHfont followed by a ReleaseHfont means the font doesn't not persist
1070  through re-realization */
1071 
1072  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
1073  EXPECT_HR(hr, S_OK);
1074 
1075  hr = IFont_get_hFont(font, &hfont);
1076  EXPECT_HR(hr, S_OK);
1077 
1078  for(i = 0; i < 100; i++)
1079  {
1080  HFONT last_hfont = hfont;
1081 
1082  size.int64 = (i + 10) * 20000;
1083 
1084  obj_type = GetObjectType(hfont);
1085  ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1086 
1087  hr = IFont_put_Size(font, size);
1088  EXPECT_HR(hr, S_OK);
1089 
1090  /* put_Size doesn't cause the new font to be realized */
1091  obj_type = GetObjectType(last_hfont);
1092  ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1093 
1094  hr = IFont_get_hFont(font, &hfont);
1095  EXPECT_HR(hr, S_OK);
1096 
1097  hr = IFont_AddRefHfont(font, hfont);
1098  EXPECT_HR(hr, S_OK);
1099 
1100  hr = IFont_ReleaseHfont(font, hfont);
1101  EXPECT_HR(hr, S_OK);
1102 
1103  obj_type = GetObjectType(last_hfont);
1104  ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type);
1105  }
1106 
1107  /* Interestingly if we release a nonexistent reference on the hfont,
1108  * it persists until the font object is released
1109  */
1110  for(i = 0; i < 100; i++)
1111  {
1112  size.int64 = (i + 10) * 20000;
1113 
1114  obj_type = GetObjectType(hfont);
1115  ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1116 
1117  hr = IFont_put_Size(font, size);
1118  EXPECT_HR(hr, S_OK);
1119 
1120  hr = IFont_get_hFont(font, &hfont);
1121  EXPECT_HR(hr, S_OK);
1122 
1123  hr = IFont_ReleaseHfont(font, hfont);
1124  EXPECT_HR(hr, S_OK);
1125 
1126  if(i == 0) first_hfont = hfont;
1127  obj_type = GetObjectType(first_hfont);
1128  ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1129  }
1130 
1131  IFont_Release(font);
1132 
1133  obj_type = GetObjectType(first_hfont);
1134  ok(obj_type == 0, "got obj type %d\n", obj_type);
1135 
1136  /* If we take two internal references on a hfont then we can release
1137  it twice. So it looks like there's a total reference count
1138  that includes internal and external references */
1139 
1140  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
1141  EXPECT_HR(hr, S_OK);
1142  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font2);
1143  EXPECT_HR(hr, S_OK);
1144 
1145  hr = IFont_get_hFont(font, &hfont);
1146  EXPECT_HR(hr, S_OK);
1147  hr = IFont_get_hFont(font2, &first_hfont);
1148  EXPECT_HR(hr, S_OK);
1149 todo_wine
1150  ok(hfont == first_hfont, "fonts differ\n");
1151  hr = IFont_ReleaseHfont(font, hfont);
1152  EXPECT_HR(hr, S_OK);
1153  hr = IFont_ReleaseHfont(font, hfont);
1154 todo_wine
1155  EXPECT_HR(hr, S_OK);
1156  hr = IFont_ReleaseHfont(font, hfont);
1157  EXPECT_HR(hr, S_FALSE);
1158 
1159  obj_type = GetObjectType(hfont);
1160  ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1161 
1162  IFont_Release(font);
1163 
1164  obj_type = GetObjectType(hfont);
1165  ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1166 
1167  IFont_Release(font2);
1168 
1169  obj_type = GetObjectType(hfont);
1170  ok(obj_type == 0, "got obj type %d\n", obj_type);
1171 }
1172 
1173 static void test_realization(void)
1174 {
1175  IFont *font;
1176  FONTDESC fontdesc;
1177  HRESULT hr;
1178  BSTR name;
1179  SHORT cs;
1180 
1181  /* Try to create a symbol only font (marlett) with charset
1182  set to ANSI. This will result in another, ANSI, font
1183  being selected */
1184  fontdesc.cbSizeofstruct = sizeof(fontdesc);
1185  fontdesc.lpstrName = marlett_font;
1186  fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
1187  fontdesc.sWeight = FW_NORMAL;
1188  fontdesc.sCharset = ANSI_CHARSET;
1189  fontdesc.fItalic = FALSE;
1190  fontdesc.fUnderline = FALSE;
1191  fontdesc.fStrikethrough = FALSE;
1192 
1193  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
1194  EXPECT_HR(hr, S_OK);
1195 
1196  hr = IFont_get_Charset(font, &cs);
1197  EXPECT_HR(hr, S_OK);
1198  ok(cs == ANSI_CHARSET, "got charset %d\n", cs);
1199 
1200  IFont_Release(font);
1201 
1202  /* Now create an ANSI font and change the name to marlett */
1203 
1204  fontdesc.lpstrName = arial_font;
1205 
1206  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
1207  EXPECT_HR(hr, S_OK);
1208 
1209  hr = IFont_get_Charset(font, &cs);
1210  EXPECT_HR(hr, S_OK);
1211  ok(cs == ANSI_CHARSET, "got charset %d\n", cs);
1212 
1214  hr = IFont_put_Name(font, name);
1215  EXPECT_HR(hr, S_OK);
1217 
1218  hr = IFont_get_Name(font, &name);
1219  EXPECT_HR(hr, S_OK);
1220  ok(!lstrcmpiW(name, marlett_font), "got name %s\n", wine_dbgstr_w(name));
1222 
1223  hr = IFont_get_Charset(font, &cs);
1224  EXPECT_HR(hr, S_OK);
1225  ok(cs == SYMBOL_CHARSET, "got charset %d\n", cs);
1226 
1227  IFont_Release(font);
1228 }
1229 
1231 {
1232  FONTDESC fontdesc;
1233  IUnknown *unk, *unk2;
1234  IFont *font;
1235  HRESULT hr;
1236 
1237  fontdesc.cbSizeofstruct = sizeof(fontdesc);
1238  fontdesc.lpstrName = arial_font;
1239  fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
1240  fontdesc.sWeight = FW_NORMAL;
1241  fontdesc.sCharset = ANSI_CHARSET;
1242  fontdesc.fItalic = FALSE;
1243  fontdesc.fUnderline = FALSE;
1244  fontdesc.fStrikethrough = FALSE;
1245 
1246  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
1247  EXPECT_HR(hr, S_OK);
1248  IFont_Release(font);
1249 
1250  /* play with cbSizeofstruct value */
1251  fontdesc.cbSizeofstruct = sizeof(fontdesc)-1;
1252  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
1253  EXPECT_HR(hr, S_OK);
1254  IFont_Release(font);
1255 
1256  fontdesc.cbSizeofstruct = sizeof(fontdesc)+1;
1257  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
1258  EXPECT_HR(hr, S_OK);
1259  IFont_Release(font);
1260 
1261  fontdesc.cbSizeofstruct = 0;
1262  hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
1263  EXPECT_HR(hr, S_OK);
1264  IFont_Release(font);
1265 
1266  hr = OleInitialize(NULL);
1267  ok(hr == S_OK, "got 0x%08x\n", hr);
1268 
1269  hr = CoGetClassObject(&CLSID_StdFont, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&unk);
1270  ok(hr == S_OK, "got 0x%08x\n", hr);
1271 
1272  hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void**)&unk2);
1273  ok(hr == S_OK, "got 0x%08x\n", hr);
1274 
1275  IUnknown_Release(unk);
1276  IUnknown_Release(unk2);
1277 
1278  OleUninitialize();
1279 }
1280 
1281 START_TEST(olefont)
1282 {
1283  hOleaut32 = GetModuleHandleA("oleaut32.dll");
1284  pOleCreateFontIndirect = (void*)GetProcAddress(hOleaut32, "OleCreateFontIndirect");
1285  if (!pOleCreateFontIndirect)
1286  {
1287  win_skip("OleCreateFontIndirect not available\n");
1288  return;
1289  }
1290 
1292  test_type_info();
1293  test_ifont_sizes();
1296  test_Invoke();
1297  test_IsEqual();
1299  test_AddRefHfont();
1300  test_returns();
1302  test_realization();
1304 }
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
#define DISPID_FONT_UNDER
Definition: olectl.h:431
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
#define abs(i)
Definition: fconv.c:206
#define MAKELCID(lgid, srtid)
#define TRUE
Definition: types.h:120
#define E_NOINTERFACE
Definition: winerror.h:2364
static void test_type_info(void)
Definition: olefont.c:219
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
_Must_inspect_result_ _Out_ LPSIZE psize
Definition: ntgdi.h:1569
static BSTR fonteventsdisp_invoke_arg0
Definition: olefont.c:309
static HRESULT WINAPI FontEventsDisp_GetIDsOfNames(IFontEventsDisp *iface, REFIID riid, LPOLESTR *names, UINT cNames, LCID lcid, DISPID *dispid)
Definition: olefont.c:301
HRESULT hr
Definition: shlfolder.c:183
static WCHAR arial_font[]
Definition: olefont.c:47
HDC WINAPI GetDC(_In_opt_ HWND)
Definition: mk_font.cpp:20
static void test_names_ids(WCHAR *w_name_1, const char *a_name_1, WCHAR *w_name_2, const char *a_name_2, LCID lcid, DISPID id_1, DISPID id_2, HRESULT hres_expect, int numnames)
Definition: olefont.c:494
#define DISPID_FONT_WEIGHT
Definition: olectl.h:433
REFIID riid
Definition: precomp.h:44
static HMODULE hOleaut32
Definition: olefont.c:50
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define SYMBOL_CHARSET
Definition: wingdi.h:384
BOOL fItalic
Definition: olectl.h:124
#define V_I2(A)
Definition: oleauto.h:245
static HDC
Definition: imagelist.c:92
#define DISP_E_MEMBERNOTFOUND
Definition: winerror.h:2512
static int fonteventsdisp_invoke_called
Definition: olefont.c:308
const GUID IID_IConnectionPointContainer
GLdouble n
Definition: glext.h:7729
#define S(x)
Definition: test.h:190
const char * wine_dbgstr_guid(const GUID *guid)
static IFontEventsDisp FontEventsDisp
Definition: olefont.c:346
#define DISPID_FONT_BOLD
Definition: olectl.h:429
BOOL fStrikethrough
Definition: olectl.h:126
static int fd
Definition: io.c:51
CY cySize
Definition: olectl.h:121
DWORD LCID
Definition: nls.h:13
OLECHAR * BSTR
Definition: compat.h:1942
static void test_ifont_size(LONGLONG size, LONG ratio_logical, LONG ratio_himetric, LONG hfont_height, const char *test_name)
Definition: olefont.c:61
Definition: movable.cpp:7
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:571
#define SUBLANG_FRENCH
Definition: nls.h:242
static LPOLESTR
Definition: stg_prop.c:27
Definition: ocidl.idl:75
#define E_FAIL
Definition: ddrawi.h:102
static void test_ifont_sizes(void)
Definition: olefont.c:120
int32_t INT
Definition: typedefs.h:56
Definition: send.c:47
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
DISPID dispid
Definition: olefont.c:350
#define DISPATCH_METHOD
Definition: oleauto.h:1006
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static WCHAR MSSansSerif_font[]
Definition: olefont.c:45
const GUID CLSID_StdFont
GLuint GLuint * names
Definition: glext.h:11545
static void test_realization(void)
Definition: olefont.c:1173
#define EXPECT_HR(hr, hr_exp)
Definition: olefont.c:54
uint32_t cs
Definition: isohybrid.c:75
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: compat.h:1904
#define V_CY(A)
Definition: oleauto.h:229
#define DISPID_FONT_SIZE
Definition: olectl.h:428
long LONG
Definition: pedump.c:60
short SHORT
Definition: pedump.c:59
LONG lfHeight
Definition: dimm.idl:42
#define DISPID_FONT_STRIKE
Definition: olectl.h:432
GLenum GLint ref
Definition: glext.h:6028
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * name
Definition: olefont.c:351
static void test_GetIDsOfNames(void)
Definition: olefont.c:532
static const WCHAR strikeW[]
Definition: string.c:57
static const WCHAR boldW[]
Definition: string.c:40
smooth NULL
Definition: ftsmooth.c:416
static REFIID
Definition: olefont.c:52
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:241
struct tagFONTDESC FONTDESC
static const WCHAR charsetW[]
Definition: htmlmeta.c:149
#define FW_BLACK
Definition: wingdi.h:381
static const WCHAR sizeW[]
Definition: editor.c:79
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
static HFONT hfont
static void test_ReleaseHfont(void)
Definition: olefont.c:760
HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3103
static const WCHAR nameW[]
Definition: main.c:46
int64_t LONGLONG
Definition: typedefs.h:66
#define dpi
Definition: sysparams.c:22
static HRESULT WINAPI FontEventsDisp_QueryInterface(IFontEventsDisp *iface, REFIID riid, void **ppvObject)
Definition: olefont.c:262
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONGLONG int64
Definition: compat.h:1914
#define SORT_DEFAULT
LONG HRESULT
Definition: typedefs.h:77
static void test_returns(void)
Definition: olefont.c:958
UINT cbSizeofstruct
Definition: olectl.h:119
struct tagFONTDESC * LPFONTDESC
const GUID IID_IUnknown
static void test_font_events_disp(void)
Definition: olefont.c:354
#define WINAPI
Definition: msvc.h:8
static IFontEventsDispVtbl FontEventsDisp_Vtbl
Definition: olefont.c:335
#define V_BOOL(A)
Definition: oleauto.h:224
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT WINAPI FontEventsDisp_GetTypeInfo(IFontEventsDisp *iface, UINT itinfo, LCID lcid, ITypeInfo **pptinfo)
Definition: olefont.c:295
#define DISP_E_UNKNOWNINTERFACE
Definition: winerror.h:2511
#define OBJ_FONT
Definition: objidl.idl:1414
static HRESULT WINAPI FontEventsDisp_GetTypeInfoCount(IFontEventsDisp *iface, UINT *pctinfo)
Definition: olefont.c:289
#define LANG_ENGLISH
Definition: nls.h:52
const GUID IID_IDispatch
const GUID IID_IFont
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:651
#define IID_NULL
Definition: guiddef.h:98
#define todo_wine
Definition: test.h:154
HDC hdc
Definition: main.c:9
#define DISP_E_PARAMNOTOPTIONAL
Definition: winerror.h:2524
#define V_VT(A)
Definition: oleauto.h:211
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
#define GUID_NULL
Definition: ks.h:106
REFIID LPVOID * ppvObject
Definition: precomp.h:44
#define DISPID_FONT_ITALIC
Definition: olectl.h:430
const GUID IID_IFontDisp
SHORT sWeight
Definition: olectl.h:122
Definition: compat.h:1950
static void test_QueryInterface(void)
Definition: olefont.c:186
#define LANG_FRENCH
Definition: nls.h:58
#define V_BSTR(A)
Definition: oleauto.h:226
#define broken(x)
Definition: _sntprintf.h:21
#define DISPID_FONT_CHARSET
Definition: olectl.h:434
static void test_IsEqual(void)
Definition: olefont.c:651
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:169
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:519
static const char * test_name
Definition: run.c:177
struct stdole::EXCEPINFO EXCEPINFO
static void test_AddRefHfont(void)
Definition: olefont.c:830
static VARIANTARG static DISPID
Definition: ordinal.c:49
#define S_OK
Definition: intsafe.h:59
static void test_OleCreateFontIndirect(void)
Definition: olefont.c:1230
#define DISPID_FONT_NAME
Definition: olectl.h:427
#define ARRAY_SIZE(a)
Definition: main.h:24
#define ok(value,...)
Definition: atltest.h:57
#define E_NOTIMPL
Definition: ddrawi.h:99
static void test_hfont_lifetime(void)
Definition: olefont.c:991
LPOLESTR lpstrName
Definition: olectl.h:120
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:274
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
static POBJECT_TYPE GetObjectType(IN PCWSTR TypeName)
Definition: ObTypes.c:15
static void test_Invoke(void)
Definition: olefont.c:603
#define DISP_E_BADPARAMCOUNT
Definition: winerror.h:2523
static ULONG WINAPI FontEventsDisp_AddRef(IFontEventsDisp *iface)
Definition: olefont.c:277
#define FW_NORMAL
Definition: wingdi.h:372
#define DISPID_FONT_CHANGED
Definition: olectl.h:435
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define skip(...)
Definition: atltest.h:64
static HRESULT WINAPI FontEventsDisp_Invoke(IFontEventsDisp *iface, DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: olefont.c:311
Definition: name.c:36
struct stdole::DISPPARAMS DISPPARAMS
START_TEST(olefont)
Definition: olefont.c:1281
unsigned int ULONG
Definition: retypes.h:1
#define MAKELANGID(p, s)
Definition: nls.h:15
#define CTL_E_INVALIDPROPERTYVALUE
Definition: olectl.h:292
static WCHAR marlett_font[]
Definition: olefont.c:48
#define LOCALE_NEUTRAL
const GUID IID_IFontEventsDisp
#define GetProcAddress(x, y)
Definition: compat.h:418
#define LOGPIXELSY
Definition: wingdi.h:718
BOOL fUnderline
Definition: olectl.h:125
static ULONG WINAPI FontEventsDisp_Release(IFontEventsDisp *iface)
Definition: olefont.c:283
SHORT sCharset
Definition: olectl.h:123
#define ANSI_CHARSET
Definition: wingdi.h:382
#define E_POINTER
Definition: winerror.h:2365
static WCHAR system_font[]
Definition: olefont.c:46
const GUID IID_IClassFactory
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:230
#define win_skip
Definition: test.h:141
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
Definition: compat.h:1946
static HRESULT(WINAPI *pOleCreateFontIndirect)(LPFONTDESC
DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
GLuint const GLchar * name
Definition: glext.h:6031