home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / BOCOLE.PAK / BOLEFONT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  19.5 KB  |  795 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectComponents
  3. // Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
  4. //
  5. // $Revision:   2.12  $
  6. //
  7. // Implements the Bolero versoin of the OLE2 font object.
  8. //----------------------------------------------------------------------------
  9. #include "BOle.h"
  10. #include "BOleCMan.h"
  11. #include "BOleFont.h"
  12. #include "BOcxCtrl.h"
  13. #include <OleCtl.h>
  14.  
  15.  
  16. //-----------
  17. //  BOleFont implementation
  18. //
  19.  
  20. // rayk - need to ensure that this object supports IPersistStream
  21. BOleFont::BOleFont (BOleClassManager *pCF, IBUnknownMain * pO) :
  22.         BOleComponent (pCF, pO),
  23.         weight (FW_NORMAL),            modified (FALSE),
  24.         charSet (DEFAULT_CHARSET),     style (fsBold),
  25.         pTI (NULLP),                   pTL (NULLP),
  26.         pF (NULLP),                    pEventList (NULLP),
  27.         cyLogical (1),                 cyHimetric (1),
  28.         bstrName (SysAllocString (OLESTR ("Arial")))
  29. //        bstrName (SysAllocString (OLESTR ("MS Sans Serif")))
  30. {
  31.   SETFONTSIZE(height, 12);
  32.   HRESULT err = LoadTypeLib (OLESTR ("bole.tlb"), &pTL);
  33.   if (!err) {
  34.     ITypeInfo *pTI;
  35.     err = pTL->GetTypeInfoOfGuid (IID_BOleFont, &pTI);
  36.   }
  37.   // EventHandler deal with ConnecctionPoints
  38.   pEventList = new BEventList (1);
  39.   if (pEventList) {
  40.     pEventList->AddRef();
  41.     pEventList->AddEventsSet (IID_IPropertyNotifySink, AsPIUnknown(this), 5);
  42.   }
  43. }
  44.  
  45.  
  46. BOleFont::~BOleFont ()
  47. {
  48.   SysFreeString (bstrName);
  49.   if (pF)
  50.     pF->Release ();
  51.   if (pTI)
  52.     pTI->Release ();
  53.   if (pTL)
  54.     pTL->Release ();
  55.   if (pEventList)
  56.     pEventList->Release();
  57.  
  58. }
  59.  
  60.  
  61. HRESULT _IFUNC BOleFont::QueryInterfaceMain (REFIID iid, LPVOID FAR *ppv)
  62. {
  63.    HRESULT hr = ResultFromScode(E_NOINTERFACE);
  64.    *ppv = NULL;
  65.  
  66.    // Self
  67.    //
  68.    if (iid == IID_BOleFont) {
  69.       (BOleFont *)*ppv = this;
  70.       AddRef();
  71.       return NOERROR;
  72.    }
  73.  
  74.    // interfaces
  75.    if (SUCCEEDED(hr = IFont_QueryInterface (this, iid, ppv))) {
  76.    }
  77.    else if (SUCCEEDED(hr = IFontDisp_QueryInterface (this, iid, ppv))) {
  78.    }
  79.    else if (SUCCEEDED(hr = IConnectionPointContainer_QueryInterface(this, iid, ppv))) {
  80.    }
  81.    else if (SUCCEEDED(hr = IDispatch_QueryInterface(this, iid, ppv))) {
  82.    }
  83.    else if (SUCCEEDED(hr = BOleComponent::QueryInterfaceMain(iid, ppv))) {
  84.    }
  85.    return hr;
  86. }
  87.  
  88.  
  89. HRESULT _IFUNC BOleFont::get_Name (BSTR FAR* pname)                   
  90. {
  91.   *pname = SysAllocString (bstrName);
  92.   if ( !(*pname))
  93.     return ResultFromScode (E_OUTOFMEMORY);
  94.   return NOERROR;
  95. }
  96.  
  97.  
  98. HRESULT _IFUNC BOleFont::get_Size (CY FAR* psize)
  99. {
  100.   XFERFONTSIZE ( (*psize), height);
  101.   return NOERROR;
  102. }
  103.  
  104.  
  105. HRESULT _IFUNC BOleFont::get_Weight (short FAR* pweight)             
  106. {
  107.   *pweight = weight;
  108.   return NOERROR;
  109. }
  110.  
  111.  
  112. HRESULT _IFUNC BOleFont::get_Charset (short FAR* pcharset)           
  113. {
  114.   *pcharset = charSet;
  115.   return NOERROR;
  116. }
  117.  
  118.  
  119. HRESULT _IFUNC BOleFont::get_Bold (BOOL FAR* pbold)                  
  120. {
  121.   *pbold = (style & fsBold) != 0;
  122.   return NOERROR;
  123. }
  124.  
  125.  
  126. HRESULT _IFUNC BOleFont::get_Italic (BOOL FAR* pitalic)              
  127. {
  128.   *pitalic = (style & fsItalic) != 0;
  129.   return NOERROR;
  130. }
  131.  
  132.  
  133. HRESULT _IFUNC BOleFont::get_Underline (BOOL FAR* punderline)        
  134. {
  135.   *punderline = (style & fsUnderline) != 0;
  136.   return NOERROR;
  137. }
  138.  
  139.  
  140. HRESULT _IFUNC BOleFont::get_Strikethrough (BOOL FAR* pstrikethrough)
  141. {
  142.   *pstrikethrough = (style & fsStrikeThrough) != 0;
  143.   return NOERROR;
  144. }
  145.  
  146.  
  147. HRESULT _IFUNC BOleFont::put_Name (BSTR name)
  148. {
  149.   if (lstrcmp (name, bstrName) != 0) {
  150.     if (PropRequestEdit (DISPID_FONT_NAME) == S_OK) {
  151.       SysReAllocString (&bstrName, name);
  152.       modified = TRUE;
  153.       PropChanged (DISPID_FONT_NAME);
  154.     }
  155.   }
  156.   return NOERROR;
  157. }
  158.  
  159.  
  160. HRESULT _IFUNC BOleFont::put_Size (CY value)   
  161. {
  162.   if ( !ISEQUALFONTSIZE (value, height)) {
  163.     if (PropRequestEdit (DISPID_FONT_NAME) == S_OK) {
  164.       XFERFONTSIZE (height, value);
  165.       modified = TRUE;
  166.       PropChanged (DISPID_FONT_SIZE);
  167.     }
  168.   }
  169.   return NOERROR;
  170. }
  171.  
  172.  
  173. HRESULT _IFUNC BOleFont::put_Bold (BOOL bold)                        
  174. {
  175.   if (bold != ((style & fsBold) != 0)) {
  176.     if (PropRequestEdit (DISPID_FONT_NAME) == S_OK) {
  177.       if (bold) {
  178.         weight = FW_BOLD;
  179.         style |= fsBold;
  180.       } else {
  181.         weight = FW_NORMAL;
  182.         style &= ~fsBold;
  183.       }
  184.       modified = TRUE;
  185.       PropChanged (DISPID_FONT_BOLD);
  186.     }
  187.   }
  188.   return NOERROR;
  189. }
  190.  
  191.  
  192. HRESULT _IFUNC BOleFont::put_Italic (BOOL italic)                    
  193. {
  194.   if (italic != ((style & fsItalic) != 0)) {
  195.     if (PropRequestEdit (DISPID_FONT_NAME) == S_OK) {
  196.       if (italic)
  197.         style |= fsItalic;
  198.       else
  199.         style &= ~fsItalic;
  200.       modified = TRUE;
  201.       PropChanged (DISPID_FONT_ITALIC);
  202.     }
  203.   }
  204.   return NOERROR;
  205. }
  206.  
  207.  
  208. HRESULT _IFUNC BOleFont::put_Underline (BOOL underline)              
  209. {
  210.   if (underline != ((style & fsUnderline) != 0)) {
  211.     if (PropRequestEdit (DISPID_FONT_NAME) == S_OK) {
  212.       if (underline)
  213.         style |= fsUnderline;
  214.       else
  215.         style &= ~fsUnderline;
  216.       modified = TRUE;
  217.       PropChanged (DISPID_FONT_UNDER);
  218.     }
  219.   }
  220.   return NOERROR;
  221. }
  222.  
  223.  
  224. HRESULT _IFUNC BOleFont::put_Strikethrough (BOOL strikethrough)      
  225. {
  226.   if (strikethrough != ((style & fsStrikeThrough) != 0)) {
  227.     if (PropRequestEdit (DISPID_FONT_NAME) == S_OK) {
  228.       if (strikethrough)
  229.         style |= fsStrikeThrough;
  230.       else
  231.         style &= ~fsStrikeThrough;
  232.       modified = TRUE;
  233.       PropChanged (DISPID_FONT_STRIKE);
  234.     }
  235.   }
  236.   return NOERROR;
  237. }
  238.  
  239.  
  240. HRESULT _IFUNC BOleFont::put_Weight (short value)                   
  241. {
  242.   if (value != weight) {
  243.     if (PropRequestEdit (DISPID_FONT_NAME) == S_OK) {
  244.       weight = value;
  245.       if (weight > (FW_BOLD + FW_NORMAL)/2 ) 
  246.         style |= fsBold;
  247.       else
  248.         style &= ~fsBold;
  249.       modified = TRUE;
  250.       PropChanged (DISPID_FONT_WEIGHT);
  251.     }
  252.   }
  253.   return NOERROR;
  254. }
  255.  
  256.  
  257. HRESULT _IFUNC BOleFont::put_Charset (short value)                 
  258. {
  259.   if (value != charSet) {
  260.     if (PropRequestEdit (DISPID_FONT_NAME) == S_OK) {
  261.       charSet = value;
  262.       modified = TRUE;
  263.       PropChanged (DISPID_FONT_CHARSET);
  264.     }
  265.   }
  266.   return NOERROR;
  267. }
  268.  
  269.  
  270. HRESULT _IFUNC BOleFont::GetTypeInfoCount (UINT FAR* pctinfo)         
  271. {
  272.   *pctinfo = 1;
  273.   if (!pTI)
  274.     *pctinfo = 0;
  275.   return NOERROR;
  276. }
  277.  
  278.  
  279. HRESULT _IFUNC BOleFont::GetTypeInfo (UINT itinfo, LCID lcid,          
  280.    ITypeInfo FAR* FAR* pptinfo)                               
  281. {
  282.   if (!pTI)
  283.     return ResultFromScode (E_NOTIMPL);
  284.   *pptinfo = pTI;
  285.   return NOERROR;
  286. }
  287.  
  288.  
  289. HRESULT _IFUNC BOleFont::GetIDsOfNames (REFIID riid, LPOLESTR FAR* rgszNames,
  290.    UINT cNames, LCID lcid, DISPID FAR* rgdispid)              
  291. {
  292.   return DispGetIDsOfNames (pTI, rgszNames, cNames, rgdispid);
  293. }
  294.  
  295.  
  296. HRESULT _IFUNC BOleFont::Invoke (DISPID dispidMember, REFIID riid, LCID lcid,
  297.    WORD wFlags, DISPPARAMS FAR* pargs, VARIANT FAR* pVarResult,
  298.    EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr)             
  299. {
  300.   HRESULT    hr = NOERROR;
  301.  
  302.   if (pVarResult)
  303.      VariantInit (pVarResult);
  304.  
  305.   if ( !(wFlags & DISPATCH_PROPERTYGET|DISPATCH_PROPERTYPUT))
  306.     return ResultFromScode(E_INVALIDARG);
  307.  
  308.   if (wFlags & DISPATCH_PROPERTYGET) {
  309.  
  310.     if ( !((IID_NULL == riid) && (pVarResult)))
  311.       return ResultFromScode(E_INVALIDARG);
  312.  
  313.     switch (dispidMember)
  314.     {
  315.       case DISPID_FONT_NAME: 
  316.          V_BSTR (pVarResult) = SysAllocString (bstrName);
  317.          if ( !(V_BSTR (pVarResult)))
  318.            return ResultFromScode (E_OUTOFMEMORY);
  319.          V_VT (pVarResult) = VT_BSTR;
  320.          break;
  321.  
  322.       case DISPID_FONT_SIZE: 
  323.          XFERFONTSIZE ( V_CY (pVarResult), height);
  324.          V_VT (pVarResult) = VT_CY;
  325.          break;
  326.  
  327.       case DISPID_FONT_CHARSET: 
  328.          V_I2 (pVarResult) = charSet; 
  329.          V_VT (pVarResult) = VT_I2;
  330.          break;
  331.  
  332.       case DISPID_FONT_BOLD: 
  333.          V_BOOL (pVarResult) = (style & fsBold) != 0;
  334.          V_VT (pVarResult) = VT_BOOL;
  335.          break;
  336.  
  337.       case DISPID_FONT_ITALIC: 
  338.          V_BOOL (pVarResult) = (style & fsItalic) != 0;
  339.          V_VT (pVarResult) = VT_BOOL;
  340.          break;
  341.  
  342.       case DISPID_FONT_UNDER: 
  343.          V_BOOL (pVarResult) = (style & fsUnderline) != 0;
  344.          V_VT (pVarResult) = VT_BOOL;
  345.          break;
  346.  
  347.       case DISPID_FONT_STRIKE: 
  348.          V_BOOL (pVarResult) = (style & fsStrikeThrough) != 0;
  349.          V_VT (pVarResult) = VT_BOOL;
  350.          break;
  351.  
  352.       case DISPID_FONT_WEIGHT: 
  353.          V_I2 (pVarResult) = weight;
  354.          V_VT (pVarResult) = VT_I2;
  355.          break;
  356.     }
  357.   } else if (wFlags & DISPATCH_PROPERTYPUT) {
  358.      if ((pargs->cArgs != 1) || (pargs->cNamedArgs != 1))
  359.        return ResultFromScode(E_INVALIDARG);
  360.      if (pargs->rgdispidNamedArgs[0] != DISPID_PROPERTYPUT)
  361.        return ResultFromScode(E_INVALIDARG);
  362.  
  363.     switch (dispidMember)
  364.     {
  365.       case DISPID_FONT_NAME: 
  366.          hr = put_Name (V_BSTR (pargs->rgvarg));
  367.          break;
  368.  
  369.       case DISPID_FONT_SIZE: 
  370.          hr = put_Size (V_CY (pargs->rgvarg));
  371.          break;
  372.  
  373.       case DISPID_FONT_CHARSET: 
  374.          hr = put_Charset (V_I2 (pargs->rgvarg));
  375.          break;
  376.  
  377.       case DISPID_FONT_BOLD: 
  378.          hr = put_Bold (V_BOOL (pargs->rgvarg));
  379.          break;
  380.  
  381.       case DISPID_FONT_ITALIC: 
  382.          hr = put_Italic (V_BOOL (pargs->rgvarg));
  383.          break;
  384.  
  385.       case DISPID_FONT_UNDER: 
  386.          hr = put_Underline (V_BOOL (pargs->rgvarg));
  387.          break;
  388.  
  389.       case DISPID_FONT_STRIKE: 
  390.          hr = put_Strikethrough (V_BOOL (pargs->rgvarg));
  391.          break;
  392.  
  393.       case DISPID_FONT_WEIGHT: 
  394.          hr = put_Weight (V_I2 (pargs->rgvarg));
  395.          break;
  396.  
  397.     }
  398.   }
  399.   return hr;
  400. }
  401.  
  402.  
  403. HRESULT _IFUNC BOleFont::get_hFont (HFONT FAR* phfont)                
  404. {
  405.   HRESULT hr;
  406.   BOleFontObj *pFontObj = NULL;
  407.  
  408.   if (!IsEqual (pF)) {
  409.     pFontObj = FindFontObj ();
  410.     if (pFontObj) {
  411.       pFontObj->AddRef ();
  412.     } else if ((!pF) || (!(pF->SingleRef()) && !IsEqual (pF))) {
  413.       pFontObj = new BOleFontObj (pFactory, NULL);
  414.       if (!pFontObj)
  415.         return ResultFromScode (E_OUTOFMEMORY);
  416.       pFactory->SetFontCache (pFontObj);
  417.     }
  418.     if (pF && pFontObj)  // if replace fontobj, release old one
  419.       pF->Release ();
  420.     if (pFontObj)        // now replace it
  421.       pF = pFontObj;
  422.     pF->CreateHFont (this);
  423.   } else if (pF->hFont == 0) 
  424.     pF->CreateHFont (this);
  425.  
  426.   *phfont = NULL;
  427.   if (pF->hFont)
  428.     *phfont = pF->hFont;
  429.   return NOERROR;
  430. }
  431.  
  432.  
  433. HRESULT _IFUNC BOleFont::Clone (IFont FAR* FAR* lplpfont)             
  434. {
  435.   IFont *pIF;
  436.  
  437.   pIF = new BOleFont (pFactory, NULL);
  438.   if (!pIF) 
  439.     return ResultFromScode (E_OUTOFMEMORY);
  440.  
  441.   pIF->put_Name (bstrName);
  442.   pIF->put_Size (height);
  443.   pIF->put_Italic (style & fsItalic);
  444.   pIF->put_Underline (style & fsUnderline);
  445.   pIF->put_Strikethrough (style & fsStrikeThrough);
  446.   pIF->put_Weight (weight);   // weight also covers fsBold
  447.   pIF->put_Charset (charSet);
  448.   *lplpfont = pIF;
  449.   return NOERROR;
  450. }
  451.  
  452.  
  453. HRESULT _IFUNC BOleFont::IsEqual (IFont FAR * lpFontOther)            
  454. {
  455.   BSTR  name = NULL;                   
  456.   BOOL  bValue;
  457.   SHORT sValue;
  458.   CY    hValue;
  459.   HRESULT hr = S_OK;
  460.  
  461.   lpFontOther->get_Bold (&bValue);
  462.   if (bValue != ((style & fsBold) != 0))
  463.     return ResultFromScode (S_FALSE);
  464.   lpFontOther->get_Italic (&bValue);
  465.   if (bValue != ((style & fsItalic) != 0))
  466.     return ResultFromScode (S_FALSE);
  467.   lpFontOther->get_Underline (&bValue);
  468.   if (bValue != ((style & fsUnderline) != 0))
  469.     return ResultFromScode (S_FALSE);
  470.   lpFontOther->get_Strikethrough (&bValue);
  471.   if (bValue != ((style & fsStrikeThrough) != 0))
  472.     return ResultFromScode (S_FALSE);
  473.   lpFontOther->get_Weight (&sValue);   // weight also covers fsBold
  474.   if (sValue != weight)
  475.     return ResultFromScode (S_FALSE);
  476.   lpFontOther->get_Charset (&sValue);
  477.   if (sValue != charSet)
  478.     return ResultFromScode (S_FALSE);
  479.   lpFontOther->get_Size (&hValue);
  480.   if ( !ISEQUALFONTSIZE (hValue, height))
  481.     return ResultFromScode (S_FALSE);
  482.   hr = lpFontOther->get_Name (&name);
  483.   if (name) {
  484.      if (lstrcmp (bstrName, name) != 0)
  485.        hr = ResultFromScode (S_FALSE);
  486.      SysFreeString (name);
  487.   }
  488.   return hr;
  489. }
  490.  
  491.  
  492. HRESULT _IFUNC BOleFont::SetRatio (long cyLog, long cyHi)   
  493. {
  494.   cyLogical  = cyLog;
  495.   cyHimetric = cyHi;
  496.   modified   = TRUE;
  497.   return NOERROR;
  498. }
  499.  
  500.  
  501. HRESULT _IFUNC BOleFont::QueryTextMetrics (LPTEXTMETRICOLE lptm)      
  502. {
  503.   HDC     hdc;
  504.   HRESULT hr;
  505.   BOOL    ret;
  506.   HFONT   hF, SaveFont;
  507.  
  508.   hr = get_hFont (&hF);
  509.   if (hr)
  510.     return hr;
  511.  
  512.   hdc = GetDC (0);
  513.   if (!hdc)
  514.     return ResultFromScode (E_NOTIMPL);
  515.  
  516.   SaveFont = (HFONT) SelectObject (hdc, hF);
  517. #if defined(_WIN32) && !defined(OLE2ANSI)
  518.   ret = GetTextMetricsW (hdc, lptm);
  519. #else
  520. #if defined(_WIN32) 
  521.   ret = GetTextMetricsA (hdc, lptm);
  522. #else
  523.   ret = GetTextMetrics (hdc, lptm);
  524. #endif
  525. #endif
  526.   SelectObject (hdc, SaveFont);
  527.   ReleaseDC (0, hdc);
  528.   if (!ret)
  529.     return ResultFromScode (E_NOTIMPL);
  530.   return NOERROR;
  531. }
  532.  
  533.  
  534. HRESULT _IFUNC BOleFont::AddRefHfont (HFONT hfont)                    
  535. {
  536.   BOleFontObj *pF = FindFontObj (hfont);
  537.   if (pF) {
  538.     pF->AddRef ();
  539.     return NOERROR;
  540.   }
  541.   else
  542.     return ResultFromScode (CTL_E_PROPERTYNOTFOUND);
  543. }
  544.  
  545.  
  546. HRESULT _IFUNC BOleFont::ReleaseHfont (HFONT hfont)                   
  547. {
  548.   BOleFontObj *pF = FindFontObj (hfont);
  549.   if (pF) {
  550.     pF->Release ();
  551.     return NOERROR;
  552.   }
  553.   else
  554.     return ResultFromScode (CTL_E_PROPERTYNOTFOUND);
  555. }
  556.  
  557.  
  558. BOOL BOleFont::IsEqual (BOleFontObj FAR * pObj)
  559. {
  560.   if (pObj && ISEQUALFONTSIZE (height, pObj->height) && 
  561.       (weight == pObj->weight) && (style == pObj->style) && 
  562.       (charSet == pObj->charSet) && 
  563.       (cyLogical == pObj->cyLogical) &&
  564.       (cyHimetric == pObj->cyHimetric) &&
  565.       ((pObj->bstrName) && (lstrcmp (bstrName, pObj->bstrName) == 0)))
  566.     return TRUE;
  567.   return FALSE;
  568. #ifdef MANUAL_WAY
  569.   BOOL res = TRUE;
  570.   if (pObj != NULLP) {
  571.     if ( !ISEQUALFONTSIZE (height, pObj->height))
  572.       res = FALSE;
  573.     if ( !(weight == pObj->weight))
  574.       res = FALSE;
  575.     if ( !(style == pObj->style))
  576.       res = FALSE;
  577.     if ( !(charSet == pObj->charSet))
  578.       res = FALSE;
  579.     BSTR  name = pObj->bstrName;                   
  580.     if ( (!name && (strcmp (bstrName, name) != 0)))
  581.       res = FALSE;
  582.     if ( (!(pObj->bstrName) && (strcmp (bstrName, pObj->bstrName) != 0)))
  583.       res = FALSE;
  584.     return res;
  585.   }
  586.   return FALSE;
  587. #endif
  588. }
  589.  
  590.  
  591. BOleFontObj *BOleFont::FindFontObj (HFONT hFont)
  592. {
  593.   BOleFontObj *pF = pFactory->GetFontCache ();
  594.  
  595.   while (pF) {
  596.     if (pF->hFont == hFont)
  597.       return pF;
  598.     pF = pF->pNext;
  599.   }
  600.   return NULLP;
  601. }
  602.  
  603.  
  604. BOleFontObj *BOleFont::FindFontObj ()
  605. {
  606.   BOleFontObj *pF = pFactory->GetFontCache ();
  607.  
  608.   while (pF) {
  609.     if (IsEqual (pF))
  610.       return pF;
  611.     pF = pF->pNext;
  612.   }
  613.   return NULLP;
  614. }
  615.  
  616. // IConnectionPointContainer methods 
  617. //
  618. HRESULT _IFUNC BOleFont::EnumConnectionPoints 
  619.                                 (LPENUMCONNECTIONPOINTS FAR* ppEnum)
  620. {
  621.   // if at least one connection point is here, return the collection!
  622.   HRESULT hr = ResultFromScode (E_NOINTERFACE);
  623.   if (pEventList && (*pEventList)[0]) {
  624.     hr = pEventList->QueryInterface (IID_IEnumConnectionPoints, 
  625.                                                    (LPVOID *)ppEnum);
  626.   }
  627.   return hr;
  628. }
  629.  
  630. HRESULT _IFUNC BOleFont::FindConnectionPoint (REFIID iid, LPCONNECTIONPOINT FAR* ppCP)
  631. {
  632.   // only one connection point for BOleFont (i.e. IPropertyNotifySink)
  633.   //
  634.   HRESULT hr = ResultFromScode (E_NOINTERFACE);
  635.   IID     TempIID;
  636.  
  637.   (*pEventList)[0]->GetConnectionInterface (&TempIID); // get iid
  638.   if (TempIID == iid) {
  639.     IConnectionPoint *pCP = (*pEventList)[0];
  640.     pCP->AddRef ();
  641.     *ppCP = pCP;
  642.     hr = NOERROR;
  643.   }
  644.   return hr;
  645. }
  646.  
  647. // Service prop notify sink connection point
  648. //
  649. HRESULT BOleFont::PropChanged (DISPID dispid)
  650. {
  651.   IBSinkList    *pSinkList;
  652.   IBEventClass  *pEC;
  653.   IPropertyNotifySink *pSink;
  654.  
  655.  
  656.   (*pEventList)[0]->QueryInterface (IID_IBEventClass, &(LPVOID) pEC);
  657.   pEC->GetSinkList (&pSinkList);
  658.   pSinkList->Reset();
  659.   while (pSinkList->NextSink (&(LPVOID)pSink) == S_OK){
  660.     pSink->OnChanged (dispid);
  661.     pSink->Release ();
  662.   }
  663.   pEC->Release ();
  664.   return NOERROR;
  665. }
  666.  
  667.  
  668. HRESULT BOleFont::PropRequestEdit (DISPID dispid)
  669. {
  670.   HRESULT        result;
  671.   IBSinkList    *pSinkList;
  672.   IBEventClass  *pEC;
  673.   IPropertyNotifySink *pSink;
  674.  
  675.   (*pEventList)[0]->QueryInterface (IID_IBEventClass, &(LPVOID) pEC);
  676.   pEC->GetSinkList (&pSinkList);
  677.   pSinkList->Reset ();
  678.   while (pSinkList->NextSink (&(LPVOID)pSink) == S_OK){
  679.     result = pSink->OnRequestEdit (dispid);
  680.     pSink->Release ();
  681.     if (FAILED (result)) 
  682.       break;
  683.   }
  684.   pEC->Release ();
  685.   return result;
  686. }
  687.  
  688.  
  689.  
  690.  
  691. // --- Font Cache implementation
  692.  
  693.  
  694. BOleFontObj::BOleFontObj (BOleClassManager *pF, IBUnknownMain * pO) :
  695.         BOleComponent (pF, pO),        weight (FW_NORMAL),  
  696.         charSet (DEFAULT_CHARSET),     style (fsBold),
  697.         hFont (0),                     bstrName (NULL),
  698.         pNext (NULL),                  pPrev (NULL),
  699.         nRefs (0)
  700.  
  701. {
  702.   SETFONTSIZE(height, 10);
  703.   nRefs = 1;
  704. }
  705.  
  706.  
  707. BOleFontObj::~BOleFontObj ()
  708. {
  709.   SysFreeString (bstrName);
  710.   if (hFont)
  711.     DeleteObject (hFont);
  712.   if (this == pFactory->GetFontCache ())
  713.     pFactory->SetFontCache (NULL);
  714.   else if (pPrev) 
  715.     pPrev->pNext = pNext;
  716.  
  717. }
  718.  
  719.  
  720. HRESULT BOleFontObj::CreateHFont (BOleFont *pBF)
  721. {
  722.   HRESULT hr;
  723.   LOGFONT LogFont;
  724.   long    ht;
  725.  
  726.   if (hFont)
  727.     DeleteObject (hFont);
  728.  
  729.   pBF->get_Size (&height);
  730.   pBF->get_Weight (&weight);
  731.   pBF->get_Charset (&charSet);
  732.   style = pBF->getStyle ();
  733.   cyHimetric = pBF->getCyHimetric ();
  734.   cyLogical  = pBF->getCyLogical ();
  735.   if (!bstrName || (lstrcmp (pBF->getName (), bstrName) != 0))
  736.   {
  737.     if (!bstrName)
  738.       bstrName = SysAllocString (pBF->getName());
  739.     else
  740.       SysReAllocString (&bstrName, pBF->getName());
  741.     lstrcpy (bstrName, pBF->getName());
  742.   }
  743.  
  744.   ht = 0;
  745.   HDC hdc = GetDC (0);
  746.   if (hdc) {
  747. #ifdef WIN32
  748.     ht = height.s.Lo / 10000;
  749. #else
  750.     ht = height.Lo / 10000; 
  751. #endif
  752.     long temp = GetDeviceCaps (hdc, LOGPIXELSY);
  753.     ht = - MulDiv (ht, GetDeviceCaps (hdc, LOGPIXELSY), 72);  // translate to pixel
  754. //    ht = - (cyHimetric * ht) / cyLogical;                    
  755.     ReleaseDC (0, hdc);
  756.   }
  757.   LogFont.lfHeight      = ht;
  758.   LogFont.lfWidth       = 0;  // have font mapper choose 
  759.   LogFont.lfEscapement  = 0;  // only straight fonts 
  760.   LogFont.lfOrientation = 0;  // no rotation 
  761.   LogFont.lfWeight      = weight;
  762.   LogFont.lfItalic      = (style & fsItalic) != 0;
  763.   LogFont.lfUnderline   = (style & fsUnderline) != 0;
  764.   LogFont.lfStrikeOut   = (style & fsStrikeThrough) != 0;
  765.   LogFont.lfCharSet     = charSet;
  766.   LogFont.lfQuality     = DEFAULT_QUALITY;
  767.   LogFont.lfOutPrecision   = OUT_DEFAULT_PRECIS;
  768.   LogFont.lfClipPrecision  = CLIP_DEFAULT_PRECIS;
  769.   LogFont.lfPitchAndFamily = DEFAULT_PITCH;
  770. #ifdef ANSI    // UNICODE conversion needed
  771.   WideCharToMultiByte (CP_ACP, 0, bstrName, lstrlen(bstrName), 
  772.                       LogFont.lfFaceName, 32, 0, 0);
  773. #else
  774.   lstrcpy (LogFont.lfFaceName, bstrName);
  775. #endif
  776.   hFont = CreateFontIndirect (&LogFont);
  777.   if (hFont)
  778.     GetObject (hFont, sizeof(LogFont), &LogFont);
  779.   return NOERROR;
  780. }
  781.  
  782.  
  783. ULONG _IFUNC BOleFontObj::AddRefMain()
  784. {
  785.   return ++nRefs;
  786. }
  787.  
  788. ULONG _IFUNC BOleFontObj::ReleaseMain()
  789. {
  790.   return --nRefs ? nRefs : (delete this, 0);
  791. }
  792.  
  793.  
  794.  
  795.