home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / ctlfont.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  6KB  |  284 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFXCTL_CORE2_SEG
  14. #pragma code_seg(AFXCTL_CORE2_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CFontHolder
  26.  
  27. CFontHolder::CFontHolder(LPPROPERTYNOTIFYSINK pNotify) :
  28.     m_pFont(NULL),
  29.     m_dwConnectCookie(0),
  30.     m_pNotify(pNotify)
  31. {
  32.     ASSERT_NULL_OR_POINTER(pNotify, IPropertyNotifySink);
  33. }
  34.  
  35. void CFontHolder::SetFontNotifySink(LPPROPERTYNOTIFYSINK pNotify)
  36. {
  37.     ASSERT_NULL_OR_POINTER(pNotify, IPropertyNotifySink);
  38.     m_pNotify = pNotify;
  39. }
  40.  
  41. CFontHolder::~CFontHolder()
  42. {
  43.     ReleaseFont();
  44. }
  45.  
  46. void CFontHolder::ReleaseFont()
  47. {
  48.     if ((m_pFont != NULL) && (m_pNotify != NULL))
  49.     {
  50.         AfxConnectionUnadvise(m_pFont, IID_IPropertyNotifySink, m_pNotify,
  51.             FALSE, m_dwConnectCookie);
  52.     }
  53.  
  54.     RELEASE(m_pFont);
  55. }
  56.  
  57. AFX_STATIC_DATA const FONTDESC _afxFontDescDefault =
  58.     { sizeof(FONTDESC), OLESTR("MS Sans Serif"), FONTSIZE(12), FW_NORMAL,
  59.       DEFAULT_CHARSET, FALSE, FALSE, FALSE };
  60.  
  61. void CFontHolder::InitializeFont(const FONTDESC* pFontDesc,
  62.     LPDISPATCH pFontDispAmbient)
  63. {
  64.     ASSERT_NULL_OR_POINTER(pFontDesc, FONTDESC);
  65.     ASSERT_NULL_OR_POINTER(pFontDispAmbient, IDispatch);
  66. #ifdef _DEBUG
  67.     if (pFontDesc != NULL)
  68.         ASSERT(pFontDesc->cbSizeofstruct == sizeof(FONTDESC));
  69. #endif
  70.  
  71.     // Release any previous font, in preparation for creating a new one.
  72.     ReleaseFont();
  73.  
  74.     LPFONT pFontAmbient;
  75.     LPFONT pFontNew = NULL;
  76.  
  77.     if ((pFontDispAmbient != NULL) &&
  78.         SUCCEEDED(pFontDispAmbient->QueryInterface(IID_IFont,
  79.                 (LPVOID*)&pFontAmbient)))
  80.     {
  81.         ASSERT_POINTER(pFontAmbient, IFont);
  82.  
  83.         // Make a clone of the ambient font.
  84.         pFontAmbient->Clone(&pFontNew);
  85.         pFontAmbient->Release();
  86.     }
  87.     else
  88.     {
  89.         // Create the font.
  90.         if (pFontDesc == NULL)
  91.             pFontDesc = &_afxFontDescDefault;
  92.  
  93.         if (FAILED(::OleCreateFontIndirect((LPFONTDESC)pFontDesc, IID_IFont,
  94.                 (LPVOID *)&pFontNew)))
  95.             pFontNew = NULL;
  96.     }
  97.  
  98.     // Setup advisory connection and find dispatch interface.
  99.     if (pFontNew != NULL)
  100.         SetFont(pFontNew);
  101. }
  102.  
  103. BOOL AFXAPI _AfxIsSameFont(CFontHolder& font, const FONTDESC* pFontDesc,
  104.     LPFONTDISP pFontDispAmbient)
  105. {
  106.     if (font.m_pFont == NULL)
  107.         return FALSE;
  108.  
  109.     BOOL bSame = FALSE;
  110.  
  111.     if (pFontDispAmbient != NULL)
  112.     {
  113.         LPFONT pFontAmbient;
  114.         if (SUCCEEDED(pFontDispAmbient->QueryInterface(IID_IFont,
  115.             (LPVOID*)&pFontAmbient)))
  116.         {
  117.             ASSERT_POINTER(pFontAmbient, IFont);
  118.             bSame = pFontAmbient->IsEqual(font.m_pFont) == S_OK;
  119.             pFontAmbient->Release();
  120.         }
  121.     }
  122.     else
  123.     {
  124.         if (pFontDesc == NULL)
  125.             pFontDesc = &_afxFontDescDefault;
  126.  
  127.         bSame = TRUE;
  128.         BOOL bFlag;
  129.  
  130.         font.m_pFont->get_Italic(&bFlag);
  131.         bSame = (bFlag == pFontDesc->fItalic);
  132.  
  133.         if (bSame)
  134.         {
  135.             font.m_pFont->get_Underline(&bFlag);
  136.             bSame = (bFlag == pFontDesc->fUnderline);
  137.         }
  138.  
  139.         if (bSame)
  140.         {
  141.             font.m_pFont->get_Strikethrough(&bFlag);
  142.             bSame = (bFlag == pFontDesc->fStrikethrough);
  143.         }
  144.  
  145.         if (bSame)
  146.         {
  147.             short sCharset;
  148.             font.m_pFont->get_Charset(&sCharset);
  149.             bSame = (sCharset == pFontDesc->sCharset);
  150.         }
  151.  
  152.         if (bSame)
  153.         {
  154.             short sWeight;
  155.             font.m_pFont->get_Weight(&sWeight);
  156.             bSame = (sWeight == pFontDesc->sWeight);
  157.         }
  158.  
  159.         if (bSame)
  160.         {
  161.             CURRENCY cy;
  162.             font.m_pFont->get_Size(&cy);
  163.             bSame = (memcmp(&cy, &pFontDesc->cySize, sizeof(CURRENCY)) == 0);
  164.         }
  165.  
  166.         if (bSame)
  167.         {
  168.             BSTR bstrName;
  169.             font.m_pFont->get_Name(&bstrName);
  170.             CString strName1(bstrName);
  171.             CString strName2(pFontDesc->lpstrName);
  172.             bSame = (strName1 == strName2);
  173.             SysFreeString(bstrName);
  174.         }
  175.     }
  176.  
  177.     return bSame;
  178. }
  179.  
  180. HFONT CFontHolder::GetFontHandle()
  181. {
  182.     // Assume a screen DC for logical/himetric ratio.
  183.     return GetFontHandle(afxData.cyPixelsPerInch, HIMETRIC_PER_INCH);
  184. }
  185.  
  186. HFONT CFontHolder::GetFontHandle(long cyLogical, long cyHimetric)
  187. {
  188.     HFONT hFont = NULL;
  189.  
  190.     if ((m_pFont != NULL) &&
  191.         SUCCEEDED(m_pFont->SetRatio(cyLogical, cyHimetric)) &&
  192.         SUCCEEDED(m_pFont->get_hFont(&hFont)))
  193.     {
  194.         ASSERT(hFont != NULL);
  195.     }
  196.  
  197.     return hFont;
  198. }
  199.  
  200. CFont* CFontHolder::Select(CDC* pDC, long cyLogical, long cyHimetric)
  201. {
  202.     ASSERT_POINTER(pDC, CDC);
  203.  
  204.     HFONT hFont = NULL;
  205.  
  206.     if (m_pFont != NULL)
  207.         hFont = GetFontHandle(cyLogical, cyHimetric);
  208.  
  209.     if (hFont != NULL)
  210.     {
  211.         if ((pDC->m_hAttribDC != pDC->m_hDC) &&
  212.             (pDC->m_hAttribDC != NULL))
  213.         {
  214.             ::SelectObject(pDC->m_hAttribDC, hFont);
  215.         }
  216.  
  217.         return CFont::FromHandle((HFONT)::SelectObject(pDC->m_hDC, hFont));
  218.     }
  219.  
  220.     return NULL;
  221. }
  222.  
  223. void CFontHolder::QueryTextMetrics(LPTEXTMETRIC lptm)
  224. {
  225.     ASSERT(lptm != NULL);
  226.  
  227.     if (m_pFont != NULL)
  228.     {
  229. #if defined(_UNICODE) || defined(OLE2ANSI)
  230.         // no conversion necessary
  231.         m_pFont->QueryTextMetrics(lptm);
  232. #else
  233.         TEXTMETRICW tmw;
  234.         m_pFont->QueryTextMetrics(&tmw);
  235.         AfxTextMetricW2A(lptm, &tmw);
  236. #endif
  237.     }
  238.     else
  239.     {
  240.         memset(lptm, 0, sizeof(TEXTMETRIC));
  241.     }
  242. }
  243.  
  244. LPFONTDISP CFontHolder::GetFontDispatch()
  245. {
  246.     LPFONTDISP pFontDisp = NULL;
  247.  
  248.     if ((m_pFont != NULL) &&
  249.         SUCCEEDED(m_pFont->QueryInterface(IID_IFontDisp, (LPVOID*)&pFontDisp)))
  250.     {
  251.         ASSERT_POINTER(pFontDisp, IFontDisp);
  252.     }
  253.  
  254.     return pFontDisp;
  255. }
  256.  
  257. void CFontHolder::SetFont(LPFONT pFontNew)
  258. {
  259.     ASSERT_NULL_OR_POINTER(pFontNew, IFont);
  260.  
  261.     if (m_pFont != NULL)
  262.         ReleaseFont();
  263.  
  264.     m_pFont = pFontNew;
  265.  
  266.     if (m_pNotify != NULL)
  267.     {
  268.         AfxConnectionAdvise(m_pFont, IID_IPropertyNotifySink, m_pNotify,
  269.             FALSE, &m_dwConnectCookie);
  270.     }
  271. }
  272.  
  273. BOOL CFontHolder::GetDisplayString(CString& strValue)
  274. {
  275.     return strValue.LoadString(AFX_IDS_DISPLAYSTRING_FONT);
  276. }
  277.  
  278. /////////////////////////////////////////////////////////////////////////////
  279. // Force any extra compiler-generated code into AFX_INIT_SEG
  280.  
  281. #ifdef AFX_INIT_SEG
  282. #pragma code_seg(AFX_INIT_SEG)
  283. #endif
  284.