reactos/reactos/dll/win32/oleaut32/olefont.c
KJK::Hyperion 936851e20d Sync widl, comcat, ole32, oleaut32 and rpcrt4 to wine 1.1.12
widl can now automatically generate boilerplate code for DLLs hosting RPC proxies (and ole32 and oleaut32 now use this feature): invoke the generation automatically from rbuild rules for rpcproxy modules

svn path=/trunk/; revision=38774
2009-01-15 17:52:35 +00:00

2347 lines
65 KiB
C

/*
* 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/list.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
/***********************************************************************
* List of the HFONTs it has given out, with each one having a separate
* ref count.
*/
typedef struct _HFONTItem
{
struct list entry;
/* Reference count for that instance of the class. */
LONG ref;
/* Contain the font associated with this object. */
HFONT gdiFont;
} HFONTItem, *PHFONTItem;
static struct list OLEFontImpl_hFontList = LIST_INIT(OLEFontImpl_hFontList);
/* Counts how many fonts contain at least one lock */
static LONG ifont_cnt = 0;
/***********************************************************************
* Critical section for OLEFontImpl_hFontList
*/
static CRITICAL_SECTION OLEFontImpl_csHFONTLIST;
static CRITICAL_SECTION_DEBUG OLEFontImpl_csHFONTLIST_debug =
{
0, 0, &OLEFontImpl_csHFONTLIST,
{ &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList,
&OLEFontImpl_csHFONTLIST_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": OLEFontImpl_csHFONTLIST") }
};
static CRITICAL_SECTION OLEFontImpl_csHFONTLIST = { &OLEFontImpl_csHFONTLIST_debug, -1, 0, 0, 0, 0 };
static void HFONTItem_Delete(PHFONTItem item)
{
DeleteObject(item->gdiFont);
list_remove(&item->entry);
HeapFree(GetProcessHeap(), 0, item);
}
/***********************************************************************
* 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;
/*
* 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(const FONTDESC *fontDesc);
static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
/******************************************************************************
* 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;
this->gdiFont = 0;
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_QueryInterface (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static 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.
*/
static 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.
*/
static ULONG WINAPI OLEFontImpl_Release(
IFont* iface)
{
OLEFontImpl *this = (OLEFontImpl *)iface;
ULONG ret;
PHFONTItem ptr, next;
TRACE("(%p)->(ref=%d)\n", this, this->ref);
/* Decrease the reference count for current interface */
ret = InterlockedDecrement(&this->ref);
/* If the reference count goes down to 0, destroy. */
if (ret == 0)
{
ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt);
/* Check if all HFONT list refs are zero */
if (fontlist_refs == 0)
{
EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry)
HFONTItem_Delete(ptr);
LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
}
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;
PHFONTItem newEntry;
/*
* 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);
/* Add font to the cache */
newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(HFONTItem));
newEntry->ref = 1;
newEntry->gdiFont = this->gdiFont;
EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
list_add_tail(&OLEFontImpl_hFontList,&newEntry->entry);
LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
}
*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;
PHFONTItem newEntry;
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);
/* Add font to the cache */
InterlockedIncrement(&ifont_cnt);
newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(HFONTItem));
newEntry->ref = 1;
newEntry->gdiFont = newObject->gdiFont;
EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
list_add_tail(&OLEFontImpl_hFontList,&newEntry->entry);
LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
/* 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;
INT ret;
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);
ret = CompareStringW(0,0,left->description.lpstrName, left_len,
right->description.lpstrName, right_len);
if (ret != 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;
PHFONTItem ptr, next;
HRESULT hres = S_FALSE; /* assume not present */
TRACE("(%p)->(%p)\n", this, hfont);
if (!hfont)
return E_INVALIDARG;
/* Check of the hFont is already in the list */
EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry)
{
if (ptr->gdiFont == hfont)
{
ptr->ref++;
hres = S_OK;
break;
}
}
LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
return hres;
}
/************************************************************************
* 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;
PHFONTItem ptr, next;
HRESULT hres = S_FALSE; /* assume not present */
TRACE("(%p)->(%p)\n", this, hfont);
if (!hfont)
return E_INVALIDARG;
/* Check of the hFont is already in the list */
EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry)
{
if ((ptr->gdiFont == hfont) && ptr->ref)
{
/* Remove from cache and delete object if not referenced */
if (!--ptr->ref)
{
if (ptr->gdiFont == this->gdiFont)
this->gdiFont = NULL;
}
hres = S_OK;
break;
}
}
LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
return hres;
}
/************************************************************************
* 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;
}
/*
* 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
};
/************************************************************************
* 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);
ITypeLib_Release(tl);
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;
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;
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;
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;
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;
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;
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;
}
}
static const IDispatchVtbl OLEFontImpl_IDispatch_VTable =
{
OLEFontImpl_IDispatch_QueryInterface,
OLEFontImpl_IDispatch_AddRef,
OLEFontImpl_IDispatch_Release,
OLEFontImpl_GetTypeInfoCount,
OLEFontImpl_GetTypeInfo,
OLEFontImpl_GetIDsOfNames,
OLEFontImpl_Invoke
};
/************************************************************************
* 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;
*pClassID = 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 += WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
strlenW(this->description.lpstrName),
NULL, 0, NULL, NULL );
return S_OK;
}
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
};
/************************************************************************
* 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;
}
}
static const IConnectionPointContainerVtbl
OLEFontImpl_IConnectionPointContainer_VTable =
{
OLEFontImpl_IConnectionPointContainer_QueryInterface,
OLEFontImpl_IConnectionPointContainer_AddRef,
OLEFontImpl_IConnectionPointContainer_Release,
OLEFontImpl_EnumConnectionPoints,
OLEFontImpl_FindConnectionPoint
};
/************************************************************************
* 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
};
/************************************************************************
* 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(const FONTDESC *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->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;
}
InterlockedIncrement(&ifont_cnt);
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);
}
/*******************************************************************************
* 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; }