| /* |
| * OLE Font encapsulation implementation |
| * |
| * This file contains an implementation of the IFont |
| * interface and the OleCreateFontIndirect API call. |
| * |
| * Copyright 1999 Francis Beaudet |
| * Copyright 2006 (Google) Benjamin Arai |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| #include <assert.h> |
| #include <stdarg.h> |
| #include <string.h> |
| |
| #define COBJMACROS |
| #define NONAMELESSUNION |
| #define NONAMELESSSTRUCT |
| |
| #include "winerror.h" |
| #include "windef.h" |
| #include "winbase.h" |
| #include "wingdi.h" |
| #include "winuser.h" |
| #include "wine/unicode.h" |
| #include "objbase.h" |
| #include "oleauto.h" /* for SysAllocString(....) */ |
| #include "ole2.h" |
| #include "olectl.h" |
| #include "wine/debug.h" |
| #include "connpt.h" /* for CreateConnectionPoint */ |
| #include "oaidl.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(ole); |
| |
| /*********************************************************************** |
| * Declaration of constants used when serializing the font object. |
| */ |
| #define FONTPERSIST_ITALIC 0x02 |
| #define FONTPERSIST_UNDERLINE 0x04 |
| #define FONTPERSIST_STRIKETHROUGH 0x08 |
| |
| /*********************************************************************** |
| * Declaration of the implementation class for the IFont interface |
| */ |
| typedef struct OLEFontImpl OLEFontImpl; |
| |
| struct OLEFontImpl |
| { |
| /* |
| * This class supports many interfaces. IUnknown, IFont, |
| * IDispatch, IDispFont IPersistStream and IConnectionPointContainer. |
| * The first two are supported by the first vtable, the next two are |
| * supported by the second table and the last two have their own. |
| */ |
| const IFontVtbl* lpVtbl; |
| const IDispatchVtbl* lpvtblIDispatch; |
| const IPersistStreamVtbl* lpvtblIPersistStream; |
| const IConnectionPointContainerVtbl* lpvtblIConnectionPointContainer; |
| const IPersistPropertyBagVtbl* lpvtblIPersistPropertyBag; |
| const IPersistStreamInitVtbl* lpvtblIPersistStreamInit; |
| /* |
| * Reference count for that instance of the class. |
| */ |
| LONG ref; |
| |
| /* |
| * This structure contains the description of the class. |
| */ |
| FONTDESC description; |
| |
| /* |
| * Contain the font associated with this object. |
| */ |
| HFONT gdiFont; |
| |
| /* |
| * Font lock count. |
| */ |
| DWORD fontLock; |
| |
| /* |
| * Size ratio |
| */ |
| long cyLogical; |
| long cyHimetric; |
| |
| IConnectionPoint *pPropertyNotifyCP; |
| IConnectionPoint *pFontEventsCP; |
| }; |
| |
| /* |
| * Here, I define utility macros to help with the casting of the |
| * "this" parameter. |
| * There is a version to accommodate all of the VTables implemented |
| * by this object. |
| */ |
| |
| static inline OLEFontImpl *impl_from_IDispatch( IDispatch *iface ) |
| { |
| return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIDispatch)); |
| } |
| |
| static inline OLEFontImpl *impl_from_IPersistStream( IPersistStream *iface ) |
| { |
| return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStream)); |
| } |
| |
| static inline OLEFontImpl *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface ) |
| { |
| return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIConnectionPointContainer)); |
| } |
| |
| static inline OLEFontImpl *impl_from_IPersistPropertyBag( IPersistPropertyBag *iface ) |
| { |
| return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistPropertyBag)); |
| } |
| |
| static inline OLEFontImpl *impl_from_IPersistStreamInit( IPersistStreamInit *iface ) |
| { |
| return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStreamInit)); |
| } |
| |
| |
| /*********************************************************************** |
| * Prototypes for the implementation functions for the IFont |
| * interface |
| */ |
| static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc); |
| static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc); |
| static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid); |
| static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface); |
| static ULONG WINAPI OLEFontImpl_Release(IFont* iface); |
| static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname); |
| static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name); |
| static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize); |
| static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size); |
| static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold); |
| static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold); |
| static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic); |
| static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic); |
| static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline); |
| static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline); |
| static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough); |
| static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough); |
| static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight); |
| static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight); |
| static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset); |
| static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset); |
| static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont); |
| static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont); |
| static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther); |
| static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, LONG cyLogical, LONG cyHimetric); |
| static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm); |
| static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont); |
| static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont); |
| static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc); |
| |
| /*********************************************************************** |
| * Prototypes for the implementation functions for the IDispatch |
| * interface |
| */ |
| static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface, |
| REFIID riid, |
| VOID** ppvoid); |
| static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface); |
| static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface); |
| static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface, |
| unsigned int* pctinfo); |
| static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface, |
| UINT iTInfo, |
| LCID lcid, |
| ITypeInfo** ppTInfo); |
| static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface, |
| REFIID riid, |
| LPOLESTR* rgszNames, |
| UINT cNames, |
| LCID lcid, |
| DISPID* rgDispId); |
| static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface, |
| DISPID dispIdMember, |
| REFIID riid, |
| LCID lcid, |
| WORD wFlags, |
| DISPPARAMS* pDispParams, |
| VARIANT* pVarResult, |
| EXCEPINFO* pExepInfo, |
| UINT* puArgErr); |
| |
| /*********************************************************************** |
| * Prototypes for the implementation functions for the IPersistStream |
| * interface |
| */ |
| static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface, |
| REFIID riid, |
| VOID** ppvoid); |
| static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface); |
| static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface); |
| static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface, |
| CLSID* pClassID); |
| static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface); |
| static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface, |
| IStream* pLoadStream); |
| static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface, |
| IStream* pOutStream, |
| BOOL fClearDirty); |
| static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface, |
| ULARGE_INTEGER* pcbSize); |
| |
| /*********************************************************************** |
| * Prototypes for the implementation functions for the |
| * IConnectionPointContainer interface |
| */ |
| static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface( |
| IConnectionPointContainer* iface, |
| REFIID riid, |
| VOID** ppvoid); |
| static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef( |
| IConnectionPointContainer* iface); |
| static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release( |
| IConnectionPointContainer* iface); |
| static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints( |
| IConnectionPointContainer* iface, |
| IEnumConnectionPoints **ppEnum); |
| static HRESULT WINAPI OLEFontImpl_FindConnectionPoint( |
| IConnectionPointContainer* iface, |
| REFIID riid, |
| IConnectionPoint **ppCp); |
| |
| /* |
| * Virtual function tables for the OLEFontImpl class. |
| */ |
| static const IFontVtbl OLEFontImpl_VTable = |
| { |
| OLEFontImpl_QueryInterface, |
| OLEFontImpl_AddRef, |
| OLEFontImpl_Release, |
| OLEFontImpl_get_Name, |
| OLEFontImpl_put_Name, |
| OLEFontImpl_get_Size, |
| OLEFontImpl_put_Size, |
| OLEFontImpl_get_Bold, |
| OLEFontImpl_put_Bold, |
| OLEFontImpl_get_Italic, |
| OLEFontImpl_put_Italic, |
| OLEFontImpl_get_Underline, |
| OLEFontImpl_put_Underline, |
| OLEFontImpl_get_Strikethrough, |
| OLEFontImpl_put_Strikethrough, |
| OLEFontImpl_get_Weight, |
| OLEFontImpl_put_Weight, |
| OLEFontImpl_get_Charset, |
| OLEFontImpl_put_Charset, |
| OLEFontImpl_get_hFont, |
| OLEFontImpl_Clone, |
| OLEFontImpl_IsEqual, |
| OLEFontImpl_SetRatio, |
| OLEFontImpl_QueryTextMetrics, |
| OLEFontImpl_AddRefHfont, |
| OLEFontImpl_ReleaseHfont, |
| OLEFontImpl_SetHdc |
| }; |
| |
| static const IDispatchVtbl OLEFontImpl_IDispatch_VTable = |
| { |
| OLEFontImpl_IDispatch_QueryInterface, |
| OLEFontImpl_IDispatch_AddRef, |
| OLEFontImpl_IDispatch_Release, |
| OLEFontImpl_GetTypeInfoCount, |
| OLEFontImpl_GetTypeInfo, |
| OLEFontImpl_GetIDsOfNames, |
| OLEFontImpl_Invoke |
| }; |
| |
| static const IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable = |
| { |
| OLEFontImpl_IPersistStream_QueryInterface, |
| OLEFontImpl_IPersistStream_AddRef, |
| OLEFontImpl_IPersistStream_Release, |
| OLEFontImpl_GetClassID, |
| OLEFontImpl_IsDirty, |
| OLEFontImpl_Load, |
| OLEFontImpl_Save, |
| OLEFontImpl_GetSizeMax |
| }; |
| |
| static const IConnectionPointContainerVtbl |
| OLEFontImpl_IConnectionPointContainer_VTable = |
| { |
| OLEFontImpl_IConnectionPointContainer_QueryInterface, |
| OLEFontImpl_IConnectionPointContainer_AddRef, |
| OLEFontImpl_IConnectionPointContainer_Release, |
| OLEFontImpl_EnumConnectionPoints, |
| OLEFontImpl_FindConnectionPoint |
| }; |
| |
| static const IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable; |
| static const IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable; |
| |
| /****************************************************************************** |
| * OleCreateFontIndirect [OLEAUT32.420] |
| */ |
| HRESULT WINAPI OleCreateFontIndirect( |
| LPFONTDESC lpFontDesc, |
| REFIID riid, |
| LPVOID* ppvObj) |
| { |
| OLEFontImpl* newFont = 0; |
| HRESULT hr = S_OK; |
| |
| TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj); |
| /* |
| * Sanity check |
| */ |
| if (ppvObj==0) |
| return E_POINTER; |
| |
| *ppvObj = 0; |
| |
| if (!lpFontDesc) { |
| FONTDESC fd; |
| |
| static WCHAR fname[] = { 'S','y','s','t','e','m',0 }; |
| |
| fd.cbSizeofstruct = sizeof(fd); |
| fd.lpstrName = fname; |
| fd.cySize.s.Lo = 80000; |
| fd.cySize.s.Hi = 0; |
| fd.sWeight = 0; |
| fd.sCharset = 0; |
| fd.fItalic = 0; |
| fd.fUnderline = 0; |
| fd.fStrikethrough = 0; |
| lpFontDesc = &fd; |
| } |
| |
| /* |
| * Try to construct a new instance of the class. |
| */ |
| newFont = OLEFontImpl_Construct(lpFontDesc); |
| |
| if (newFont == 0) |
| return E_OUTOFMEMORY; |
| |
| /* |
| * Make sure it supports the interface required by the caller. |
| */ |
| hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj); |
| |
| /* |
| * Release the reference obtained in the constructor. If |
| * the QueryInterface was unsuccessful, it will free the class. |
| */ |
| IFont_Release((IFont*)newFont); |
| |
| return hr; |
| } |
| |
| |
| /*********************************************************************** |
| * Implementation of the OLEFontImpl class. |
| */ |
| |
| /*********************************************************************** |
| * OLEFont_SendNotify (internal) |
| * |
| * Sends notification messages of changed properties to any interested |
| * connections. |
| */ |
| static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID) |
| { |
| static const WCHAR wszName[] = {'N','a','m','e',0}; |
| static const WCHAR wszSize[] = {'S','i','z','e',0}; |
| static const WCHAR wszBold[] = {'B','o','l','d',0}; |
| static const WCHAR wszItalic[] = {'I','t','a','l','i','c',0}; |
| static const WCHAR wszUnder[] = {'U','n','d','e','r','l','i','n','e',0}; |
| static const WCHAR wszStrike[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0}; |
| static const WCHAR wszWeight[] = {'W','e','i','g','h','t',0}; |
| static const WCHAR wszCharset[] = {'C','h','a','r','s','s','e','t',0}; |
| static const LPCWSTR dispid_mapping[] = |
| { |
| wszName, |
| NULL, |
| wszSize, |
| wszBold, |
| wszItalic, |
| wszUnder, |
| wszStrike, |
| wszWeight, |
| wszCharset |
| }; |
| |
| IEnumConnections *pEnum; |
| CONNECTDATA CD; |
| HRESULT hres; |
| |
| hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum); |
| if (SUCCEEDED(hres)) |
| { |
| while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) { |
| IPropertyNotifySink *sink; |
| |
| IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink); |
| IPropertyNotifySink_OnChanged(sink, dispID); |
| IPropertyNotifySink_Release(sink); |
| IUnknown_Release(CD.pUnk); |
| } |
| IEnumConnections_Release(pEnum); |
| } |
| |
| hres = IConnectionPoint_EnumConnections(this->pFontEventsCP, &pEnum); |
| if (SUCCEEDED(hres)) |
| { |
| DISPPARAMS dispparams; |
| VARIANTARG vararg; |
| |
| VariantInit(&vararg); |
| V_VT(&vararg) = VT_BSTR; |
| V_BSTR(&vararg) = SysAllocString(dispid_mapping[dispID]); |
| |
| dispparams.cArgs = 1; |
| dispparams.cNamedArgs = 0; |
| dispparams.rgdispidNamedArgs = NULL; |
| dispparams.rgvarg = &vararg; |
| |
| while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) { |
| IFontEventsDisp *disp; |
| |
| IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (LPVOID)&disp); |
| IDispatch_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL, |
| LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL, |
| NULL, NULL); |
| |
| IDispatch_Release(disp); |
| IUnknown_Release(CD.pUnk); |
| } |
| VariantClear(&vararg); |
| IEnumConnections_Release(pEnum); |
| } |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_Construct |
| * |
| * This method will construct a new instance of the OLEFontImpl |
| * class. |
| * |
| * The caller of this method must release the object when it's |
| * done with it. |
| */ |
| static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc) |
| { |
| OLEFontImpl* newObject = 0; |
| |
| /* |
| * Allocate space for the object. |
| */ |
| newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl)); |
| |
| if (newObject==0) |
| return newObject; |
| |
| /* |
| * Initialize the virtual function table. |
| */ |
| newObject->lpVtbl = &OLEFontImpl_VTable; |
| newObject->lpvtblIDispatch = &OLEFontImpl_IDispatch_VTable; |
| newObject->lpvtblIPersistStream = &OLEFontImpl_IPersistStream_VTable; |
| newObject->lpvtblIConnectionPointContainer = &OLEFontImpl_IConnectionPointContainer_VTable; |
| newObject->lpvtblIPersistPropertyBag = &OLEFontImpl_IPersistPropertyBag_VTable; |
| newObject->lpvtblIPersistStreamInit = &OLEFontImpl_IPersistStreamInit_VTable; |
| |
| /* |
| * Start with one reference count. The caller of this function |
| * must release the interface pointer when it is done. |
| */ |
| newObject->ref = 1; |
| |
| /* |
| * Copy the description of the font in the object. |
| */ |
| assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC)); |
| |
| newObject->description.cbSizeofstruct = sizeof(FONTDESC); |
| newObject->description.lpstrName = HeapAlloc(GetProcessHeap(), |
| 0, |
| (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR)); |
| strcpyW(newObject->description.lpstrName, fontDesc->lpstrName); |
| newObject->description.cySize = fontDesc->cySize; |
| newObject->description.sWeight = fontDesc->sWeight; |
| newObject->description.sCharset = fontDesc->sCharset; |
| newObject->description.fItalic = fontDesc->fItalic; |
| newObject->description.fUnderline = fontDesc->fUnderline; |
| newObject->description.fStrikethrough = fontDesc->fStrikethrough; |
| |
| /* |
| * Initializing all the other members. |
| */ |
| newObject->gdiFont = 0; |
| newObject->fontLock = 0; |
| newObject->cyLogical = 72L; |
| newObject->cyHimetric = 2540L; |
| newObject->pPropertyNotifyCP = NULL; |
| newObject->pFontEventsCP = NULL; |
| |
| CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP); |
| CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP); |
| |
| if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP) |
| { |
| OLEFontImpl_Destroy(newObject); |
| return NULL; |
| } |
| |
| TRACE("returning %p\n", newObject); |
| return newObject; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_Destroy |
| * |
| * This method is called by the Release method when the reference |
| * count goes down to 0. It will free all resources used by |
| * this object. |
| */ |
| static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc) |
| { |
| TRACE("(%p)\n", fontDesc); |
| |
| HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName); |
| |
| if (fontDesc->gdiFont!=0) |
| DeleteObject(fontDesc->gdiFont); |
| |
| if (fontDesc->pPropertyNotifyCP) |
| IConnectionPoint_Release(fontDesc->pPropertyNotifyCP); |
| if (fontDesc->pFontEventsCP) |
| IConnectionPoint_Release(fontDesc->pFontEventsCP); |
| |
| HeapFree(GetProcessHeap(), 0, fontDesc); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_QueryInterface (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| HRESULT WINAPI OLEFontImpl_QueryInterface( |
| IFont* iface, |
| REFIID riid, |
| void** ppvObject) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject); |
| |
| /* |
| * Perform a sanity check on the parameters. |
| */ |
| if ( (this==0) || (ppvObject==0) ) |
| return E_INVALIDARG; |
| |
| /* |
| * Initialize the return parameter. |
| */ |
| *ppvObject = 0; |
| |
| /* |
| * Compare the riid with the interface IDs implemented by this object. |
| */ |
| if (IsEqualGUID(&IID_IUnknown, riid)) |
| *ppvObject = (IFont*)this; |
| if (IsEqualGUID(&IID_IFont, riid)) |
| *ppvObject = (IFont*)this; |
| if (IsEqualGUID(&IID_IDispatch, riid)) |
| *ppvObject = (IDispatch*)&(this->lpvtblIDispatch); |
| if (IsEqualGUID(&IID_IFontDisp, riid)) |
| *ppvObject = (IDispatch*)&(this->lpvtblIDispatch); |
| if (IsEqualIID(&IID_IPersist, riid) || IsEqualGUID(&IID_IPersistStream, riid)) |
| *ppvObject = (IPersistStream*)&(this->lpvtblIPersistStream); |
| if (IsEqualGUID(&IID_IConnectionPointContainer, riid)) |
| *ppvObject = (IConnectionPointContainer*)&(this->lpvtblIConnectionPointContainer); |
| if (IsEqualGUID(&IID_IPersistPropertyBag, riid)) |
| *ppvObject = (IPersistPropertyBag*)&(this->lpvtblIPersistPropertyBag); |
| if (IsEqualGUID(&IID_IPersistStreamInit, riid)) |
| *ppvObject = (IPersistStreamInit*)&(this->lpvtblIPersistStreamInit); |
| |
| /* |
| * Check that we obtained an interface. |
| */ |
| if ((*ppvObject)==0) |
| { |
| FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid)); |
| return E_NOINTERFACE; |
| } |
| OLEFontImpl_AddRef((IFont*)this); |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_AddRef (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| ULONG WINAPI OLEFontImpl_AddRef( |
| IFont* iface) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(ref=%d)\n", this, this->ref); |
| return InterlockedIncrement(&this->ref); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_Release (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| ULONG WINAPI OLEFontImpl_Release( |
| IFont* iface) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| ULONG ret; |
| TRACE("(%p)->(ref=%d)\n", this, this->ref); |
| |
| /* |
| * Decrease the reference count on this object. |
| */ |
| ret = InterlockedDecrement(&this->ref); |
| |
| /* |
| * If the reference count goes down to 0, perform suicide. |
| */ |
| if (ret==0) OLEFontImpl_Destroy(this); |
| |
| return ret; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_get_Name (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_get_Name( |
| IFont* iface, |
| BSTR* pname) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, pname); |
| /* |
| * Sanity check. |
| */ |
| if (pname==0) |
| return E_POINTER; |
| |
| if (this->description.lpstrName!=0) |
| *pname = SysAllocString(this->description.lpstrName); |
| else |
| *pname = 0; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_put_Name (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_put_Name( |
| IFont* iface, |
| BSTR name) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, name); |
| |
| if (this->description.lpstrName==0) |
| { |
| this->description.lpstrName = HeapAlloc(GetProcessHeap(), |
| 0, |
| (lstrlenW(name)+1) * sizeof(WCHAR)); |
| } |
| else |
| { |
| this->description.lpstrName = HeapReAlloc(GetProcessHeap(), |
| 0, |
| this->description.lpstrName, |
| (lstrlenW(name)+1) * sizeof(WCHAR)); |
| } |
| |
| if (this->description.lpstrName==0) |
| return E_OUTOFMEMORY; |
| |
| strcpyW(this->description.lpstrName, name); |
| TRACE("new name %s\n", debugstr_w(this->description.lpstrName)); |
| OLEFont_SendNotify(this, DISPID_FONT_NAME); |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_get_Size (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_get_Size( |
| IFont* iface, |
| CY* psize) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, psize); |
| |
| /* |
| * Sanity check |
| */ |
| if (psize==0) |
| return E_POINTER; |
| |
| psize->s.Hi = 0; |
| psize->s.Lo = this->description.cySize.s.Lo; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_put_Size (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_put_Size( |
| IFont* iface, |
| CY size) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%d)\n", this, size.s.Lo); |
| this->description.cySize.s.Hi = 0; |
| this->description.cySize.s.Lo = size.s.Lo; |
| OLEFont_SendNotify(this, DISPID_FONT_SIZE); |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_get_Bold (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_get_Bold( |
| IFont* iface, |
| BOOL* pbold) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, pbold); |
| /* |
| * Sanity check |
| */ |
| if (pbold==0) |
| return E_POINTER; |
| |
| *pbold = this->description.sWeight > 550; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_put_Bold (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_put_Bold( |
| IFont* iface, |
| BOOL bold) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%d)\n", this, bold); |
| this->description.sWeight = bold ? FW_BOLD : FW_NORMAL; |
| OLEFont_SendNotify(this, DISPID_FONT_BOLD); |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_get_Italic (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_get_Italic( |
| IFont* iface, |
| BOOL* pitalic) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, pitalic); |
| /* |
| * Sanity check |
| */ |
| if (pitalic==0) |
| return E_POINTER; |
| |
| *pitalic = this->description.fItalic; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_put_Italic (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_put_Italic( |
| IFont* iface, |
| BOOL italic) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%d)\n", this, italic); |
| |
| this->description.fItalic = italic; |
| |
| OLEFont_SendNotify(this, DISPID_FONT_ITALIC); |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_get_Underline (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_get_Underline( |
| IFont* iface, |
| BOOL* punderline) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, punderline); |
| |
| /* |
| * Sanity check |
| */ |
| if (punderline==0) |
| return E_POINTER; |
| |
| *punderline = this->description.fUnderline; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_put_Underline (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_put_Underline( |
| IFont* iface, |
| BOOL underline) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%d)\n", this, underline); |
| |
| this->description.fUnderline = underline; |
| |
| OLEFont_SendNotify(this, DISPID_FONT_UNDER); |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_get_Strikethrough (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_get_Strikethrough( |
| IFont* iface, |
| BOOL* pstrikethrough) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, pstrikethrough); |
| |
| /* |
| * Sanity check |
| */ |
| if (pstrikethrough==0) |
| return E_POINTER; |
| |
| *pstrikethrough = this->description.fStrikethrough; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_put_Strikethrough (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_put_Strikethrough( |
| IFont* iface, |
| BOOL strikethrough) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%d)\n", this, strikethrough); |
| |
| this->description.fStrikethrough = strikethrough; |
| OLEFont_SendNotify(this, DISPID_FONT_STRIKE); |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_get_Weight (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_get_Weight( |
| IFont* iface, |
| short* pweight) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, pweight); |
| |
| /* |
| * Sanity check |
| */ |
| if (pweight==0) |
| return E_POINTER; |
| |
| *pweight = this->description.sWeight; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_put_Weight (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_put_Weight( |
| IFont* iface, |
| short weight) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%d)\n", this, weight); |
| |
| this->description.sWeight = weight; |
| |
| OLEFont_SendNotify(this, DISPID_FONT_WEIGHT); |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_get_Charset (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_get_Charset( |
| IFont* iface, |
| short* pcharset) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, pcharset); |
| |
| /* |
| * Sanity check |
| */ |
| if (pcharset==0) |
| return E_POINTER; |
| |
| *pcharset = this->description.sCharset; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_put_Charset (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_put_Charset( |
| IFont* iface, |
| short charset) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%d)\n", this, charset); |
| |
| this->description.sCharset = charset; |
| OLEFont_SendNotify(this, DISPID_FONT_CHARSET); |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_get_hFont (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_get_hFont( |
| IFont* iface, |
| HFONT* phfont) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, phfont); |
| if (phfont==NULL) |
| return E_POINTER; |
| |
| /* |
| * Realize the font if necessary |
| */ |
| if (this->gdiFont==0) |
| { |
| LOGFONTW logFont; |
| INT fontHeight; |
| CY cySize; |
| |
| /* |
| * The height of the font returned by the get_Size property is the |
| * height of the font in points multiplied by 10000... Using some |
| * simple conversions and the ratio given by the application, it can |
| * be converted to a height in pixels. |
| */ |
| IFont_get_Size(iface, &cySize); |
| |
| /* Standard ratio is 72 / 2540, or 18 / 635 in lowest terms. */ |
| /* Ratio is applied here relative to the standard. */ |
| fontHeight = MulDiv( cySize.s.Lo, this->cyLogical*635, this->cyHimetric*18 ); |
| |
| memset(&logFont, 0, sizeof(LOGFONTW)); |
| |
| logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 : |
| (-fontHeight/10000L); |
| logFont.lfItalic = this->description.fItalic; |
| logFont.lfUnderline = this->description.fUnderline; |
| logFont.lfStrikeOut = this->description.fStrikethrough; |
| logFont.lfWeight = this->description.sWeight; |
| logFont.lfCharSet = this->description.sCharset; |
| logFont.lfOutPrecision = OUT_CHARACTER_PRECIS; |
| logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; |
| logFont.lfQuality = DEFAULT_QUALITY; |
| logFont.lfPitchAndFamily = DEFAULT_PITCH; |
| strcpyW(logFont.lfFaceName,this->description.lpstrName); |
| |
| this->gdiFont = CreateFontIndirectW(&logFont); |
| } |
| |
| *phfont = this->gdiFont; |
| TRACE("Returning %p\n", *phfont); |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_Clone (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_Clone( |
| IFont* iface, |
| IFont** ppfont) |
| { |
| OLEFontImpl* newObject = 0; |
| LOGFONTW logFont; |
| INT fontHeight; |
| CY cySize; |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p)\n", this, ppfont); |
| |
| if (ppfont == NULL) |
| return E_POINTER; |
| |
| *ppfont = NULL; |
| |
| /* |
| * Allocate space for the object. |
| */ |
| newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl)); |
| |
| if (newObject==NULL) |
| return E_OUTOFMEMORY; |
| |
| *newObject = *this; |
| |
| /* We need to alloc new memory for the string, otherwise |
| * we free memory twice. |
| */ |
| newObject->description.lpstrName = HeapAlloc( |
| GetProcessHeap(),0, |
| (1+strlenW(this->description.lpstrName))*2 |
| ); |
| strcpyW(newObject->description.lpstrName, this->description.lpstrName); |
| /* We need to clone the HFONT too. This is just cut & paste from above */ |
| IFont_get_Size(iface, &cySize); |
| |
| fontHeight = MulDiv(cySize.s.Lo, this->cyLogical*635,this->cyHimetric*18); |
| |
| memset(&logFont, 0, sizeof(LOGFONTW)); |
| |
| logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 : |
| (-fontHeight/10000L); |
| logFont.lfItalic = this->description.fItalic; |
| logFont.lfUnderline = this->description.fUnderline; |
| logFont.lfStrikeOut = this->description.fStrikethrough; |
| logFont.lfWeight = this->description.sWeight; |
| logFont.lfCharSet = this->description.sCharset; |
| logFont.lfOutPrecision = OUT_CHARACTER_PRECIS; |
| logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; |
| logFont.lfQuality = DEFAULT_QUALITY; |
| logFont.lfPitchAndFamily = DEFAULT_PITCH; |
| strcpyW(logFont.lfFaceName,this->description.lpstrName); |
| |
| newObject->gdiFont = CreateFontIndirectW(&logFont); |
| |
| /* create new connection points */ |
| newObject->pPropertyNotifyCP = NULL; |
| newObject->pFontEventsCP = NULL; |
| CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP); |
| CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP); |
| |
| if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP) |
| { |
| OLEFontImpl_Destroy(newObject); |
| return E_OUTOFMEMORY; |
| } |
| |
| /* The cloned object starts with a reference count of 1 */ |
| newObject->ref = 1; |
| |
| *ppfont = (IFont*)newObject; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IsEqual (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_IsEqual( |
| IFont* iface, |
| IFont* pFontOther) |
| { |
| OLEFontImpl *left = (OLEFontImpl *)iface; |
| OLEFontImpl *right = (OLEFontImpl *)pFontOther; |
| HRESULT hres; |
| INT left_len,right_len; |
| |
| if((iface == NULL) || (pFontOther == NULL)) |
| return E_POINTER; |
| else if (left->description.cySize.s.Lo != right->description.cySize.s.Lo) |
| return S_FALSE; |
| else if (left->description.cySize.s.Hi != right->description.cySize.s.Hi) |
| return S_FALSE; |
| else if (left->description.sWeight != right->description.sWeight) |
| return S_FALSE; |
| else if (left->description.sCharset != right->description.sCharset) |
| return S_FALSE; |
| else if (left->description.fItalic != right->description.fItalic) |
| return S_FALSE; |
| else if (left->description.fUnderline != right->description.fUnderline) |
| return S_FALSE; |
| else if (left->description.fStrikethrough != right->description.fStrikethrough) |
| return S_FALSE; |
| |
| /* Check from string */ |
| left_len = strlenW(left->description.lpstrName); |
| right_len = strlenW(right->description.lpstrName); |
| hres = CompareStringW(0,0,left->description.lpstrName, left_len, |
| right->description.lpstrName, right_len); |
| if (hres != CSTR_EQUAL) |
| return S_FALSE; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_SetRatio (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_SetRatio( |
| IFont* iface, |
| LONG cyLogical, |
| LONG cyHimetric) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%d, %d)\n", this, cyLogical, cyHimetric); |
| |
| this->cyLogical = cyLogical; |
| this->cyHimetric = cyHimetric; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_QueryTextMetrics (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_QueryTextMetrics( |
| IFont* iface, |
| TEXTMETRICOLE* ptm) |
| { |
| HDC hdcRef; |
| HFONT hOldFont, hNewFont; |
| |
| hdcRef = GetDC(0); |
| OLEFontImpl_get_hFont(iface, &hNewFont); |
| hOldFont = SelectObject(hdcRef, hNewFont); |
| GetTextMetricsW(hdcRef, ptm); |
| SelectObject(hdcRef, hOldFont); |
| ReleaseDC(0, hdcRef); |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_AddRefHfont (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_AddRefHfont( |
| IFont* iface, |
| HFONT hfont) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p) (lock=%d)\n", this, hfont, this->fontLock); |
| |
| if ( (hfont == 0) || |
| (hfont != this->gdiFont) ) |
| return E_INVALIDARG; |
| |
| this->fontLock++; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_ReleaseHfont (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_ReleaseHfont( |
| IFont* iface, |
| HFONT hfont) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| TRACE("(%p)->(%p) (lock=%d)\n", this, hfont, this->fontLock); |
| |
| if ( (hfont == 0) || |
| (hfont != this->gdiFont) ) |
| return E_INVALIDARG; |
| |
| this->fontLock--; |
| |
| /* |
| * If we just released our last font reference, destroy it. |
| */ |
| if (this->fontLock==0) |
| { |
| DeleteObject(this->gdiFont); |
| this->gdiFont = 0; |
| } |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_SetHdc (IFont) |
| * |
| * See Windows documentation for more details on IFont methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_SetHdc( |
| IFont* iface, |
| HDC hdc) |
| { |
| OLEFontImpl *this = (OLEFontImpl *)iface; |
| FIXME("(%p)->(%p): Stub\n", this, hdc); |
| return E_NOTIMPL; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IDispatch_QueryInterface (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface( |
| IDispatch* iface, |
| REFIID riid, |
| VOID** ppvoid) |
| { |
| OLEFontImpl *this = impl_from_IDispatch(iface); |
| |
| return IFont_QueryInterface((IFont *)this, riid, ppvoid); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IDispatch_Release (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static ULONG WINAPI OLEFontImpl_IDispatch_Release( |
| IDispatch* iface) |
| { |
| OLEFontImpl *this = impl_from_IDispatch(iface); |
| |
| return IFont_Release((IFont *)this); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IDispatch_AddRef (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static ULONG WINAPI OLEFontImpl_IDispatch_AddRef( |
| IDispatch* iface) |
| { |
| OLEFontImpl *this = impl_from_IDispatch(iface); |
| |
| return IFont_AddRef((IFont *)this); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_GetTypeInfoCount (IDispatch) |
| * |
| * See Windows documentation for more details on IDispatch methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount( |
| IDispatch* iface, |
| unsigned int* pctinfo) |
| { |
| OLEFontImpl *this = impl_from_IDispatch(iface); |
| TRACE("(%p)->(%p)\n", this, pctinfo); |
| *pctinfo = 1; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_GetTypeInfo (IDispatch) |
| * |
| * See Windows documentation for more details on IDispatch methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_GetTypeInfo( |
| IDispatch* iface, |
| UINT iTInfo, |
| LCID lcid, |
| ITypeInfo** ppTInfo) |
| { |
| static const WCHAR stdole2tlb[] = {'s','t','d','o','l','e','2','.','t','l','b',0}; |
| ITypeLib *tl; |
| HRESULT hres; |
| |
| OLEFontImpl *this = impl_from_IDispatch(iface); |
| TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo, (int)lcid, ppTInfo); |
| if (iTInfo != 0) |
| return E_FAIL; |
| hres = LoadTypeLib(stdole2tlb, &tl); |
| if (FAILED(hres)) { |
| ERR("Could not load the stdole2.tlb?\n"); |
| return hres; |
| } |
| hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IFontDisp, ppTInfo); |
| if (FAILED(hres)) { |
| FIXME("Did not IDispatch typeinfo from typelib, hres %x\n",hres); |
| } |
| return hres; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_GetIDsOfNames (IDispatch) |
| * |
| * See Windows documentation for more details on IDispatch methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_GetIDsOfNames( |
| IDispatch* iface, |
| REFIID riid, |
| LPOLESTR* rgszNames, |
| UINT cNames, |
| LCID lcid, |
| DISPID* rgDispId) |
| { |
| ITypeInfo * pTInfo; |
| HRESULT hres; |
| |
| OLEFontImpl *this = impl_from_IDispatch(iface); |
| |
| TRACE("(%p,%s,%p,cNames=%d,lcid=%04x,%p)\n", this, debugstr_guid(riid), |
| rgszNames, cNames, (int)lcid, rgDispId); |
| |
| if (cNames == 0) |
| { |
| return E_INVALIDARG; |
| } |
| else |
| { |
| /* retrieve type information */ |
| hres = OLEFontImpl_GetTypeInfo(iface, 0, lcid, &pTInfo); |
| |
| if (FAILED(hres)) |
| { |
| ERR("GetTypeInfo failed.\n"); |
| return hres; |
| } |
| |
| /* convert names to DISPIDs */ |
| hres = DispGetIDsOfNames (pTInfo, rgszNames, cNames, rgDispId); |
| ITypeInfo_Release(pTInfo); |
| |
| return hres; |
| } |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_Invoke (IDispatch) |
| * |
| * See Windows documentation for more details on IDispatch methods. |
| * |
| * Note: Do not call _put_Xxx methods, since setting things here |
| * should not call notify functions as I found out debugging the generic |
| * MS VB5 installer. |
| */ |
| static HRESULT WINAPI OLEFontImpl_Invoke( |
| IDispatch* iface, |
| DISPID dispIdMember, |
| REFIID riid, |
| LCID lcid, |
| WORD wFlags, |
| DISPPARAMS* pDispParams, |
| VARIANT* pVarResult, |
| EXCEPINFO* pExepInfo, |
| UINT* puArgErr) |
| { |
| OLEFontImpl *this = impl_from_IDispatch(iface); |
| HRESULT hr; |
| |
| TRACE("%p->(%d,%s,0x%x,0x%x,%p,%p,%p,%p)\n", this, dispIdMember, |
| debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExepInfo, |
| puArgErr); |
| |
| /* validate parameters */ |
| |
| if (!IsEqualIID(riid, &IID_NULL)) |
| { |
| ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid)); |
| return DISP_E_UNKNOWNINTERFACE; |
| } |
| |
| if (wFlags & DISPATCH_PROPERTYGET) |
| { |
| if (!pVarResult) |
| { |
| ERR("null pVarResult not allowed when DISPATCH_PROPERTYGET specified\n"); |
| return DISP_E_PARAMNOTOPTIONAL; |
| } |
| } |
| else if (wFlags & DISPATCH_PROPERTYPUT) |
| { |
| if (!pDispParams) |
| { |
| ERR("null pDispParams not allowed when DISPATCH_PROPERTYPUT specified\n"); |
| return DISP_E_PARAMNOTOPTIONAL; |
| } |
| if (pDispParams->cArgs != 1) |
| { |
| ERR("param count for DISPATCH_PROPERTYPUT was %d instead of 1\n", pDispParams->cArgs); |
| return DISP_E_BADPARAMCOUNT; |
| } |
| } |
| else |
| { |
| ERR("one of DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT must be specified\n"); |
| return DISP_E_MEMBERNOTFOUND; |
| } |
| |
| switch (dispIdMember) { |
| case DISPID_FONT_NAME: |
| if (wFlags & DISPATCH_PROPERTYGET) { |
| V_VT(pVarResult) = VT_BSTR; |
| return IFont_get_Name((IFont *)this, &V_BSTR(pVarResult)); |
| } else { |
| VARIANTARG vararg; |
| |
| VariantInit(&vararg); |
| hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BSTR); |
| if (FAILED(hr)) |
| return hr; |
| |
| hr = IFont_put_Name((IFont *)this, V_BSTR(&vararg)); |
| |
| VariantClear(&vararg); |
| return hr; |
| } |
| break; |
| case DISPID_FONT_BOLD: |
| if (wFlags & DISPATCH_PROPERTYGET) { |
| BOOL value; |
| hr = IFont_get_Bold((IFont *)this, &value); |
| V_VT(pVarResult) = VT_BOOL; |
| V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; |
| return hr; |
| } else { |
| VARIANTARG vararg; |
| |
| VariantInit(&vararg); |
| hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL); |
| if (FAILED(hr)) |
| return hr; |
| |
| hr = IFont_put_Bold((IFont *)this, V_BOOL(&vararg)); |
| |
| VariantClear(&vararg); |
| return hr; |
| } |
| break; |
| case DISPID_FONT_ITALIC: |
| if (wFlags & DISPATCH_PROPERTYGET) { |
| BOOL value; |
| hr = IFont_get_Italic((IFont *)this, &value); |
| V_VT(pVarResult) = VT_BOOL; |
| V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; |
| return hr; |
| } else { |
| VARIANTARG vararg; |
| HRESULT hr; |
| |
| VariantInit(&vararg); |
| hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL); |
| if (FAILED(hr)) |
| return hr; |
| |
| hr = IFont_put_Italic((IFont *)this, V_BOOL(&vararg)); |
| |
| VariantClear(&vararg); |
| return hr; |
| } |
| break; |
| case DISPID_FONT_UNDER: |
| if (wFlags & DISPATCH_PROPERTYGET) { |
| BOOL value; |
| hr = IFont_get_Underline((IFont *)this, &value); |
| V_VT(pVarResult) = VT_BOOL; |
| V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; |
| return hr; |
| } else { |
| VARIANTARG vararg; |
| HRESULT hr; |
| |
| VariantInit(&vararg); |
| hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL); |
| if (FAILED(hr)) |
| return hr; |
| |
| hr = IFont_put_Underline((IFont *)this, V_BOOL(&vararg)); |
| |
| VariantClear(&vararg); |
| return hr; |
| } |
| break; |
| case DISPID_FONT_STRIKE: |
| if (wFlags & DISPATCH_PROPERTYGET) { |
| BOOL value; |
| hr = IFont_get_Strikethrough((IFont *)this, &value); |
| V_VT(pVarResult) = VT_BOOL; |
| V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; |
| return hr; |
| } else { |
| VARIANTARG vararg; |
| HRESULT hr; |
| |
| VariantInit(&vararg); |
| hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL); |
| if (FAILED(hr)) |
| return hr; |
| |
| hr = IFont_put_Strikethrough((IFont *)this, V_BOOL(&vararg)); |
| |
| VariantClear(&vararg); |
| return hr; |
| } |
| break; |
| case DISPID_FONT_SIZE: |
| if (wFlags & DISPATCH_PROPERTYGET) { |
| V_VT(pVarResult) = VT_CY; |
| return OLEFontImpl_get_Size((IFont *)this, &V_CY(pVarResult)); |
| } else { |
| VARIANTARG vararg; |
| HRESULT hr; |
| |
| VariantInit(&vararg); |
| hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_CY); |
| if (FAILED(hr)) |
| return hr; |
| |
| hr = IFont_put_Size((IFont *)this, V_CY(&vararg)); |
| |
| VariantClear(&vararg); |
| return hr; |
| } |
| break; |
| case DISPID_FONT_WEIGHT: |
| if (wFlags & DISPATCH_PROPERTYGET) { |
| V_VT(pVarResult) = VT_I2; |
| return OLEFontImpl_get_Weight((IFont *)this, &V_I2(pVarResult)); |
| } else { |
| VARIANTARG vararg; |
| HRESULT hr; |
| |
| VariantInit(&vararg); |
| hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2); |
| if (FAILED(hr)) |
| return hr; |
| |
| hr = IFont_put_Weight((IFont *)this, V_I2(&vararg)); |
| |
| VariantClear(&vararg); |
| return hr; |
| } |
| break; |
| case DISPID_FONT_CHARSET: |
| if (wFlags & DISPATCH_PROPERTYGET) { |
| V_VT(pVarResult) = VT_I2; |
| return OLEFontImpl_get_Charset((IFont *)this, &V_I2(pVarResult)); |
| } else { |
| VARIANTARG vararg; |
| HRESULT hr; |
| |
| VariantInit(&vararg); |
| hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2); |
| if (FAILED(hr)) |
| return hr; |
| |
| hr = IFont_put_Charset((IFont *)this, V_I2(&vararg)); |
| |
| VariantClear(&vararg); |
| return hr; |
| } |
| break; |
| default: |
| ERR("member not found for dispid 0x%x\n", dispIdMember); |
| return DISP_E_MEMBERNOTFOUND; |
| } |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IPersistStream_QueryInterface (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface( |
| IPersistStream* iface, |
| REFIID riid, |
| VOID** ppvoid) |
| { |
| OLEFontImpl *this = impl_from_IPersistStream(iface); |
| |
| return IFont_QueryInterface((IFont *)this, riid, ppvoid); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IPersistStream_Release (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static ULONG WINAPI OLEFontImpl_IPersistStream_Release( |
| IPersistStream* iface) |
| { |
| OLEFontImpl *this = impl_from_IPersistStream(iface); |
| |
| return IFont_Release((IFont *)this); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IPersistStream_AddRef (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef( |
| IPersistStream* iface) |
| { |
| OLEFontImpl *this = impl_from_IPersistStream(iface); |
| |
| return IFont_AddRef((IFont *)this); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_GetClassID (IPersistStream) |
| * |
| * See Windows documentation for more details on IPersistStream methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_GetClassID( |
| IPersistStream* iface, |
| CLSID* pClassID) |
| { |
| TRACE("(%p,%p)\n",iface,pClassID); |
| if (pClassID==0) |
| return E_POINTER; |
| |
| memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont)); |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IsDirty (IPersistStream) |
| * |
| * See Windows documentation for more details on IPersistStream methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_IsDirty( |
| IPersistStream* iface) |
| { |
| TRACE("(%p)\n",iface); |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_Load (IPersistStream) |
| * |
| * See Windows documentation for more details on IPersistStream methods. |
| * |
| * This is the format of the standard font serialization as far as I |
| * know |
| * |
| * Offset Type Value Comment |
| * 0x0000 Byte Unknown Probably a version number, contains 0x01 |
| * 0x0001 Short Charset Charset value from the FONTDESC structure |
| * 0x0003 Byte Attributes Flags defined as follows: |
| * 00000010 - Italic |
| * 00000100 - Underline |
| * 00001000 - Strikethrough |
| * 0x0004 Short Weight Weight value from FONTDESC structure |
| * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC |
| * structure/ |
| * 0x000A Byte name length Length of the font name string (no null character) |
| * 0x000B String name Name of the font (ASCII, no nul character) |
| */ |
| static HRESULT WINAPI OLEFontImpl_Load( |
| IPersistStream* iface, |
| IStream* pLoadStream) |
| { |
| char readBuffer[0x100]; |
| ULONG cbRead; |
| BYTE bVersion; |
| BYTE bAttributes; |
| BYTE bStringSize; |
| INT len; |
| |
| OLEFontImpl *this = impl_from_IPersistStream(iface); |
| |
| /* |
| * Read the version byte |
| */ |
| IStream_Read(pLoadStream, &bVersion, 1, &cbRead); |
| |
| if ( (cbRead!=1) || |
| (bVersion!=0x01) ) |
| return E_FAIL; |
| |
| /* |
| * Charset |
| */ |
| IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead); |
| |
| if (cbRead!=2) |
| return E_FAIL; |
| |
| /* |
| * Attributes |
| */ |
| IStream_Read(pLoadStream, &bAttributes, 1, &cbRead); |
| |
| if (cbRead!=1) |
| return E_FAIL; |
| |
| this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0; |
| this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0; |
| this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0; |
| |
| /* |
| * Weight |
| */ |
| IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead); |
| |
| if (cbRead!=2) |
| return E_FAIL; |
| |
| /* |
| * Size |
| */ |
| IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead); |
| |
| if (cbRead!=4) |
| return E_FAIL; |
| |
| this->description.cySize.s.Hi = 0; |
| |
| /* |
| * FontName |
| */ |
| IStream_Read(pLoadStream, &bStringSize, 1, &cbRead); |
| |
| if (cbRead!=1) |
| return E_FAIL; |
| |
| IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead); |
| |
| if (cbRead!=bStringSize) |
| return E_FAIL; |
| |
| HeapFree(GetProcessHeap(), 0, this->description.lpstrName); |
| |
| len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 ); |
| this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) ); |
| MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len ); |
| this->description.lpstrName[len] = 0; |
| |
| /* Ensure use of this font causes a new one to be created @@@@ */ |
| DeleteObject(this->gdiFont); |
| this->gdiFont = 0; |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_Save (IPersistStream) |
| * |
| * See Windows documentation for more details on IPersistStream methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_Save( |
| IPersistStream* iface, |
| IStream* pOutStream, |
| BOOL fClearDirty) |
| { |
| char* writeBuffer = NULL; |
| ULONG cbWritten; |
| BYTE bVersion = 0x01; |
| BYTE bAttributes; |
| BYTE bStringSize; |
| |
| OLEFontImpl *this = impl_from_IPersistStream(iface); |
| |
| /* |
| * Read the version byte |
| */ |
| IStream_Write(pOutStream, &bVersion, 1, &cbWritten); |
| |
| if (cbWritten!=1) |
| return E_FAIL; |
| |
| /* |
| * Charset |
| */ |
| IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten); |
| |
| if (cbWritten!=2) |
| return E_FAIL; |
| |
| /* |
| * Attributes |
| */ |
| bAttributes = 0; |
| |
| if (this->description.fItalic) |
| bAttributes |= FONTPERSIST_ITALIC; |
| |
| if (this->description.fStrikethrough) |
| bAttributes |= FONTPERSIST_STRIKETHROUGH; |
| |
| if (this->description.fUnderline) |
| bAttributes |= FONTPERSIST_UNDERLINE; |
| |
| IStream_Write(pOutStream, &bAttributes, 1, &cbWritten); |
| |
| if (cbWritten!=1) |
| return E_FAIL; |
| |
| /* |
| * Weight |
| */ |
| IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten); |
| |
| if (cbWritten!=2) |
| return E_FAIL; |
| |
| /* |
| * Size |
| */ |
| IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten); |
| |
| if (cbWritten!=4) |
| return E_FAIL; |
| |
| /* |
| * FontName |
| */ |
| if (this->description.lpstrName!=0) |
| bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName, |
| strlenW(this->description.lpstrName), NULL, 0, NULL, NULL ); |
| else |
| bStringSize = 0; |
| |
| IStream_Write(pOutStream, &bStringSize, 1, &cbWritten); |
| |
| if (cbWritten!=1) |
| return E_FAIL; |
| |
| if (bStringSize!=0) |
| { |
| if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY; |
| WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName, |
| strlenW(this->description.lpstrName), |
| writeBuffer, bStringSize, NULL, NULL ); |
| |
| IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten); |
| HeapFree(GetProcessHeap(), 0, writeBuffer); |
| |
| if (cbWritten!=bStringSize) |
| return E_FAIL; |
| } |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_GetSizeMax (IPersistStream) |
| * |
| * See Windows documentation for more details on IPersistStream methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_GetSizeMax( |
| IPersistStream* iface, |
| ULARGE_INTEGER* pcbSize) |
| { |
| OLEFontImpl *this = impl_from_IPersistStream(iface); |
| |
| if (pcbSize==NULL) |
| return E_POINTER; |
| |
| pcbSize->u.HighPart = 0; |
| pcbSize->u.LowPart = 0; |
| |
| pcbSize->u.LowPart += sizeof(BYTE); /* Version */ |
| pcbSize->u.LowPart += sizeof(WORD); /* Lang code */ |
| pcbSize->u.LowPart += sizeof(BYTE); /* Flags */ |
| pcbSize->u.LowPart += sizeof(WORD); /* Weight */ |
| pcbSize->u.LowPart += sizeof(DWORD); /* Size */ |
| pcbSize->u.LowPart += sizeof(BYTE); /* StrLength */ |
| |
| if (this->description.lpstrName!=0) |
| pcbSize->u.LowPart += lstrlenW(this->description.lpstrName); |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface( |
| IConnectionPointContainer* iface, |
| REFIID riid, |
| VOID** ppvoid) |
| { |
| OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); |
| |
| return IFont_QueryInterface((IFont*)this, riid, ppvoid); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IConnectionPointContainer_Release (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release( |
| IConnectionPointContainer* iface) |
| { |
| OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); |
| |
| return IFont_Release((IFont*)this); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef( |
| IConnectionPointContainer* iface) |
| { |
| OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); |
| |
| return IFont_AddRef((IFont*)this); |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer) |
| * |
| * See Windows documentation for more details on IConnectionPointContainer |
| * methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints( |
| IConnectionPointContainer* iface, |
| IEnumConnectionPoints **ppEnum) |
| { |
| OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); |
| |
| FIXME("(%p)->(%p): stub\n", this, ppEnum); |
| return E_NOTIMPL; |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer) |
| * |
| * See Windows documentation for more details on IConnectionPointContainer |
| * methods. |
| */ |
| static HRESULT WINAPI OLEFontImpl_FindConnectionPoint( |
| IConnectionPointContainer* iface, |
| REFIID riid, |
| IConnectionPoint **ppCp) |
| { |
| OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); |
| TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppCp); |
| |
| if(IsEqualIID(riid, &IID_IPropertyNotifySink)) { |
| return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP, |
| &IID_IConnectionPoint, |
| (LPVOID)ppCp); |
| } else if(IsEqualIID(riid, &IID_IFontEventsDisp)) { |
| return IConnectionPoint_QueryInterface(this->pFontEventsCP, |
| &IID_IConnectionPoint, |
| (LPVOID)ppCp); |
| } else { |
| FIXME("no connection point for %s\n", debugstr_guid(riid)); |
| return CONNECT_E_NOCONNECTION; |
| } |
| } |
| |
| /************************************************************************ |
| * OLEFontImpl implementation of IPersistPropertyBag. |
| */ |
| static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface( |
| IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj |
| ) { |
| OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); |
| return IFont_QueryInterface((IFont *)this,riid,ppvObj); |
| } |
| |
| static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef( |
| IPersistPropertyBag *iface |
| ) { |
| OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); |
| return IFont_AddRef((IFont *)this); |
| } |
| |
| static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release( |
| IPersistPropertyBag *iface |
| ) { |
| OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); |
| return IFont_Release((IFont *)this); |
| } |
| |
| static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID( |
| IPersistPropertyBag *iface, CLSID *classid |
| ) { |
| FIXME("(%p,%p), stub!\n", iface, classid); |
| return E_FAIL; |
| } |
| |
| static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew( |
| IPersistPropertyBag *iface |
| ) { |
| FIXME("(%p), stub!\n", iface); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load( |
| IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog |
| ) { |
| /* (from Visual Basic 6 property bag) |
| Name = "MS Sans Serif" |
| Size = 13.8 |
| Charset = 0 |
| Weight = 400 |
| Underline = 0 'False |
| Italic = 0 'False |
| Strikethrough = 0 'False |
| */ |
| static const WCHAR sAttrName[] = {'N','a','m','e',0}; |
| static const WCHAR sAttrSize[] = {'S','i','z','e',0}; |
| static const WCHAR sAttrCharset[] = {'C','h','a','r','s','e','t',0}; |
| static const WCHAR sAttrWeight[] = {'W','e','i','g','h','t',0}; |
| static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0}; |
| static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0}; |
| static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0}; |
| VARIANT rawAttr; |
| VARIANT valueAttr; |
| HRESULT iRes = S_OK; |
| OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); |
| |
| VariantInit(&rawAttr); |
| VariantInit(&valueAttr); |
| |
| if (iRes == S_OK) { |
| iRes = IPropertyBag_Read(pPropBag, sAttrName, &rawAttr, pErrorLog); |
| if (iRes == S_OK) |
| { |
| iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BSTR); |
| if (iRes == S_OK) |
| iRes = IFont_put_Name((IFont *)this, V_BSTR(&valueAttr)); |
| } |
| else if (iRes == E_INVALIDARG) |
| iRes = S_OK; |
| VariantClear(&rawAttr); |
| VariantClear(&valueAttr); |
| } |
| |
| if (iRes == S_OK) { |
| iRes = IPropertyBag_Read(pPropBag, sAttrSize, &rawAttr, pErrorLog); |
| if (iRes == S_OK) |
| { |
| iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_CY); |
| if (iRes == S_OK) |
| iRes = IFont_put_Size((IFont *)this, V_CY(&valueAttr)); |
| } |
| else if (iRes == E_INVALIDARG) |
| iRes = S_OK; |
| VariantClear(&rawAttr); |
| VariantClear(&valueAttr); |
| } |
| |
| if (iRes == S_OK) { |
| iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &rawAttr, pErrorLog); |
| if (iRes == S_OK) |
| { |
| iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2); |
| if (iRes == S_OK) |
| iRes = IFont_put_Charset((IFont *)this, V_I2(&valueAttr)); |
| } |
| else if (iRes == E_INVALIDARG) |
| iRes = S_OK; |
| VariantClear(&rawAttr); |
| VariantClear(&valueAttr); |
| } |
| |
| if (iRes == S_OK) { |
| iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &rawAttr, pErrorLog); |
| if (iRes == S_OK) |
| { |
| iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2); |
| if (iRes == S_OK) |
| iRes = IFont_put_Weight((IFont *)this, V_I2(&valueAttr)); |
| } |
| else if (iRes == E_INVALIDARG) |
| iRes = S_OK; |
| VariantClear(&rawAttr); |
| VariantClear(&valueAttr); |
| |
| } |
| |
| if (iRes == S_OK) { |
| iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &rawAttr, pErrorLog); |
| if (iRes == S_OK) |
| { |
| iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); |
| if (iRes == S_OK) |
| iRes = IFont_put_Underline((IFont *)this, V_BOOL(&valueAttr)); |
| } |
| else if (iRes == E_INVALIDARG) |
| iRes = S_OK; |
| VariantClear(&rawAttr); |
| VariantClear(&valueAttr); |
| } |
| |
| if (iRes == S_OK) { |
| iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &rawAttr, pErrorLog); |
| if (iRes == S_OK) |
| { |
| iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); |
| if (iRes == S_OK) |
| iRes = IFont_put_Italic((IFont *)this, V_BOOL(&valueAttr)); |
| } |
| else if (iRes == E_INVALIDARG) |
| iRes = S_OK; |
| VariantClear(&rawAttr); |
| VariantClear(&valueAttr); |
| } |
| |
| if (iRes == S_OK) { |
| iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &rawAttr, pErrorLog); |
| if (iRes == S_OK) |
| { |
| iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); |
| if (iRes == S_OK) |
| IFont_put_Strikethrough((IFont *)this, V_BOOL(&valueAttr)); |
| } |
| else if (iRes == E_INVALIDARG) |
| iRes = S_OK; |
| VariantClear(&rawAttr); |
| VariantClear(&valueAttr); |
| } |
| |
| if (FAILED(iRes)) |
| WARN("-- 0x%08x\n", iRes); |
| return iRes; |
| } |
| |
| static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save( |
| IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty, |
| BOOL fSaveAllProperties |
| ) { |
| FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties); |
| return E_FAIL; |
| } |
| |
| static const IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable = |
| { |
| OLEFontImpl_IPersistPropertyBag_QueryInterface, |
| OLEFontImpl_IPersistPropertyBag_AddRef, |
| OLEFontImpl_IPersistPropertyBag_Release, |
| |
| OLEFontImpl_IPersistPropertyBag_GetClassID, |
| OLEFontImpl_IPersistPropertyBag_InitNew, |
| OLEFontImpl_IPersistPropertyBag_Load, |
| OLEFontImpl_IPersistPropertyBag_Save |
| }; |
| |
| /************************************************************************ |
| * OLEFontImpl implementation of IPersistStreamInit. |
| */ |
| static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface( |
| IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj |
| ) { |
| OLEFontImpl *this = impl_from_IPersistStreamInit(iface); |
| return IFont_QueryInterface((IFont *)this,riid,ppvObj); |
| } |
| |
| static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef( |
| IPersistStreamInit *iface |
| ) { |
| OLEFontImpl *this = impl_from_IPersistStreamInit(iface); |
| return IFont_AddRef((IFont *)this); |
| } |
| |
| static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release( |
| IPersistStreamInit *iface |
| ) { |
| OLEFontImpl *this = impl_from_IPersistStreamInit(iface); |
| return IFont_Release((IFont *)this); |
| } |
| |
| static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID( |
| IPersistStreamInit *iface, CLSID *classid |
| ) { |
| FIXME("(%p,%p), stub!\n", iface, classid); |
| return E_FAIL; |
| } |
| |
| static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty( |
| IPersistStreamInit *iface |
| ) { |
| FIXME("(%p), stub!\n", iface); |
| return E_FAIL; |
| } |
| |
| static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load( |
| IPersistStreamInit *iface, LPSTREAM pStm |
| ) { |
| FIXME("(%p,%p), stub!\n", iface, pStm); |
| return E_FAIL; |
| } |
| |
| static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save( |
| IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty |
| ) { |
| FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty); |
| return E_FAIL; |
| } |
| |
| static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax( |
| IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize |
| ) { |
| FIXME("(%p,%p), stub!\n", iface, pcbSize); |
| return E_FAIL; |
| } |
| |
| static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew( |
| IPersistStreamInit *iface |
| ) { |
| FIXME("(%p), stub!\n", iface); |
| return S_OK; |
| } |
| |
| static const IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable = |
| { |
| OLEFontImpl_IPersistStreamInit_QueryInterface, |
| OLEFontImpl_IPersistStreamInit_AddRef, |
| OLEFontImpl_IPersistStreamInit_Release, |
| |
| OLEFontImpl_IPersistStreamInit_GetClassID, |
| OLEFontImpl_IPersistStreamInit_IsDirty, |
| OLEFontImpl_IPersistStreamInit_Load, |
| OLEFontImpl_IPersistStreamInit_Save, |
| OLEFontImpl_IPersistStreamInit_GetSizeMax, |
| OLEFontImpl_IPersistStreamInit_InitNew |
| }; |
| |
| /******************************************************************************* |
| * StdFont ClassFactory |
| */ |
| typedef struct |
| { |
| /* IUnknown fields */ |
| const IClassFactoryVtbl *lpVtbl; |
| LONG ref; |
| } IClassFactoryImpl; |
| |
| static HRESULT WINAPI |
| SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { |
| IClassFactoryImpl *This = (IClassFactoryImpl *)iface; |
| |
| FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj); |
| return E_NOINTERFACE; |
| } |
| |
| static ULONG WINAPI |
| SFCF_AddRef(LPCLASSFACTORY iface) { |
| IClassFactoryImpl *This = (IClassFactoryImpl *)iface; |
| return InterlockedIncrement(&This->ref); |
| } |
| |
| static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) { |
| IClassFactoryImpl *This = (IClassFactoryImpl *)iface; |
| /* static class, won't be freed */ |
| return InterlockedDecrement(&This->ref); |
| } |
| |
| static HRESULT WINAPI SFCF_CreateInstance( |
| LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj |
| ) { |
| return OleCreateFontIndirect(NULL,riid,ppobj); |
| |
| } |
| |
| static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { |
| IClassFactoryImpl *This = (IClassFactoryImpl *)iface; |
| FIXME("(%p)->(%d),stub!\n",This,dolock); |
| return S_OK; |
| } |
| |
| static const IClassFactoryVtbl SFCF_Vtbl = { |
| SFCF_QueryInterface, |
| SFCF_AddRef, |
| SFCF_Release, |
| SFCF_CreateInstance, |
| SFCF_LockServer |
| }; |
| static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 }; |
| |
| void _get_STDFONT_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDFONT_CF; } |