olefont.c

来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 2,244 行 · 第 1/5 页

C
2,244
字号
  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;
  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;
  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);
  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;
    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?