⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 olefont.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * 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 + -