Added regression test for WM_NEXTDLGCTL and default button ID
[wine/testsucceed.git] / dlls / oleaut32 / olefont.c
blob0576d4a916853903c701ccd4a3c2758927a594af
1 /*
2 * OLE Font encapsulation implementation
4 * This file contains an implementation of the IFont
5 * interface and the OleCreateFontIndirect API call.
7 * Copyright 1999 Francis Beaudet
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <assert.h>
24 #include <stdarg.h>
25 #include <string.h>
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
29 #include "winerror.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "winuser.h"
34 #include "wine/unicode.h"
35 #include "oleauto.h" /* for SysAllocString(....) */
36 #include "objbase.h"
37 #include "ole2.h"
38 #include "olectl.h"
39 #include "wine/debug.h"
40 #include "connpt.h" /* for CreateConnectionPoint */
42 WINE_DEFAULT_DEBUG_CHANNEL(ole);
44 /***********************************************************************
45 * Declaration of constants used when serializing the font object.
47 #define FONTPERSIST_ITALIC 0x02
48 #define FONTPERSIST_UNDERLINE 0x04
49 #define FONTPERSIST_STRIKETHROUGH 0x08
51 /***********************************************************************
52 * Declaration of the implementation class for the IFont interface
54 typedef struct OLEFontImpl OLEFontImpl;
56 struct OLEFontImpl
59 * This class supports many interfaces. IUnknown, IFont,
60 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
61 * The first two are supported by the first vtable, the next two are
62 * supported by the second table and the last two have their own.
64 ICOM_VTABLE(IFont)* lpvtbl1;
65 ICOM_VTABLE(IDispatch)* lpvtbl2;
66 ICOM_VTABLE(IPersistStream)* lpvtbl3;
67 ICOM_VTABLE(IConnectionPointContainer)* lpvtbl4;
68 ICOM_VTABLE(IPersistPropertyBag)* lpvtbl5;
69 ICOM_VTABLE(IPersistStreamInit)* lpvtbl6;
71 * Reference count for that instance of the class.
73 ULONG ref;
76 * This structure contains the description of the class.
78 FONTDESC description;
81 * Contain the font associated with this object.
83 HFONT gdiFont;
86 * Font lock count.
88 DWORD fontLock;
91 * Size ratio
93 long cyLogical;
94 long cyHimetric;
96 IConnectionPoint *pCP;
100 * Here, I define utility macros to help with the casting of the
101 * "this" parameter.
102 * There is a version to accomodate all of the VTables implemented
103 * by this object.
105 #define _ICOM_THIS(class,name) class* this = (class*)name
106 #define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*))
107 #define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*))
108 #define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*))
109 #define _ICOM_THIS_From_IPersistPropertyBag(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*))
110 #define _ICOM_THIS_From_IPersistStreamInit(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*))
113 /***********************************************************************
114 * Prototypes for the implementation functions for the IFont
115 * interface
117 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
118 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
119 static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);
120 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
121 static ULONG WINAPI OLEFontImpl_Release(IFont* iface);
122 static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);
123 static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);
124 static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);
125 static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);
126 static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);
127 static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);
128 static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);
129 static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);
130 static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);
131 static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);
132 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);
133 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);
134 static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);
135 static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);
136 static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);
137 static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);
138 static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
139 static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
140 static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
141 static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, long cyLogical, long cyHimetric);
142 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
143 static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
144 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
145 static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);
147 /***********************************************************************
148 * Prototypes for the implementation functions for the IDispatch
149 * interface
151 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
152 REFIID riid,
153 VOID** ppvoid);
154 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
155 static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
156 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,
157 unsigned int* pctinfo);
158 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,
159 UINT iTInfo,
160 LCID lcid,
161 ITypeInfo** ppTInfo);
162 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,
163 REFIID riid,
164 LPOLESTR* rgszNames,
165 UINT cNames,
166 LCID lcid,
167 DISPID* rgDispId);
168 static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,
169 DISPID dispIdMember,
170 REFIID riid,
171 LCID lcid,
172 WORD wFlags,
173 DISPPARAMS* pDispParams,
174 VARIANT* pVarResult,
175 EXCEPINFO* pExepInfo,
176 UINT* puArgErr);
178 /***********************************************************************
179 * Prototypes for the implementation functions for the IPersistStream
180 * interface
182 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
183 REFIID riid,
184 VOID** ppvoid);
185 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
186 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
187 static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface,
188 CLSID* pClassID);
189 static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);
190 static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,
191 IStream* pLoadStream);
192 static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,
193 IStream* pOutStream,
194 BOOL fClearDirty);
195 static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,
196 ULARGE_INTEGER* pcbSize);
198 /***********************************************************************
199 * Prototypes for the implementation functions for the
200 * IConnectionPointContainer interface
202 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
203 IConnectionPointContainer* iface,
204 REFIID riid,
205 VOID** ppvoid);
206 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
207 IConnectionPointContainer* iface);
208 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
209 IConnectionPointContainer* iface);
210 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
211 IConnectionPointContainer* iface,
212 IEnumConnectionPoints **ppEnum);
213 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
214 IConnectionPointContainer* iface,
215 REFIID riid,
216 IConnectionPoint **ppCp);
219 * Virtual function tables for the OLEFontImpl class.
221 static ICOM_VTABLE(IFont) OLEFontImpl_VTable =
223 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
224 OLEFontImpl_QueryInterface,
225 OLEFontImpl_AddRef,
226 OLEFontImpl_Release,
227 OLEFontImpl_get_Name,
228 OLEFontImpl_put_Name,
229 OLEFontImpl_get_Size,
230 OLEFontImpl_put_Size,
231 OLEFontImpl_get_Bold,
232 OLEFontImpl_put_Bold,
233 OLEFontImpl_get_Italic,
234 OLEFontImpl_put_Italic,
235 OLEFontImpl_get_Underline,
236 OLEFontImpl_put_Underline,
237 OLEFontImpl_get_Strikethrough,
238 OLEFontImpl_put_Strikethrough,
239 OLEFontImpl_get_Weight,
240 OLEFontImpl_put_Weight,
241 OLEFontImpl_get_Charset,
242 OLEFontImpl_put_Charset,
243 OLEFontImpl_get_hFont,
244 OLEFontImpl_Clone,
245 OLEFontImpl_IsEqual,
246 OLEFontImpl_SetRatio,
247 OLEFontImpl_QueryTextMetrics,
248 OLEFontImpl_AddRefHfont,
249 OLEFontImpl_ReleaseHfont,
250 OLEFontImpl_SetHdc
253 static ICOM_VTABLE(IDispatch) OLEFontImpl_IDispatch_VTable =
255 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
256 OLEFontImpl_IDispatch_QueryInterface,
257 OLEFontImpl_IDispatch_AddRef,
258 OLEFontImpl_IDispatch_Release,
259 OLEFontImpl_GetTypeInfoCount,
260 OLEFontImpl_GetTypeInfo,
261 OLEFontImpl_GetIDsOfNames,
262 OLEFontImpl_Invoke
265 static ICOM_VTABLE(IPersistStream) OLEFontImpl_IPersistStream_VTable =
267 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
268 OLEFontImpl_IPersistStream_QueryInterface,
269 OLEFontImpl_IPersistStream_AddRef,
270 OLEFontImpl_IPersistStream_Release,
271 OLEFontImpl_GetClassID,
272 OLEFontImpl_IsDirty,
273 OLEFontImpl_Load,
274 OLEFontImpl_Save,
275 OLEFontImpl_GetSizeMax
278 static ICOM_VTABLE(IConnectionPointContainer)
279 OLEFontImpl_IConnectionPointContainer_VTable =
281 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
282 OLEFontImpl_IConnectionPointContainer_QueryInterface,
283 OLEFontImpl_IConnectionPointContainer_AddRef,
284 OLEFontImpl_IConnectionPointContainer_Release,
285 OLEFontImpl_EnumConnectionPoints,
286 OLEFontImpl_FindConnectionPoint
289 static ICOM_VTABLE(IPersistPropertyBag) OLEFontImpl_IPersistPropertyBag_VTable;
290 static ICOM_VTABLE(IPersistStreamInit) OLEFontImpl_IPersistStreamInit_VTable;
291 /******************************************************************************
292 * OleCreateFontIndirect [OLEAUT32.420]
294 HRESULT WINAPI OleCreateFontIndirect(
295 LPFONTDESC lpFontDesc,
296 REFIID riid,
297 LPVOID* ppvObj)
299 OLEFontImpl* newFont = 0;
300 HRESULT hr = S_OK;
302 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
304 * Sanity check
306 if (ppvObj==0)
307 return E_POINTER;
309 *ppvObj = 0;
311 if (!lpFontDesc) {
312 FONTDESC fd;
314 static const WCHAR fname[] = { 'S','y','s','t','e','m',0 };
316 fd.cbSizeofstruct = sizeof(fd);
317 fd.lpstrName = (WCHAR*)fname;
318 fd.cySize.s.Lo = 80000;
319 fd.cySize.s.Hi = 0;
320 fd.sWeight = 0;
321 fd.sCharset = 0;
322 fd.fItalic = 0;
323 fd.fUnderline = 0;
324 fd.fStrikethrough = 0;
325 lpFontDesc = &fd;
329 * Try to construct a new instance of the class.
331 newFont = OLEFontImpl_Construct(lpFontDesc);
333 if (newFont == 0)
334 return E_OUTOFMEMORY;
337 * Make sure it supports the interface required by the caller.
339 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
342 * Release the reference obtained in the constructor. If
343 * the QueryInterface was unsuccessful, it will free the class.
345 IFont_Release((IFont*)newFont);
347 return hr;
351 /***********************************************************************
352 * Implementation of the OLEFontImpl class.
355 /***********************************************************************
356 * OLEFont_SendNotify (internal)
358 * Sends notification messages of changed properties to any interested
359 * connections.
361 static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
363 IEnumConnections *pEnum;
364 CONNECTDATA CD;
365 HRESULT hres;
367 hres = IConnectionPoint_EnumConnections(this->pCP, &pEnum);
368 if (FAILED(hres)) /* When we have 0 connections. */
369 return;
371 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
372 IPropertyNotifySink *sink;
374 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
375 IPropertyNotifySink_OnChanged(sink, dispID);
376 IPropertyNotifySink_Release(sink);
377 IUnknown_Release(CD.pUnk);
379 IEnumConnections_Release(pEnum);
380 return;
383 /************************************************************************
384 * OLEFontImpl_Construct
386 * This method will construct a new instance of the OLEFontImpl
387 * class.
389 * The caller of this method must release the object when it's
390 * done with it.
392 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
394 OLEFontImpl* newObject = 0;
397 * Allocate space for the object.
399 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
401 if (newObject==0)
402 return newObject;
405 * Initialize the virtual function table.
407 newObject->lpvtbl1 = &OLEFontImpl_VTable;
408 newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;
409 newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
410 newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable;
411 newObject->lpvtbl5 = &OLEFontImpl_IPersistPropertyBag_VTable;
412 newObject->lpvtbl6 = &OLEFontImpl_IPersistStreamInit_VTable;
415 * Start with one reference count. The caller of this function
416 * must release the interface pointer when it is done.
418 newObject->ref = 1;
421 * Copy the description of the font in the object.
423 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
425 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
426 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
428 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
429 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
430 newObject->description.cySize = fontDesc->cySize;
431 newObject->description.sWeight = fontDesc->sWeight;
432 newObject->description.sCharset = fontDesc->sCharset;
433 newObject->description.fItalic = fontDesc->fItalic;
434 newObject->description.fUnderline = fontDesc->fUnderline;
435 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
438 * Initializing all the other members.
440 newObject->gdiFont = 0;
441 newObject->fontLock = 0;
442 newObject->cyLogical = 72L;
443 newObject->cyHimetric = 2540L;
444 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pCP);
445 TRACE("returning %p\n", newObject);
446 return newObject;
449 /************************************************************************
450 * OLEFontImpl_Destroy
452 * This method is called by the Release method when the reference
453 * count goes down to 0. It will free all resources used by
454 * this object.
456 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
458 TRACE("(%p)\n", fontDesc);
460 if (fontDesc->description.lpstrName!=0)
461 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
463 if (fontDesc->gdiFont!=0)
464 DeleteObject(fontDesc->gdiFont);
466 HeapFree(GetProcessHeap(), 0, fontDesc);
469 /************************************************************************
470 * OLEFontImpl_QueryInterface (IUnknown)
472 * See Windows documentation for more details on IUnknown methods.
474 HRESULT WINAPI OLEFontImpl_QueryInterface(
475 IFont* iface,
476 REFIID riid,
477 void** ppvObject)
479 _ICOM_THIS(OLEFontImpl, iface);
480 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
483 * Perform a sanity check on the parameters.
485 if ( (this==0) || (ppvObject==0) )
486 return E_INVALIDARG;
489 * Initialize the return parameter.
491 *ppvObject = 0;
494 * Compare the riid with the interface IDs implemented by this object.
496 if (IsEqualGUID(&IID_IUnknown, riid))
497 *ppvObject = (IFont*)this;
498 if (IsEqualGUID(&IID_IFont, riid))
499 *ppvObject = (IFont*)this;
500 if (IsEqualGUID(&IID_IDispatch, riid))
501 *ppvObject = (IDispatch*)&(this->lpvtbl2);
502 if (IsEqualGUID(&IID_IFontDisp, riid))
503 *ppvObject = (IDispatch*)&(this->lpvtbl2);
504 if (IsEqualGUID(&IID_IPersistStream, riid))
505 *ppvObject = (IPersistStream*)&(this->lpvtbl3);
506 if (IsEqualGUID(&IID_IConnectionPointContainer, riid))
507 *ppvObject = (IConnectionPointContainer*)&(this->lpvtbl4);
508 if (IsEqualGUID(&IID_IPersistPropertyBag, riid))
509 *ppvObject = (IPersistPropertyBag*)&(this->lpvtbl5);
510 if (IsEqualGUID(&IID_IPersistStreamInit, riid))
511 *ppvObject = (IPersistStreamInit*)&(this->lpvtbl6);
514 * Check that we obtained an interface.
516 if ((*ppvObject)==0)
518 FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid));
519 return E_NOINTERFACE;
521 OLEFontImpl_AddRef((IFont*)this);
522 return S_OK;
525 /************************************************************************
526 * OLEFontImpl_AddRef (IUnknown)
528 * See Windows documentation for more details on IUnknown methods.
530 ULONG WINAPI OLEFontImpl_AddRef(
531 IFont* iface)
533 _ICOM_THIS(OLEFontImpl, iface);
534 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
535 this->ref++;
537 return this->ref;
540 /************************************************************************
541 * OLEFontImpl_Release (IUnknown)
543 * See Windows documentation for more details on IUnknown methods.
545 ULONG WINAPI OLEFontImpl_Release(
546 IFont* iface)
548 _ICOM_THIS(OLEFontImpl, iface);
549 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
552 * Decrease the reference count on this object.
554 this->ref--;
557 * If the reference count goes down to 0, perform suicide.
559 if (this->ref==0)
561 OLEFontImpl_Destroy(this);
563 return 0;
566 return this->ref;
569 /************************************************************************
570 * OLEFontImpl_get_Name (IFont)
572 * See Windows documentation for more details on IFont methods.
574 static HRESULT WINAPI OLEFontImpl_get_Name(
575 IFont* iface,
576 BSTR* pname)
578 _ICOM_THIS(OLEFontImpl, iface);
579 TRACE("(%p)->(%p)\n", this, pname);
581 * Sanity check.
583 if (pname==0)
584 return E_POINTER;
586 if (this->description.lpstrName!=0)
587 *pname = SysAllocString(this->description.lpstrName);
588 else
589 *pname = 0;
591 return S_OK;
594 /************************************************************************
595 * OLEFontImpl_put_Name (IFont)
597 * See Windows documentation for more details on IFont methods.
599 static HRESULT WINAPI OLEFontImpl_put_Name(
600 IFont* iface,
601 BSTR name)
603 _ICOM_THIS(OLEFontImpl, iface);
604 TRACE("(%p)->(%p)\n", this, name);
606 if (this->description.lpstrName==0)
608 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
610 (lstrlenW(name)+1) * sizeof(WCHAR));
612 else
614 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
616 this->description.lpstrName,
617 (lstrlenW(name)+1) * sizeof(WCHAR));
620 if (this->description.lpstrName==0)
621 return E_OUTOFMEMORY;
623 strcpyW(this->description.lpstrName, name);
624 TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
625 OLEFont_SendNotify(this, DISPID_FONT_NAME);
626 return S_OK;
629 /************************************************************************
630 * OLEFontImpl_get_Size (IFont)
632 * See Windows documentation for more details on IFont methods.
634 static HRESULT WINAPI OLEFontImpl_get_Size(
635 IFont* iface,
636 CY* psize)
638 _ICOM_THIS(OLEFontImpl, iface);
639 TRACE("(%p)->(%p)\n", this, psize);
642 * Sanity check
644 if (psize==0)
645 return E_POINTER;
647 psize->s.Hi = 0;
648 psize->s.Lo = this->description.cySize.s.Lo;
650 return S_OK;
653 /************************************************************************
654 * OLEFontImpl_put_Size (IFont)
656 * See Windows documentation for more details on IFont methods.
658 static HRESULT WINAPI OLEFontImpl_put_Size(
659 IFont* iface,
660 CY size)
662 _ICOM_THIS(OLEFontImpl, iface);
663 TRACE("(%p)->(%ld)\n", this, size.s.Lo);
664 this->description.cySize.s.Hi = 0;
665 this->description.cySize.s.Lo = size.s.Lo;
666 OLEFont_SendNotify(this, DISPID_FONT_SIZE);
668 return S_OK;
671 /************************************************************************
672 * OLEFontImpl_get_Bold (IFont)
674 * See Windows documentation for more details on IFont methods.
676 static HRESULT WINAPI OLEFontImpl_get_Bold(
677 IFont* iface,
678 BOOL* pbold)
680 _ICOM_THIS(OLEFontImpl, iface);
681 TRACE("(%p)->(%p)\n", this, pbold);
683 * Sanity check
685 if (pbold==0)
686 return E_POINTER;
688 *pbold = this->description.sWeight > 550;
690 return S_OK;
693 /************************************************************************
694 * OLEFontImpl_put_Bold (IFont)
696 * See Windows documentation for more details on IFont methods.
698 static HRESULT WINAPI OLEFontImpl_put_Bold(
699 IFont* iface,
700 BOOL bold)
702 _ICOM_THIS(OLEFontImpl, iface);
703 TRACE("(%p)->(%d)\n", this, bold);
704 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
705 OLEFont_SendNotify(this, DISPID_FONT_BOLD);
707 return S_OK;
710 /************************************************************************
711 * OLEFontImpl_get_Italic (IFont)
713 * See Windows documentation for more details on IFont methods.
715 static HRESULT WINAPI OLEFontImpl_get_Italic(
716 IFont* iface,
717 BOOL* pitalic)
719 _ICOM_THIS(OLEFontImpl, iface);
720 TRACE("(%p)->(%p)\n", this, pitalic);
722 * Sanity check
724 if (pitalic==0)
725 return E_POINTER;
727 *pitalic = this->description.fItalic;
729 return S_OK;
732 /************************************************************************
733 * OLEFontImpl_put_Italic (IFont)
735 * See Windows documentation for more details on IFont methods.
737 static HRESULT WINAPI OLEFontImpl_put_Italic(
738 IFont* iface,
739 BOOL italic)
741 _ICOM_THIS(OLEFontImpl, iface);
742 TRACE("(%p)->(%d)\n", this, italic);
744 this->description.fItalic = italic;
746 OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
747 return S_OK;
750 /************************************************************************
751 * OLEFontImpl_get_Underline (IFont)
753 * See Windows documentation for more details on IFont methods.
755 static HRESULT WINAPI OLEFontImpl_get_Underline(
756 IFont* iface,
757 BOOL* punderline)
759 _ICOM_THIS(OLEFontImpl, iface);
760 TRACE("(%p)->(%p)\n", this, punderline);
763 * Sanity check
765 if (punderline==0)
766 return E_POINTER;
768 *punderline = this->description.fUnderline;
770 return S_OK;
773 /************************************************************************
774 * OLEFontImpl_put_Underline (IFont)
776 * See Windows documentation for more details on IFont methods.
778 static HRESULT WINAPI OLEFontImpl_put_Underline(
779 IFont* iface,
780 BOOL underline)
782 _ICOM_THIS(OLEFontImpl, iface);
783 TRACE("(%p)->(%d)\n", this, underline);
785 this->description.fUnderline = underline;
787 OLEFont_SendNotify(this, DISPID_FONT_UNDER);
788 return S_OK;
791 /************************************************************************
792 * OLEFontImpl_get_Strikethrough (IFont)
794 * See Windows documentation for more details on IFont methods.
796 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
797 IFont* iface,
798 BOOL* pstrikethrough)
800 _ICOM_THIS(OLEFontImpl, iface);
801 TRACE("(%p)->(%p)\n", this, pstrikethrough);
804 * Sanity check
806 if (pstrikethrough==0)
807 return E_POINTER;
809 *pstrikethrough = this->description.fStrikethrough;
811 return S_OK;
814 /************************************************************************
815 * OLEFontImpl_put_Strikethrough (IFont)
817 * See Windows documentation for more details on IFont methods.
819 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
820 IFont* iface,
821 BOOL strikethrough)
823 _ICOM_THIS(OLEFontImpl, iface);
824 TRACE("(%p)->(%d)\n", this, strikethrough);
826 this->description.fStrikethrough = strikethrough;
827 OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
829 return S_OK;
832 /************************************************************************
833 * OLEFontImpl_get_Weight (IFont)
835 * See Windows documentation for more details on IFont methods.
837 static HRESULT WINAPI OLEFontImpl_get_Weight(
838 IFont* iface,
839 short* pweight)
841 _ICOM_THIS(OLEFontImpl, iface);
842 TRACE("(%p)->(%p)\n", this, pweight);
845 * Sanity check
847 if (pweight==0)
848 return E_POINTER;
850 *pweight = this->description.sWeight;
852 return S_OK;
855 /************************************************************************
856 * OLEFontImpl_put_Weight (IFont)
858 * See Windows documentation for more details on IFont methods.
860 static HRESULT WINAPI OLEFontImpl_put_Weight(
861 IFont* iface,
862 short weight)
864 _ICOM_THIS(OLEFontImpl, iface);
865 TRACE("(%p)->(%d)\n", this, weight);
867 this->description.sWeight = weight;
869 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
870 return S_OK;
873 /************************************************************************
874 * OLEFontImpl_get_Charset (IFont)
876 * See Windows documentation for more details on IFont methods.
878 static HRESULT WINAPI OLEFontImpl_get_Charset(
879 IFont* iface,
880 short* pcharset)
882 _ICOM_THIS(OLEFontImpl, iface);
883 TRACE("(%p)->(%p)\n", this, pcharset);
886 * Sanity check
888 if (pcharset==0)
889 return E_POINTER;
891 *pcharset = this->description.sCharset;
893 return S_OK;
896 /************************************************************************
897 * OLEFontImpl_put_Charset (IFont)
899 * See Windows documentation for more details on IFont methods.
901 static HRESULT WINAPI OLEFontImpl_put_Charset(
902 IFont* iface,
903 short charset)
905 _ICOM_THIS(OLEFontImpl, iface);
906 TRACE("(%p)->(%d)\n", this, charset);
908 this->description.sCharset = charset;
909 OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
911 return S_OK;
914 /************************************************************************
915 * OLEFontImpl_get_hFont (IFont)
917 * See Windows documentation for more details on IFont methods.
919 static HRESULT WINAPI OLEFontImpl_get_hFont(
920 IFont* iface,
921 HFONT* phfont)
923 _ICOM_THIS(OLEFontImpl, iface);
924 TRACE("(%p)->(%p)\n", this, phfont);
925 if (phfont==NULL)
926 return E_POINTER;
929 * Realize the font if necessary
931 if (this->gdiFont==0)
933 LOGFONTW logFont;
934 INT fontHeight;
935 CY cySize;
938 * The height of the font returned by the get_Size property is the
939 * height of the font in points multiplied by 10000... Using some
940 * simple conversions and the ratio given by the application, it can
941 * be converted to a height in pixels.
943 IFont_get_Size(iface, &cySize);
945 fontHeight = MulDiv( cySize.s.Lo, this->cyLogical, this->cyHimetric );
947 memset(&logFont, 0, sizeof(LOGFONTW));
949 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
950 (-fontHeight/10000L);
951 logFont.lfItalic = this->description.fItalic;
952 logFont.lfUnderline = this->description.fUnderline;
953 logFont.lfStrikeOut = this->description.fStrikethrough;
954 logFont.lfWeight = this->description.sWeight;
955 logFont.lfCharSet = this->description.sCharset;
956 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
957 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
958 logFont.lfQuality = DEFAULT_QUALITY;
959 logFont.lfPitchAndFamily = DEFAULT_PITCH;
960 strcpyW(logFont.lfFaceName,this->description.lpstrName);
962 this->gdiFont = CreateFontIndirectW(&logFont);
965 *phfont = this->gdiFont;
966 TRACE("Returning %p\n", *phfont);
967 return S_OK;
970 /************************************************************************
971 * OLEFontImpl_Clone (IFont)
973 * See Windows documentation for more details on IFont methods.
975 static HRESULT WINAPI OLEFontImpl_Clone(
976 IFont* iface,
977 IFont** ppfont)
979 OLEFontImpl* newObject = 0;
980 LOGFONTW logFont;
981 INT fontHeight;
982 CY cySize;
983 _ICOM_THIS(OLEFontImpl, iface);
984 TRACE("(%p)->(%p)\n", this, ppfont);
986 if (ppfont == NULL)
987 return E_POINTER;
989 *ppfont = NULL;
992 * Allocate space for the object.
994 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
996 if (newObject==NULL)
997 return E_OUTOFMEMORY;
999 *newObject = *this;
1001 /* We need to alloc new memory for the string, otherwise
1002 * we free memory twice.
1004 newObject->description.lpstrName = HeapAlloc(
1005 GetProcessHeap(),0,
1006 (1+strlenW(this->description.lpstrName))*2
1008 strcpyW(newObject->description.lpstrName, this->description.lpstrName);
1009 /* We need to clone the HFONT too. This is just cut & paste from above */
1010 IFont_get_Size(iface, &cySize);
1012 fontHeight = MulDiv(cySize.s.Lo, this->cyLogical,this->cyHimetric);
1014 memset(&logFont, 0, sizeof(LOGFONTW));
1016 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
1017 (-fontHeight/10000L);
1018 logFont.lfItalic = this->description.fItalic;
1019 logFont.lfUnderline = this->description.fUnderline;
1020 logFont.lfStrikeOut = this->description.fStrikethrough;
1021 logFont.lfWeight = this->description.sWeight;
1022 logFont.lfCharSet = this->description.sCharset;
1023 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
1024 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1025 logFont.lfQuality = DEFAULT_QUALITY;
1026 logFont.lfPitchAndFamily = DEFAULT_PITCH;
1027 strcpyW(logFont.lfFaceName,this->description.lpstrName);
1029 newObject->gdiFont = CreateFontIndirectW(&logFont);
1032 /* The cloned object starts with a reference count of 1 */
1033 newObject->ref = 1;
1035 *ppfont = (IFont*)newObject;
1037 return S_OK;
1040 /************************************************************************
1041 * OLEFontImpl_IsEqual (IFont)
1043 * See Windows documentation for more details on IFont methods.
1045 static HRESULT WINAPI OLEFontImpl_IsEqual(
1046 IFont* iface,
1047 IFont* pFontOther)
1049 FIXME("(%p, %p), stub!\n",iface,pFontOther);
1050 return E_NOTIMPL;
1053 /************************************************************************
1054 * OLEFontImpl_SetRatio (IFont)
1056 * See Windows documentation for more details on IFont methods.
1058 static HRESULT WINAPI OLEFontImpl_SetRatio(
1059 IFont* iface,
1060 long cyLogical,
1061 long cyHimetric)
1063 _ICOM_THIS(OLEFontImpl, iface);
1064 TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric);
1066 this->cyLogical = cyLogical;
1067 this->cyHimetric = cyHimetric;
1069 return S_OK;
1072 /************************************************************************
1073 * OLEFontImpl_QueryTextMetrics (IFont)
1075 * See Windows documentation for more details on IFont methods.
1077 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
1078 IFont* iface,
1079 TEXTMETRICOLE* ptm)
1081 FIXME("(%p, %p), stub!\n",iface,ptm);
1082 return E_NOTIMPL;
1085 /************************************************************************
1086 * OLEFontImpl_AddRefHfont (IFont)
1088 * See Windows documentation for more details on IFont methods.
1090 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
1091 IFont* iface,
1092 HFONT hfont)
1094 _ICOM_THIS(OLEFontImpl, iface);
1095 TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
1097 if ( (hfont == 0) ||
1098 (hfont != this->gdiFont) )
1099 return E_INVALIDARG;
1101 this->fontLock++;
1103 return S_OK;
1106 /************************************************************************
1107 * OLEFontImpl_ReleaseHfont (IFont)
1109 * See Windows documentation for more details on IFont methods.
1111 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
1112 IFont* iface,
1113 HFONT hfont)
1115 _ICOM_THIS(OLEFontImpl, iface);
1116 TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
1118 if ( (hfont == 0) ||
1119 (hfont != this->gdiFont) )
1120 return E_INVALIDARG;
1122 this->fontLock--;
1125 * If we just released our last font reference, destroy it.
1127 if (this->fontLock==0)
1129 DeleteObject(this->gdiFont);
1130 this->gdiFont = 0;
1133 return S_OK;
1136 /************************************************************************
1137 * OLEFontImpl_SetHdc (IFont)
1139 * See Windows documentation for more details on IFont methods.
1141 static HRESULT WINAPI OLEFontImpl_SetHdc(
1142 IFont* iface,
1143 HDC hdc)
1145 _ICOM_THIS(OLEFontImpl, iface);
1146 FIXME("(%p)->(%p): Stub\n", this, hdc);
1147 return E_NOTIMPL;
1150 /************************************************************************
1151 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1153 * See Windows documentation for more details on IUnknown methods.
1155 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
1156 IDispatch* iface,
1157 REFIID riid,
1158 VOID** ppvoid)
1160 _ICOM_THIS_From_IDispatch(IFont, iface);
1162 return IFont_QueryInterface(this, riid, ppvoid);
1165 /************************************************************************
1166 * OLEFontImpl_IDispatch_Release (IUnknown)
1168 * See Windows documentation for more details on IUnknown methods.
1170 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1171 IDispatch* iface)
1173 _ICOM_THIS_From_IDispatch(IFont, iface);
1175 return IFont_Release(this);
1178 /************************************************************************
1179 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1181 * See Windows documentation for more details on IUnknown methods.
1183 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1184 IDispatch* iface)
1186 _ICOM_THIS_From_IDispatch(IFont, iface);
1188 return IFont_AddRef(this);
1191 /************************************************************************
1192 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1194 * See Windows documentation for more details on IDispatch methods.
1196 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1197 IDispatch* iface,
1198 unsigned int* pctinfo)
1200 _ICOM_THIS_From_IDispatch(IFont, iface);
1201 FIXME("(%p)->(%p): Stub\n", this, pctinfo);
1203 return E_NOTIMPL;
1206 /************************************************************************
1207 * OLEFontImpl_GetTypeInfo (IDispatch)
1209 * See Windows documentation for more details on IDispatch methods.
1211 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1212 IDispatch* iface,
1213 UINT iTInfo,
1214 LCID lcid,
1215 ITypeInfo** ppTInfo)
1217 static const WCHAR stdole32tlb[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0};
1218 ITypeLib *tl;
1219 HRESULT hres;
1221 _ICOM_THIS_From_IDispatch(OLEFontImpl, iface);
1222 TRACE("(%p, iTInfo=%d, lcid=%04x, %p), unimplemented stub!\n", this, iTInfo, (int)lcid, ppTInfo);
1223 if (iTInfo != 0)
1224 return E_FAIL;
1225 hres = LoadTypeLib(stdole32tlb, &tl);
1226 if (FAILED(hres)) {
1227 FIXME("Could not load the stdole32.tlb?\n");
1228 return hres;
1230 hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IDispatch, ppTInfo);
1231 if (FAILED(hres)) {
1232 FIXME("Did not IDispatch typeinfo from typelib, hres %lx\n",hres);
1234 return hres;
1237 /************************************************************************
1238 * OLEFontImpl_GetIDsOfNames (IDispatch)
1240 * See Windows documentation for more details on IDispatch methods.
1242 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1243 IDispatch* iface,
1244 REFIID riid,
1245 LPOLESTR* rgszNames,
1246 UINT cNames,
1247 LCID lcid,
1248 DISPID* rgDispId)
1250 _ICOM_THIS_From_IDispatch(IFont, iface);
1251 FIXME("(%p,%s,%p,%d,%04x,%p), stub!\n", this, debugstr_guid(riid), rgszNames,
1252 cNames, (int)lcid, rgDispId
1254 return E_NOTIMPL;
1257 /************************************************************************
1258 * OLEFontImpl_Invoke (IDispatch)
1260 * See Windows documentation for more details on IDispatch methods.
1262 * Note: Do not call _put_Xxx methods, since setting things here
1263 * should not call notify functions as I found out debugging the generic
1264 * MS VB5 installer.
1266 static HRESULT WINAPI OLEFontImpl_Invoke(
1267 IDispatch* iface,
1268 DISPID dispIdMember,
1269 REFIID riid,
1270 LCID lcid,
1271 WORD wFlags,
1272 DISPPARAMS* pDispParams,
1273 VARIANT* pVarResult,
1274 EXCEPINFO* pExepInfo,
1275 UINT* puArgErr)
1277 _ICOM_THIS_From_IDispatch(IFont, iface);
1278 OLEFontImpl *xthis = (OLEFontImpl*)this;
1280 switch (dispIdMember) {
1281 case DISPID_FONT_NAME:
1282 switch (wFlags) {
1283 case DISPATCH_PROPERTYGET:
1284 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1285 V_VT(pVarResult) = VT_BSTR;
1286 return OLEFontImpl_get_Name(this, &V_BSTR(pVarResult));
1287 case DISPATCH_PROPERTYPUT: {
1288 BSTR name = V_BSTR(&pDispParams->rgvarg[0]);
1289 if (V_VT(&pDispParams->rgvarg[0])!=VT_BSTR) {
1290 FIXME("property put of Name, vt is not VT_BSTR but %d\n",V_VT(&pDispParams->rgvarg[0]));
1291 return E_FAIL;
1293 if (!xthis->description.lpstrName)
1294 xthis->description.lpstrName = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name)+1) * sizeof(WCHAR));
1295 else
1296 xthis->description.lpstrName = HeapReAlloc(GetProcessHeap(), 0, xthis->description.lpstrName, (lstrlenW(name)+1) * sizeof(WCHAR));
1298 if (xthis->description.lpstrName==0)
1299 return E_OUTOFMEMORY;
1300 strcpyW(xthis->description.lpstrName, name);
1301 return S_OK;
1304 break;
1305 case DISPID_FONT_BOLD:
1306 switch (wFlags) {
1307 case DISPATCH_PROPERTYGET:
1308 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1309 V_VT(pVarResult) = VT_BOOL;
1310 return OLEFontImpl_get_Bold(this, (BOOL*)&V_BOOL(pVarResult));
1311 case DISPATCH_PROPERTYPUT:
1312 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
1313 FIXME("DISPID_FONT_BOLD/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
1314 return E_FAIL;
1315 } else {
1316 xthis->description.sWeight = V_BOOL(&pDispParams->rgvarg[0]) ? FW_BOLD : FW_NORMAL;
1317 return S_OK;
1320 break;
1321 case DISPID_FONT_ITALIC:
1322 switch (wFlags) {
1323 case DISPATCH_PROPERTYGET:
1324 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1325 V_VT(pVarResult) = VT_BOOL;
1326 return OLEFontImpl_get_Italic(this, (BOOL*)&V_BOOL(pVarResult));
1327 case DISPATCH_PROPERTYPUT:
1328 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
1329 FIXME("DISPID_FONT_ITALIC/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
1330 return E_FAIL;
1331 } else {
1332 xthis->description.fItalic = V_BOOL(&pDispParams->rgvarg[0]);
1333 return S_OK;
1336 break;
1337 case DISPID_FONT_UNDER:
1338 switch (wFlags) {
1339 case DISPATCH_PROPERTYGET:
1340 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1341 V_VT(pVarResult) = VT_BOOL;
1342 return OLEFontImpl_get_Underline(this, (BOOL*)&V_BOOL(pVarResult));
1343 case DISPATCH_PROPERTYPUT:
1344 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
1345 FIXME("DISPID_FONT_UNDER/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
1346 return E_FAIL;
1347 } else {
1348 xthis->description.fUnderline = V_BOOL(&pDispParams->rgvarg[0]);
1349 return S_OK;
1352 break;
1353 case DISPID_FONT_STRIKE:
1354 switch (wFlags) {
1355 case DISPATCH_PROPERTYGET:
1356 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1357 V_VT(pVarResult) = VT_BOOL;
1358 return OLEFontImpl_get_Strikethrough(this, (BOOL*)&V_BOOL(pVarResult));
1359 case DISPATCH_PROPERTYPUT:
1360 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
1361 FIXME("DISPID_FONT_STRIKE/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
1362 return E_FAIL;
1363 } else {
1364 xthis->description.fStrikethrough = V_BOOL(&pDispParams->rgvarg[0]);
1365 return S_OK;
1368 break;
1369 case DISPID_FONT_SIZE:
1370 switch (wFlags) {
1371 case DISPATCH_PROPERTYPUT: {
1372 assert (pDispParams->cArgs == 1);
1373 xthis->description.cySize.s.Hi = 0;
1374 if (V_VT(&pDispParams->rgvarg[0]) != VT_CY) {
1375 if (V_VT(&pDispParams->rgvarg[0]) == VT_I2) {
1376 xthis->description.cySize.s.Lo = V_I2(&pDispParams->rgvarg[0]) * 10000;
1377 } else {
1378 FIXME("property put for Size with vt %d unsupported!\n",V_VT(&pDispParams->rgvarg[0]));
1380 } else {
1381 xthis->description.cySize.s.Lo = V_CY(&pDispParams->rgvarg[0]).s.Lo;
1383 return S_OK;
1385 case DISPATCH_PROPERTYGET:
1386 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1387 V_VT(pVarResult) = VT_CY;
1388 return OLEFontImpl_get_Size(this, &V_CY(pVarResult));
1390 break;
1391 case DISPID_FONT_CHARSET:
1392 switch (wFlags) {
1393 case DISPATCH_PROPERTYPUT:
1394 assert (pDispParams->cArgs == 1);
1395 if (V_VT(&pDispParams->rgvarg[0]) != VT_I2)
1396 FIXME("varg of first disparg is not VT_I2, but %d\n",V_VT(&pDispParams->rgvarg[0]));
1397 xthis->description.sCharset = V_I2(&pDispParams->rgvarg[0]);
1398 return S_OK;
1399 case DISPATCH_PROPERTYGET:
1400 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1401 V_VT(pVarResult) = VT_I2;
1402 return OLEFontImpl_get_Charset(this, &V_I2(pVarResult));
1404 break;
1406 FIXME("%p->(%ld,%s,%lx,%x,%p,%p,%p,%p), unhandled dispid/flag!\n",
1407 this,dispIdMember,debugstr_guid(riid),lcid,
1408 wFlags,pDispParams,pVarResult,pExepInfo,puArgErr
1410 return S_OK;
1413 /************************************************************************
1414 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1416 * See Windows documentation for more details on IUnknown methods.
1418 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1419 IPersistStream* iface,
1420 REFIID riid,
1421 VOID** ppvoid)
1423 _ICOM_THIS_From_IPersistStream(IFont, iface);
1425 return IFont_QueryInterface(this, riid, ppvoid);
1428 /************************************************************************
1429 * OLEFontImpl_IPersistStream_Release (IUnknown)
1431 * See Windows documentation for more details on IUnknown methods.
1433 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1434 IPersistStream* iface)
1436 _ICOM_THIS_From_IPersistStream(IFont, iface);
1438 return IFont_Release(this);
1441 /************************************************************************
1442 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1444 * See Windows documentation for more details on IUnknown methods.
1446 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1447 IPersistStream* iface)
1449 _ICOM_THIS_From_IPersistStream(IFont, iface);
1451 return IFont_AddRef(this);
1454 /************************************************************************
1455 * OLEFontImpl_GetClassID (IPersistStream)
1457 * See Windows documentation for more details on IPersistStream methods.
1459 static HRESULT WINAPI OLEFontImpl_GetClassID(
1460 IPersistStream* iface,
1461 CLSID* pClassID)
1463 TRACE("(%p,%p)\n",iface,pClassID);
1464 if (pClassID==0)
1465 return E_POINTER;
1467 memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));
1469 return S_OK;
1472 /************************************************************************
1473 * OLEFontImpl_IsDirty (IPersistStream)
1475 * See Windows documentation for more details on IPersistStream methods.
1477 static HRESULT WINAPI OLEFontImpl_IsDirty(
1478 IPersistStream* iface)
1480 TRACE("(%p)\n",iface);
1481 return S_OK;
1484 /************************************************************************
1485 * OLEFontImpl_Load (IPersistStream)
1487 * See Windows documentation for more details on IPersistStream methods.
1489 * This is the format of the standard font serialization as far as I
1490 * know
1492 * Offset Type Value Comment
1493 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1494 * 0x0001 Short Charset Charset value from the FONTDESC structure
1495 * 0x0003 Byte Attributes Flags defined as follows:
1496 * 00000010 - Italic
1497 * 00000100 - Underline
1498 * 00001000 - Strikethrough
1499 * 0x0004 Short Weight Weight value from FONTDESC structure
1500 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1501 * structure/
1502 * 0x000A Byte name length Length of the font name string (no null character)
1503 * 0x000B String name Name of the font (ASCII, no nul character)
1505 static HRESULT WINAPI OLEFontImpl_Load(
1506 IPersistStream* iface,
1507 IStream* pLoadStream)
1509 char readBuffer[0x100];
1510 ULONG cbRead;
1511 BYTE bVersion;
1512 BYTE bAttributes;
1513 BYTE bStringSize;
1514 INT len;
1516 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1519 * Read the version byte
1521 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1523 if ( (cbRead!=1) ||
1524 (bVersion!=0x01) )
1525 return E_FAIL;
1528 * Charset
1530 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1532 if (cbRead!=2)
1533 return E_FAIL;
1536 * Attributes
1538 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1540 if (cbRead!=1)
1541 return E_FAIL;
1543 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1544 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1545 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1548 * Weight
1550 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1552 if (cbRead!=2)
1553 return E_FAIL;
1556 * Size
1558 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
1560 if (cbRead!=4)
1561 return E_FAIL;
1563 this->description.cySize.s.Hi = 0;
1566 * FontName
1568 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1570 if (cbRead!=1)
1571 return E_FAIL;
1573 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1575 if (cbRead!=bStringSize)
1576 return E_FAIL;
1578 if (this->description.lpstrName!=0)
1579 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1581 len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );
1582 this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
1583 MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
1584 this->description.lpstrName[len] = 0;
1586 /* Ensure use of this font causes a new one to be created @@@@ */
1587 DeleteObject(this->gdiFont);
1588 this->gdiFont = 0;
1590 return S_OK;
1593 /************************************************************************
1594 * OLEFontImpl_Save (IPersistStream)
1596 * See Windows documentation for more details on IPersistStream methods.
1598 static HRESULT WINAPI OLEFontImpl_Save(
1599 IPersistStream* iface,
1600 IStream* pOutStream,
1601 BOOL fClearDirty)
1603 char* writeBuffer = NULL;
1604 ULONG cbWritten;
1605 BYTE bVersion = 0x01;
1606 BYTE bAttributes;
1607 BYTE bStringSize;
1609 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1612 * Read the version byte
1614 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1616 if (cbWritten!=1)
1617 return E_FAIL;
1620 * Charset
1622 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1624 if (cbWritten!=2)
1625 return E_FAIL;
1628 * Attributes
1630 bAttributes = 0;
1632 if (this->description.fItalic)
1633 bAttributes |= FONTPERSIST_ITALIC;
1635 if (this->description.fStrikethrough)
1636 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1638 if (this->description.fUnderline)
1639 bAttributes |= FONTPERSIST_UNDERLINE;
1641 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1643 if (cbWritten!=1)
1644 return E_FAIL;
1647 * Weight
1649 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1651 if (cbWritten!=2)
1652 return E_FAIL;
1655 * Size
1657 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
1659 if (cbWritten!=4)
1660 return E_FAIL;
1663 * FontName
1665 if (this->description.lpstrName!=0)
1666 bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1667 strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
1668 else
1669 bStringSize = 0;
1671 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1673 if (cbWritten!=1)
1674 return E_FAIL;
1676 if (bStringSize!=0)
1678 if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;
1679 WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1680 strlenW(this->description.lpstrName),
1681 writeBuffer, bStringSize, NULL, NULL );
1683 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1684 HeapFree(GetProcessHeap(), 0, writeBuffer);
1686 if (cbWritten!=bStringSize)
1687 return E_FAIL;
1690 return S_OK;
1693 /************************************************************************
1694 * OLEFontImpl_GetSizeMax (IPersistStream)
1696 * See Windows documentation for more details on IPersistStream methods.
1698 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1699 IPersistStream* iface,
1700 ULARGE_INTEGER* pcbSize)
1702 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1704 if (pcbSize==NULL)
1705 return E_POINTER;
1707 pcbSize->u.HighPart = 0;
1708 pcbSize->u.LowPart = 0;
1710 pcbSize->u.LowPart += sizeof(BYTE); /* Version */
1711 pcbSize->u.LowPart += sizeof(WORD); /* Lang code */
1712 pcbSize->u.LowPart += sizeof(BYTE); /* Flags */
1713 pcbSize->u.LowPart += sizeof(WORD); /* Weight */
1714 pcbSize->u.LowPart += sizeof(DWORD); /* Size */
1715 pcbSize->u.LowPart += sizeof(BYTE); /* StrLength */
1717 if (this->description.lpstrName!=0)
1718 pcbSize->u.LowPart += lstrlenW(this->description.lpstrName);
1720 return S_OK;
1723 /************************************************************************
1724 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1726 * See Windows documentation for more details on IUnknown methods.
1728 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
1729 IConnectionPointContainer* iface,
1730 REFIID riid,
1731 VOID** ppvoid)
1733 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1735 return IFont_QueryInterface((IFont*)this, riid, ppvoid);
1738 /************************************************************************
1739 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1741 * See Windows documentation for more details on IUnknown methods.
1743 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
1744 IConnectionPointContainer* iface)
1746 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1748 return IFont_Release((IFont*)this);
1751 /************************************************************************
1752 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1754 * See Windows documentation for more details on IUnknown methods.
1756 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
1757 IConnectionPointContainer* iface)
1759 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1761 return IFont_AddRef((IFont*)this);
1764 /************************************************************************
1765 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1767 * See Windows documentation for more details on IConnectionPointContainer
1768 * methods.
1770 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
1771 IConnectionPointContainer* iface,
1772 IEnumConnectionPoints **ppEnum)
1774 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1776 FIXME("(%p)->(%p): stub\n", this, ppEnum);
1777 return E_NOTIMPL;
1780 /************************************************************************
1781 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1783 * See Windows documentation for more details on IConnectionPointContainer
1784 * methods.
1786 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
1787 IConnectionPointContainer* iface,
1788 REFIID riid,
1789 IConnectionPoint **ppCp)
1791 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1792 TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp);
1794 if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) {
1795 return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint,
1796 (LPVOID)ppCp);
1797 } else {
1798 FIXME("Tried to find connection point on %s\n", debugstr_guid(riid));
1799 return E_NOINTERFACE;
1803 /************************************************************************
1804 * OLEFontImpl implementation of IPersistPropertyBag.
1806 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface(
1807 IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj
1809 _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);
1810 return IFont_QueryInterface(this,riid,ppvObj);
1813 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef(
1814 IPersistPropertyBag *iface
1816 _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);
1817 return IFont_AddRef(this);
1820 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release(
1821 IPersistPropertyBag *iface
1823 _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);
1824 return IFont_Release(this);
1827 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID(
1828 IPersistPropertyBag *iface, CLSID *classid
1830 FIXME("(%p,%p), stub!\n", iface, classid);
1831 return E_FAIL;
1834 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew(
1835 IPersistPropertyBag *iface
1837 FIXME("(%p), stub!\n", iface);
1838 return S_OK;
1841 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load(
1842 IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog
1844 FIXME("(%p,%p,%p), stub!\n", iface, pPropBag, pErrorLog);
1845 return E_FAIL;
1848 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save(
1849 IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty,
1850 BOOL fSaveAllProperties
1852 FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties);
1853 return E_FAIL;
1856 static ICOM_VTABLE(IPersistPropertyBag) OLEFontImpl_IPersistPropertyBag_VTable =
1858 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1859 OLEFontImpl_IPersistPropertyBag_QueryInterface,
1860 OLEFontImpl_IPersistPropertyBag_AddRef,
1861 OLEFontImpl_IPersistPropertyBag_Release,
1863 OLEFontImpl_IPersistPropertyBag_GetClassID,
1864 OLEFontImpl_IPersistPropertyBag_InitNew,
1865 OLEFontImpl_IPersistPropertyBag_Load,
1866 OLEFontImpl_IPersistPropertyBag_Save
1869 /************************************************************************
1870 * OLEFontImpl implementation of IPersistStreamInit.
1872 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface(
1873 IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj
1875 _ICOM_THIS_From_IPersistStreamInit(IFont, iface);
1876 return IFont_QueryInterface(this,riid,ppvObj);
1879 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef(
1880 IPersistStreamInit *iface
1882 _ICOM_THIS_From_IPersistStreamInit(IFont, iface);
1883 return IFont_AddRef(this);
1886 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release(
1887 IPersistStreamInit *iface
1889 _ICOM_THIS_From_IPersistStreamInit(IFont, iface);
1890 return IFont_Release(this);
1893 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID(
1894 IPersistStreamInit *iface, CLSID *classid
1896 FIXME("(%p,%p), stub!\n", iface, classid);
1897 return E_FAIL;
1900 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty(
1901 IPersistStreamInit *iface
1903 FIXME("(%p), stub!\n", iface);
1904 return E_FAIL;
1907 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load(
1908 IPersistStreamInit *iface, LPSTREAM pStm
1910 FIXME("(%p,%p), stub!\n", iface, pStm);
1911 return E_FAIL;
1914 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save(
1915 IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty
1917 FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty);
1918 return E_FAIL;
1921 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax(
1922 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize
1924 FIXME("(%p,%p), stub!\n", iface, pcbSize);
1925 return E_FAIL;
1928 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew(
1929 IPersistStreamInit *iface
1931 FIXME("(%p), stub!\n", iface);
1932 return S_OK;
1935 static ICOM_VTABLE(IPersistStreamInit) OLEFontImpl_IPersistStreamInit_VTable =
1937 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1938 OLEFontImpl_IPersistStreamInit_QueryInterface,
1939 OLEFontImpl_IPersistStreamInit_AddRef,
1940 OLEFontImpl_IPersistStreamInit_Release,
1942 OLEFontImpl_IPersistStreamInit_GetClassID,
1943 OLEFontImpl_IPersistStreamInit_IsDirty,
1944 OLEFontImpl_IPersistStreamInit_Load,
1945 OLEFontImpl_IPersistStreamInit_Save,
1946 OLEFontImpl_IPersistStreamInit_GetSizeMax,
1947 OLEFontImpl_IPersistStreamInit_InitNew
1950 /*******************************************************************************
1951 * StdFont ClassFactory
1953 typedef struct
1955 /* IUnknown fields */
1956 ICOM_VFIELD(IClassFactory);
1957 DWORD ref;
1958 } IClassFactoryImpl;
1960 static HRESULT WINAPI
1961 SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
1962 ICOM_THIS(IClassFactoryImpl,iface);
1964 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
1965 return E_NOINTERFACE;
1968 static ULONG WINAPI
1969 SFCF_AddRef(LPCLASSFACTORY iface) {
1970 ICOM_THIS(IClassFactoryImpl,iface);
1971 return ++(This->ref);
1974 static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
1975 ICOM_THIS(IClassFactoryImpl,iface);
1976 /* static class, won't be freed */
1977 return --(This->ref);
1980 static HRESULT WINAPI SFCF_CreateInstance(
1981 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
1983 return OleCreateFontIndirect(NULL,riid,ppobj);
1987 static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
1988 ICOM_THIS(IClassFactoryImpl,iface);
1989 FIXME("(%p)->(%d),stub!\n",This,dolock);
1990 return S_OK;
1993 static ICOM_VTABLE(IClassFactory) SFCF_Vtbl = {
1994 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1995 SFCF_QueryInterface,
1996 SFCF_AddRef,
1997 SFCF_Release,
1998 SFCF_CreateInstance,
1999 SFCF_LockServer
2001 static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };
2003 void _get_STDFONT_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDFONT_CF; }