ctlfont.cpp 6.1 KB

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