📄 olefont.c
字号:
/*
* OLE Font encapsulation implementation
*
* This file contains an implementation of the IFont
* interface and the OleCreateFontIndirect API call.
*
* Copyright 1999 Francis Beaudet
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 const WCHAR fname[] = { 'S','y','s','t','e','m',0 };
fd.cbSizeofstruct = sizeof(fd);
fd.lpstrName = (WCHAR*)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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -