ppgfont.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095
  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_PAGE_SEG
  12. #pragma code_seg(AFXCTL_PAGE_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. // CFontPropPage implementation
  21. BEGIN_MESSAGE_MAP(CFontPropPage, CStockPropPage)
  22. //{{AFX_MSG_MAP(CFontPropPage)
  23. ON_WM_PAINT()
  24. ON_CBN_SELCHANGE(AFX_IDC_FONTPROP, OnSelchangeFontprop)
  25. ON_CBN_EDITUPDATE(AFX_IDC_FONTNAMES, OnEditupdateFontnames)
  26. ON_CBN_EDITUPDATE(AFX_IDC_FONTSIZES, OnEditupdateFontsizes)
  27. ON_CBN_SELCHANGE(AFX_IDC_FONTNAMES, OnSelchangeFontnames)
  28. ON_CBN_SELCHANGE(AFX_IDC_FONTSIZES, OnSelchangeFontsizes)
  29. ON_CBN_SELCHANGE(AFX_IDC_FONTSTYLES, OnSelchangeFontstyles)
  30. ON_CBN_EDITCHANGE(AFX_IDC_FONTSTYLES, OnEditchangeFontstyles)
  31. ON_BN_CLICKED(AFX_IDC_STRIKEOUT, OnStrikeout)
  32. ON_BN_CLICKED(AFX_IDC_UNDERLINE, OnUnderline)
  33. //}}AFX_MSG_MAP
  34. END_MESSAGE_MAP()
  35. CFontPropPage::CFontPropPage() :
  36. CStockPropPage(IDD, AFX_IDS_FONT_PPG_CAPTION)
  37. {
  38. //{{AFX_DATA_INIT(CFontPropPage)
  39. //}}AFX_DATA_INIT
  40. }
  41. BOOL _AfxStringFromCy(CString& str, CY& cy)
  42. {
  43. VARIANTARG varCy;
  44. VARIANTARG varBstr;
  45. AfxVariantInit(&varCy);
  46. AfxVariantInit(&varBstr);
  47. V_VT(&varCy) = VT_CY;
  48. V_CY(&varCy) = cy;
  49. if (FAILED(VariantChangeType(&varBstr, &varCy, 0, VT_BSTR)))
  50. {
  51. VariantClear(&varCy);
  52. VariantClear(&varBstr);
  53. return FALSE;
  54. }
  55. str = V_BSTR(&varBstr);
  56. VariantClear(&varCy);
  57. VariantClear(&varBstr);
  58. return TRUE;
  59. }
  60. BOOL _AfxCyFromString(CY& cy, LPCTSTR psz)
  61. {
  62. USES_CONVERSION;
  63. VARIANTARG varBstr;
  64. VARIANTARG varCy;
  65. AfxVariantInit(&varBstr);
  66. AfxVariantInit(&varCy);
  67. V_VT(&varBstr) = VT_BSTR;
  68. V_BSTR(&varBstr) = SysAllocString(T2COLE(psz));
  69. if (FAILED(VariantChangeType(&varCy, &varBstr, 0, VT_CY)))
  70. {
  71. VariantClear(&varBstr);
  72. VariantClear(&varCy);
  73. return FALSE;
  74. }
  75. cy = V_CY(&varCy);
  76. VariantClear(&varBstr);
  77. VariantClear(&varCy);
  78. return TRUE;
  79. }
  80. #define DSx 0x00660046L
  81. #define DSna 0x00220326L
  82. void _AfxDrawMaskedBitmap(CDC* pDC, CBitmap* pbmp, CBitmap* pbmpMask,
  83. int x, int y, int cx, int cy)
  84. {
  85. COLORREF oldBkColor = pDC->SetBkColor(RGB(255, 255, 255));
  86. COLORREF oldTextColor = pDC->SetTextColor(RGB(0, 0, 0));
  87. CDC dcCompat;
  88. dcCompat.CreateCompatibleDC(pDC);
  89. CBitmap* pbmpSave = dcCompat.SelectObject(pbmp);
  90. pDC->BitBlt(x, y, cx, cy, &dcCompat, 0, 0, DSx);
  91. dcCompat.SelectObject(pbmpMask);
  92. pDC->BitBlt(x, y, cx, cy, &dcCompat, 0, 0, DSna);
  93. dcCompat.SelectObject(pbmp);
  94. pDC->BitBlt(x, y, cx, cy, &dcCompat, 0, 0, DSx);
  95. dcCompat.SelectObject(pbmpSave);
  96. pDC->SetBkColor(oldBkColor);
  97. pDC->SetTextColor(oldTextColor);
  98. }
  99. void _AfxInitMaskFromBitmap(CBitmap* pbmp, CBitmap* pbmpMask)
  100. {
  101. BITMAP bmp;
  102. pbmp->GetObject(sizeof (BITMAP), &bmp);
  103. pbmpMask->CreateBitmap(bmp.bmWidth, bmp.bmHeight, 1, 1, NULL);
  104. CDC dcDst;
  105. dcDst.CreateCompatibleDC(NULL);
  106. CDC dcSrc;
  107. dcSrc.CreateCompatibleDC(NULL);
  108. CBitmap* pOldDst = dcDst.SelectObject(pbmpMask);
  109. CBitmap* pOldSrc = dcSrc.SelectObject(pbmp);
  110. COLORREF oldBkColor = dcSrc.SetBkColor(dcSrc.GetPixel(0, 0));
  111. dcDst.BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &dcSrc, 0, 0, NOTSRCCOPY);
  112. dcSrc.SetBkColor(oldBkColor);
  113. dcDst.SelectObject(pOldDst);
  114. dcSrc.SelectObject(pOldSrc);
  115. }
  116. void CFontPropPage::DoDataExchange(CDataExchange* pDX)
  117. {
  118. //{{AFX_DATA_MAP(CFontPropPage)
  119. DDX_Control(pDX, AFX_IDC_FONTPROP, m_FontProp);
  120. DDX_Control(pDX, AFX_IDC_SAMPLEBOX, m_SampleBox);
  121. DDX_Control(pDX, AFX_IDC_FONTSTYLES, m_FontStyles);
  122. DDX_Control(pDX, AFX_IDC_FONTSIZES, m_FontSizes);
  123. DDX_Control(pDX, AFX_IDC_FONTNAMES, m_FontNames);
  124. //}}AFX_DATA_MAP
  125. if (pDX->m_bSaveAndValidate)
  126. {
  127. FONTOBJECT fobj;
  128. fobj.strName = m_FontNames.GetCurrentName();
  129. if (fobj.strName.IsEmpty())
  130. return;
  131. m_FontSizes.GetPointSize(fobj.cySize);
  132. if (m_nCurrentStyle & NTM_REGULAR)
  133. fobj.sWeight = FW_REGULAR;
  134. if (m_nCurrentStyle & NTM_BOLD)
  135. {
  136. fobj.sWeight = FW_BOLD;
  137. fobj.bBold = TRUE;
  138. }
  139. else
  140. fobj.bBold = FALSE;
  141. if (m_nCurrentStyle & NTM_ITALIC)
  142. fobj.bItalic = TRUE;
  143. else
  144. fobj.bItalic = FALSE;
  145. fobj.bUnderline = m_bUnderline;
  146. fobj.bStrikethrough = m_bStrikeOut;
  147. SetFontProps(pDX, fobj, m_strPropName);
  148. }
  149. else
  150. {
  151. FONTOBJECT fobj;
  152. MERGEOBJECT mobj;
  153. if (!m_strPropName.IsEmpty() && GetFontProps(pDX, &fobj, m_strPropName, &mobj))
  154. {
  155. if (fobj.bBold && fobj.bItalic)
  156. m_nCurrentStyle = NTM_BOLD | NTM_ITALIC;
  157. else if (fobj.bBold)
  158. m_nCurrentStyle = NTM_BOLD;
  159. else if (fobj.bItalic)
  160. m_nCurrentStyle = NTM_ITALIC;
  161. else
  162. m_nCurrentStyle = NTM_REGULAR;
  163. m_nActualStyle = m_nCurrentStyle;
  164. m_bUnderline = fobj.bUnderline;
  165. m_bStrikeOut = fobj.bStrikethrough;
  166. mobj.bNameOK = TRUE;
  167. mobj.bSizeOK = TRUE;
  168. mobj.bStyleOK = TRUE;
  169. mobj.bUnderlineOK = TRUE;
  170. mobj.bStrikethroughOK = TRUE;
  171. _AfxStringFromCy(m_strFontSize, fobj.cySize);
  172. SelectFontFromList(fobj.strName, &mobj);
  173. }
  174. }
  175. }
  176. BOOL CFontPropPage::SetFontProps(CDataExchange* pDX, FONTOBJECT fobj, LPCTSTR pszPropName)
  177. {
  178. USES_CONVERSION;
  179. BOOL bStatus = FALSE;
  180. COleDispatchDriver PropDispDriver;
  181. // Set the properties for all the objects
  182. ASSERT_KINDOF(COlePropertyPage, pDX->m_pDlgWnd);
  183. COlePropertyPage* propDialog = (COlePropertyPage*)(pDX->m_pDlgWnd);
  184. ULONG nObjects;
  185. LPDISPATCH* ppDisp = GetObjectArray(&nObjects);
  186. for (ULONG i = 0; i < nObjects; i++)
  187. {
  188. DISPID dwDispID;
  189. // Get the Dispatch ID for the property and if successful set the value
  190. LPCOLESTR lpOleStr = T2COLE(pszPropName);
  191. if (SUCCEEDED(ppDisp[i]->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpOleStr,
  192. 1, m_lcid, &dwDispID)))
  193. {
  194. LPDISPATCH pFontDisp = NULL;
  195. // Get property
  196. PropDispDriver.AttachDispatch(ppDisp[i], FALSE);
  197. TRY
  198. PropDispDriver.GetProperty(dwDispID, VT_DISPATCH, &pFontDisp);
  199. END_TRY
  200. PropDispDriver.DetachDispatch();
  201. if (pFontDisp == NULL)
  202. continue;
  203. // Get font interface
  204. IFont * pFont;
  205. HRESULT hresult = pFontDisp->QueryInterface(IID_IFont, (void**)&pFont);
  206. if (hresult == S_OK)
  207. {
  208. // Set font characteristics
  209. if (propDialog->GetControlStatus(AFX_IDC_FONTNAMES))
  210. {
  211. BSTR bstrName = fobj.strName.AllocSysString();
  212. pFont->put_Name(bstrName);
  213. SysFreeString(bstrName);
  214. }
  215. if (propDialog->GetControlStatus(AFX_IDC_FONTSIZES))
  216. pFont->put_Size(fobj.cySize);
  217. if (propDialog->GetControlStatus(AFX_IDC_FONTSTYLES))
  218. {
  219. pFont->put_Bold(fobj.bBold);
  220. pFont->put_Italic(fobj.bItalic);
  221. pFont->put_Weight(fobj.sWeight);
  222. }
  223. if (propDialog->GetControlStatus(AFX_IDC_UNDERLINE))
  224. pFont->put_Underline(fobj.bUnderline);
  225. if (propDialog->GetControlStatus(AFX_IDC_STRIKEOUT))
  226. pFont->put_Strikethrough(fobj.bStrikethrough);
  227. // Release the font interface
  228. RELEASE(pFont);
  229. bStatus = TRUE;
  230. }
  231. // Release the font dispatch interface
  232. RELEASE(pFontDisp);
  233. }
  234. }
  235. return bStatus;
  236. }
  237. BOOL CFontPropPage::GetFontProps(CDataExchange* /* pDX */,
  238. FONTOBJECT* pfobj, LPCTSTR pszPropName, MERGEOBJECT* pmobj)
  239. {
  240. USES_CONVERSION;
  241. BOOL bStatus = FALSE;
  242. COleDispatchDriver PropDispDriver;
  243. ULONG nObjects;
  244. LPDISPATCH* ppDisp = GetObjectArray(&nObjects);
  245. for (ULONG i = 0; i < nObjects; i++)
  246. {
  247. DISPID dwDispID;
  248. // Get the Dispatch ID for the property and if successful get the value
  249. LPCOLESTR lpOleStr = T2COLE(pszPropName);
  250. if (SUCCEEDED(ppDisp[i]->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpOleStr,
  251. 1, m_lcid, &dwDispID)))
  252. {
  253. LPDISPATCH pFontDisp;
  254. // Get property
  255. PropDispDriver.AttachDispatch(ppDisp[i], FALSE);
  256. PropDispDriver.GetProperty(dwDispID, VT_DISPATCH, &pFontDisp);
  257. PropDispDriver.DetachDispatch();
  258. if (pFontDisp == NULL)
  259. continue;
  260. // Get font interface
  261. IFont * pFont;
  262. HRESULT hresult = pFontDisp->QueryInterface(IID_IFont, (void**)&pFont);
  263. if (hresult == S_OK)
  264. {
  265. BOOL bTemp;
  266. // Set font characteristics
  267. OLECHAR *pszName;
  268. pFont->get_Name(&pszName);
  269. if (lstrcmp(OLE2CT(pszName), pfobj->strName) != 0 && i != 0)
  270. pmobj->bNameOK = FALSE;
  271. pfobj->strName = pszName;
  272. SysFreeString(pszName);
  273. CY cyTemp;
  274. pFont->get_Size(&cyTemp);
  275. if ((cyTemp.Lo != pfobj->cySize.Lo || cyTemp.Hi != pfobj->cySize.Hi) && i != 0)
  276. pmobj->bSizeOK = FALSE;
  277. pfobj->cySize = cyTemp;
  278. pFont->get_Bold(&bTemp);
  279. if (pfobj->bBold != bTemp && i != 0)
  280. pmobj->bStyleOK = FALSE;
  281. pfobj->bBold = bTemp;
  282. pFont->get_Italic(&bTemp);
  283. if (pfobj->bItalic != bTemp && i != 0)
  284. pmobj->bStyleOK = FALSE;
  285. pfobj->bItalic = bTemp;
  286. pFont->get_Underline(&bTemp);
  287. if (pfobj->bUnderline != bTemp && i != 0)
  288. pmobj->bUnderlineOK = FALSE;
  289. pfobj->bUnderline = bTemp;
  290. pFont->get_Strikethrough(&bTemp);
  291. if (pfobj->bStrikethrough != bTemp && i != 0)
  292. pmobj->bStrikethroughOK = FALSE;
  293. pfobj->bStrikethrough = bTemp;
  294. short sTemp;
  295. pFont->get_Weight(&sTemp);
  296. if (pfobj->sWeight != sTemp && i != 0)
  297. pmobj->bStyleOK = FALSE;
  298. pfobj->sWeight = sTemp;
  299. // Release the font interface
  300. RELEASE(pFont);
  301. bStatus = TRUE;
  302. }
  303. // Release font interface
  304. RELEASE(pFontDisp);
  305. }
  306. }
  307. return bStatus;
  308. }
  309. BOOL CFontPropPage::OnInitDialog()
  310. {
  311. CStockPropPage::OnInitDialog();
  312. OnObjectsChanged();
  313. IgnoreApply(AFX_IDC_FONTPROP);
  314. return TRUE; // return TRUE unless you set the focus to a control
  315. }
  316. void CFontPropPage::FillFacenameList()
  317. {
  318. // Clear the list
  319. m_FontNames.ResetContent();
  320. // Create a DC to enumerate
  321. CClientDC dc(NULL);
  322. EnumFontFamilies(dc.GetSafeHdc(), (LPCTSTR) NULL,
  323. (FONTENUMPROC)CFontPropPage::EnumFontFamiliesCallBack, (LPARAM) this);
  324. // Select the first one
  325. if (m_FontNames.SetCurSel(0) != CB_ERR)
  326. {
  327. // Fill the size list
  328. FillSizeList();
  329. }
  330. else
  331. {
  332. m_FontNames.EnableWindow(FALSE);
  333. m_FontSizes.EnableWindow(FALSE);
  334. m_FontStyles.EnableWindow(FALSE);
  335. GetDlgItem(AFX_IDC_STRIKEOUT)->EnableWindow(FALSE);
  336. GetDlgItem(AFX_IDC_UNDERLINE)->EnableWindow(FALSE);
  337. }
  338. }
  339. int CALLBACK CFontPropPage::EnumFontFamiliesCallBack(ENUMLOGFONT *lpelf, NEWTEXTMETRIC *, int FontType, LPARAM lParam)
  340. {
  341. CFontPropPage *pDlg = (CFontPropPage *)lParam;
  342. ASSERT(pDlg);
  343. pDlg->m_FontNames.AddFont(&lpelf->elfLogFont, FontType);
  344. return 1;
  345. }
  346. AFX_STATIC_DATA int _afxTTDefaults[] = { 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48 };
  347. void CFontPropPage::FillSizeList()
  348. {
  349. // Clear the size list
  350. m_FontSizes.ResetContent();
  351. m_FontStyles.ResetContent();
  352. m_nStyles = 0L;
  353. // Fill with "real" sizes
  354. CString strFaceName;
  355. m_FontNames.GetLBText(m_FontNames.GetCurSel(), strFaceName);
  356. CClientDC dc(NULL);
  357. EnumFontFamilies(dc.GetSafeHdc(), (LPCTSTR) strFaceName, (FONTENUMPROC) CFontPropPage::EnumFontFamiliesCallBack2, (LPARAM) this);
  358. // Check if we have a font that is either a vector or Truettype font
  359. if (m_FontNames.GetFontType() != RASTER_FONTTYPE)
  360. {
  361. // Fill with "common" sizes
  362. for (int i = 0; i < _countof(_afxTTDefaults); i++)
  363. m_FontSizes.AddSize(_afxTTDefaults[i], 0);
  364. }
  365. // See what fonts are native
  366. BOOL bRegular = (BOOL)(m_nStyles & NTM_REGULAR);
  367. BOOL bBold = (BOOL)(m_nStyles & NTM_BOLD);
  368. BOOL bItalic = (BOOL)(m_nStyles & NTM_ITALIC);
  369. BOOL bBoldItalic = (BOOL)((m_nStyles & NTM_BOLD) &&
  370. (m_nStyles & NTM_ITALIC));
  371. // Allow for "synthesized" italic && bold variants
  372. if (bRegular)
  373. bBold = bItalic = TRUE;
  374. if (bBold || bItalic)
  375. bBoldItalic = TRUE;
  376. // Fill the styles list box
  377. CString strStyle;
  378. int nEntry;
  379. if (bRegular)
  380. {
  381. strStyle.LoadString(AFX_IDS_REGULAR);
  382. nEntry = m_FontStyles.AddString(strStyle);
  383. m_FontStyles.SetItemData(nEntry, (DWORD)NTM_REGULAR);
  384. }
  385. if (bBold)
  386. {
  387. strStyle.LoadString(AFX_IDS_BOLD);
  388. nEntry = m_FontStyles.AddString(strStyle);
  389. m_FontStyles.SetItemData(nEntry, (DWORD)NTM_BOLD);
  390. }
  391. if (bItalic)
  392. {
  393. strStyle.LoadString(AFX_IDS_ITALIC);
  394. nEntry = m_FontStyles.AddString(strStyle);
  395. m_FontStyles.SetItemData(nEntry, (DWORD)NTM_ITALIC);
  396. }
  397. if (bBoldItalic)
  398. {
  399. strStyle.LoadString(AFX_IDS_BOLDITALIC);
  400. nEntry = m_FontStyles.AddString(strStyle);
  401. m_FontStyles.SetItemData(nEntry, (DWORD)NTM_ITALIC|NTM_BOLD);
  402. }
  403. // Set the point size
  404. if (m_FontSizes.FindString(-1, m_strFontSize) != CB_ERR)
  405. {
  406. nEntry = m_FontSizes.SelectString(-1, m_strFontSize);
  407. if (nEntry == CB_ERR)
  408. return;
  409. }
  410. else
  411. {
  412. // Point size is not in the list so just fill the edit box
  413. // and don't select anything from the list
  414. m_FontSizes.SetCurSel(-1);
  415. m_FontSizes.SetWindowText(m_strFontSize);
  416. }
  417. // Set the styles combo box selection
  418. BOOL bFound = FALSE;
  419. int nMaxEntries = m_FontStyles.GetCount();
  420. for (int nEntry3 = 0; nEntry3 < nMaxEntries; nEntry3++)
  421. {
  422. if (m_FontStyles.GetItemData(nEntry3) == m_nActualStyle)
  423. {
  424. m_FontStyles.SetCurSel(nEntry3);
  425. bFound = TRUE;
  426. }
  427. }
  428. if (!bFound)
  429. {
  430. m_FontStyles.SetCurSel(0); // Set style to regular
  431. m_nCurrentStyle = NTM_REGULAR;
  432. }
  433. else
  434. m_nCurrentStyle = m_nActualStyle;
  435. // Redraw the sample
  436. UpdateSampleFont();
  437. }
  438. int CALLBACK CFontPropPage::EnumFontFamiliesCallBack2(
  439. ENUMLOGFONT* lpelf, NEWTEXTMETRIC* lpntm, int FontType, LPARAM lParam)
  440. {
  441. CFontPropPage *pDlg = (CFontPropPage *)lParam;
  442. ASSERT(pDlg != NULL);
  443. if (FontType & TRUETYPE_FONTTYPE)
  444. {
  445. if (!(lpntm->ntmFlags & (NTM_BOLD | NTM_ITALIC)))
  446. pDlg->m_nStyles |= NTM_REGULAR;
  447. if (lpntm->ntmFlags & NTM_ITALIC)
  448. pDlg->m_nStyles |= NTM_ITALIC;
  449. if (lpntm->ntmFlags & NTM_BOLD)
  450. pDlg->m_nStyles |= NTM_BOLD;
  451. }
  452. else
  453. {
  454. if (FontType & RASTER_FONTTYPE)
  455. {
  456. int height = lpntm->tmHeight - lpntm->tmInternalLeading;
  457. pDlg->m_FontSizes.AddSize(MulDiv(height, 72, afxData.cyPixelsPerInch), height);
  458. }
  459. if (lpelf->elfLogFont.lfWeight >= FW_BOLD && lpelf->elfLogFont.lfItalic)
  460. pDlg->m_nStyles |= NTM_BOLD | NTM_ITALIC;
  461. else if (lpelf->elfLogFont.lfWeight >= FW_BOLD)
  462. pDlg->m_nStyles |= NTM_BOLD;
  463. else if (lpelf->elfLogFont.lfItalic)
  464. pDlg->m_nStyles |= NTM_ITALIC;
  465. else
  466. pDlg->m_nStyles |= NTM_REGULAR;
  467. }
  468. return 1;
  469. }
  470. #define DX_BITMAP 20
  471. #define DY_BITMAP 12
  472. /////////////////////////////////////////////////////////////////////////////
  473. // CFontComboBox
  474. CFontComboBox::CFontComboBox() : CComboBox()
  475. {
  476. m_bmpTrueType.LoadBitmap(AFX_IDB_TRUETYPE);
  477. _AfxInitMaskFromBitmap(&m_bmpTrueType, &m_bmpMask);
  478. }
  479. CFontComboBox::~CFontComboBox()
  480. {
  481. }
  482. int CFontComboBox::AddFont(LOGFONT *pLF, DWORD FontType)
  483. {
  484. int nEntry;
  485. FONTITEM_PPG* pFontItem = NULL;
  486. // Font already in the combobox
  487. if (FindString(-1, (LPCTSTR) pLF->lfFaceName) != CB_ERR)
  488. return CB_ERR;
  489. // allocate some memory for the FONTITEM_PPG structure
  490. TRY
  491. {
  492. pFontItem = new FONTITEM_PPG;
  493. }
  494. CATCH( CMemoryException, e )
  495. {
  496. return CB_ERR;
  497. }
  498. END_CATCH
  499. ASSERT( pFontItem );
  500. pFontItem->lf = *pLF;
  501. pFontItem->dwFontType = FontType;
  502. nEntry = AddString( (LPCTSTR) pFontItem->lf.lfFaceName );
  503. if (nEntry == CB_ERR)
  504. delete pFontItem;
  505. else
  506. SetItemData( nEntry, (DWORD) pFontItem );
  507. return nEntry;
  508. }
  509. FONTITEM_PPG* CFontComboBox::GetFontItem(int sel)
  510. {
  511. if (sel == -1)
  512. sel = GetCurSel();
  513. if (sel == -1)
  514. {
  515. CString str;
  516. GetWindowText( str );
  517. sel = FindString( -1, str );
  518. if (sel == CB_ERR)
  519. sel = 0;
  520. }
  521. ASSERT( GetItemData(sel) );
  522. return (FONTITEM_PPG*) GetItemData(sel);
  523. }
  524. LPLOGFONT CFontComboBox::GetLogFont(int sel)
  525. {
  526. return &GetFontItem(sel)->lf;
  527. }
  528. DWORD CFontComboBox::GetFontType(int sel)
  529. {
  530. return GetFontItem(sel)->dwFontType;
  531. }
  532. CString CFontComboBox::GetCurrentName()
  533. {
  534. CString str;
  535. GetWindowText(str);
  536. return str;
  537. }
  538. void CFontComboBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  539. {
  540. ASSERT( lpDIS->CtlType == ODT_COMBOBOX );
  541. // make sure this is a *real* item
  542. if (lpDIS->itemID == -1)
  543. return;
  544. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  545. FONTITEM_PPG* pFI = (FONTITEM_PPG*)lpDIS->itemData; // pointer to a FONTITEM storied in item data
  546. LOGFONT* pLF = &pFI->lf;
  547. COLORREF crBk, crText;
  548. TEXTMETRIC tm;
  549. int x, y;
  550. // Calculate the colors to use
  551. crBk = pDC->SetBkColor(
  552. GetSysColor(lpDIS->itemState & ODS_SELECTED ? COLOR_HIGHLIGHT : COLOR_WINDOW) );
  553. crText = pDC->SetTextColor(
  554. GetSysColor(lpDIS->itemState & ODS_SELECTED ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT) );
  555. // Calculate the position of the text
  556. pDC->GetTextMetrics( &tm );
  557. x = LOWORD(GetDialogBaseUnits()) / 4;
  558. y = (lpDIS->rcItem.bottom + lpDIS->rcItem.top - tm.tmHeight) / 2;
  559. // Draw the text
  560. pDC->ExtTextOut(lpDIS->rcItem.left + DX_BITMAP + 2 * x, y, ETO_CLIPPED | ETO_OPAQUE,
  561. &lpDIS->rcItem,(LPCTSTR) pLF->lfFaceName,
  562. lstrlen((LPCTSTR) pLF->lfFaceName), NULL );
  563. // Put the colors back as they were
  564. pDC->SetTextColor( crText );
  565. pDC->SetBkColor( crBk );
  566. // Draw the TrueType bitmap
  567. if (pFI->dwFontType & TRUETYPE_FONTTYPE)
  568. {
  569. int dy;
  570. dy = ((lpDIS->rcItem.bottom - lpDIS->rcItem.top) - DY_BITMAP) / 2;
  571. _AfxDrawMaskedBitmap(pDC, &m_bmpTrueType, &m_bmpMask,
  572. x, lpDIS->rcItem.top + dy, DX_BITMAP, DY_BITMAP);
  573. }
  574. // Draw the focus rect if needed
  575. if (lpDIS->itemState & ODS_FOCUS)
  576. pDC->DrawFocusRect( &lpDIS->rcItem );
  577. }
  578. void CFontComboBox::DeleteItem(LPDELETEITEMSTRUCT lpDIS)
  579. {
  580. FONTITEM_PPG* pFI;
  581. if (lpDIS->itemID == -1)
  582. return;
  583. ASSERT( lpDIS->CtlType == ODT_COMBOBOX );
  584. pFI = GetFontItem(lpDIS->itemID);
  585. // Free the FONTITEM_PPG created in CFontComboBox::AddFont()
  586. ASSERT(pFI);
  587. delete pFI;
  588. }
  589. /////////////////////////////////////////////////////////////////////////////
  590. // CSizeComboBox
  591. int CSizeComboBox::AddSize(int PointSize, LONG lfHeight)
  592. {
  593. if (lfHeight == 0)
  594. lfHeight = MulDiv( -afxData.cyPixelsPerInch, PointSize, 72 );
  595. CString str;
  596. wsprintf(str.GetBuffer(16), _T("%d"), PointSize);
  597. str.ReleaseBuffer();
  598. int nMaxEntries = GetCount();
  599. int nEntry;
  600. // we use positive height values for non-truetype fonts, negitive for true type
  601. if (lfHeight > 0)
  602. {
  603. for (nEntry = 0; nEntry < nMaxEntries; nEntry++)
  604. {
  605. int iComp = (int)(lfHeight - GetHeight(nEntry));
  606. if (!iComp)
  607. return CB_ERR;
  608. if (iComp < 0)
  609. break;
  610. }
  611. }
  612. else
  613. {
  614. for (nEntry = 0; nEntry < nMaxEntries; nEntry++)
  615. {
  616. int iComp = (int)(lfHeight - GetHeight(nEntry));
  617. if (!iComp)
  618. return CB_ERR;
  619. if (iComp > 0)
  620. break;
  621. }
  622. }
  623. if (nEntry == nMaxEntries)
  624. nEntry = -1;
  625. nEntry = InsertString(nEntry, str);
  626. if (nEntry != CB_ERR)
  627. SetItemData(nEntry, (DWORD)lfHeight);
  628. return nEntry;
  629. }
  630. void CSizeComboBox::GetPointSize(CY& cy)
  631. {
  632. TCHAR szText[20];
  633. GetWindowText(szText, 20);
  634. cy.Lo = 0;
  635. cy.Hi = 0;
  636. _AfxCyFromString(cy, szText);
  637. }
  638. LONG CSizeComboBox::GetHeight(int sel)
  639. {
  640. if (sel == -1)
  641. sel = GetCurSel();
  642. if (sel == -1)
  643. {
  644. TCHAR szText[20];
  645. GetWindowText(szText, 20);
  646. sel = FindString( -1, szText);
  647. if (sel == CB_ERR)
  648. {
  649. CY cyTmp;
  650. cyTmp.Lo = 0;
  651. cyTmp.Hi = 0;
  652. _AfxCyFromString(cyTmp, szText);
  653. int PointSize = (int)((cyTmp.Lo + 5000) / 10000);
  654. if (PointSize != 0)
  655. return MulDiv(-afxData.cyPixelsPerInch, PointSize, 72);
  656. else
  657. sel = 0;
  658. }
  659. }
  660. return (LONG) GetItemData(sel);
  661. }
  662. void CSizeComboBox::UpdateLogFont( LPLOGFONT lpLF, int sel )
  663. {
  664. ASSERT(lpLF);
  665. lpLF->lfHeight = (int)GetHeight(sel);
  666. lpLF->lfWidth = 0;
  667. }
  668. /////////////////////////////////////////////////////////////////////////////
  669. // CFontPropPage message handlers
  670. void CFontPropPage::OnEditupdateFontnames()
  671. {
  672. // When the users entry matches an entry in the list, select it
  673. CString str;
  674. m_FontNames.GetWindowText(str);
  675. int nEntry = m_FontNames.FindStringExact(-1, str);
  676. if (nEntry != CB_ERR)
  677. {
  678. m_FontNames.SetCurSel(nEntry);
  679. m_FontNames.SetEditSel(-1, -1);
  680. // Re-fill the size list
  681. FillSizeList();
  682. }
  683. }
  684. void CFontPropPage::OnEditupdateFontsizes()
  685. {
  686. // when the users entry matches an entry in the list, select it
  687. m_FontSizes.GetWindowText(m_strFontSize);
  688. int nEntry = m_FontSizes.FindStringExact(-1, m_strFontSize);
  689. if (nEntry != CB_ERR)
  690. {
  691. m_FontSizes.SetCurSel(nEntry);
  692. m_FontSizes.SetEditSel(-1, -1);
  693. // Update the sample text
  694. UpdateSampleFont();
  695. }
  696. }
  697. void CFontPropPage::OnSelchangeFontnames()
  698. {
  699. FillSizeList();
  700. }
  701. void CFontPropPage::UpdateSampleFont()
  702. {
  703. ASSERT(m_FontNames.GetFontItem());
  704. LOGFONT lf = *m_FontNames.GetLogFont();
  705. m_FontSizes.UpdateLogFont( &lf );
  706. // Handle styles
  707. if (m_nCurrentStyle & NTM_BOLD)
  708. lf.lfWeight = FW_BOLD;
  709. else
  710. lf.lfWeight = FW_REGULAR;
  711. if (m_nCurrentStyle & NTM_ITALIC)
  712. lf.lfItalic = TRUE;
  713. else
  714. lf.lfItalic = FALSE;
  715. lf.lfStrikeOut = (unsigned char)m_bStrikeOut;
  716. lf.lfUnderline = (unsigned char)m_bUnderline;
  717. SampleFont.DeleteObject();
  718. SampleFont.CreateFontIndirect( &lf );
  719. CRect rcSample;
  720. m_SampleBox.GetWindowRect( &rcSample );
  721. ScreenToClient( &rcSample );
  722. InvalidateRect( rcSample );
  723. UpdateWindow();
  724. }
  725. void CFontPropPage::OnPaint()
  726. {
  727. CPaintDC dc(this);
  728. CRect rcText;
  729. CFont *oldFont;
  730. CSize TextExtent;
  731. COLORREF crText;
  732. TEXTMETRIC tm;
  733. int bkMode, len, x, y;
  734. CString strSample;
  735. strSample.LoadString(AFX_IDS_SAMPLETEXT);
  736. // If there is no sample font abort
  737. if (!SampleFont.GetSafeHandle())
  738. return;
  739. // Get the bounding box
  740. m_SampleBox.GetWindowRect( &rcText );
  741. ScreenToClient( &rcText );
  742. // Select the new font and colors into the dc
  743. oldFont = dc.SelectObject( &SampleFont );
  744. crText = dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
  745. bkMode = dc.SetBkMode(TRANSPARENT);
  746. // Calculate the position of the text
  747. dc.GetTextMetrics( &tm );
  748. len = strSample.GetLength();
  749. TextExtent = dc.GetTextExtent(strSample, len);
  750. TextExtent.cy = tm.tmAscent - tm.tmInternalLeading;
  751. if ((TextExtent.cx >= (rcText.right - rcText.left)) ||
  752. (TextExtent.cx <= 0))
  753. x = rcText.left;
  754. else
  755. x = rcText.left + ((rcText.right - rcText.left) - TextExtent.cx) / 2;
  756. y = min(rcText.bottom,
  757. rcText.bottom - ((rcText.bottom - rcText.top) - TextExtent.cy) / 2);
  758. // Draw it
  759. dc.ExtTextOut(x, y - (tm.tmAscent), ETO_CLIPPED, &rcText,
  760. strSample, len, NULL);
  761. // Put the DC back the way it was
  762. dc.SetBkMode(bkMode);
  763. dc.SetTextColor(crText);
  764. if (oldFont)
  765. dc.SelectObject(oldFont);
  766. }
  767. void CFontPropPage::OnSelchangeFontsizes()
  768. {
  769. int nEntry = m_FontSizes.GetCurSel();
  770. if (nEntry != CB_ERR)
  771. {
  772. m_FontSizes.GetLBText(nEntry, m_strFontSize);
  773. UpdateSampleFont();
  774. }
  775. }
  776. void CFontPropPage::OnSelchangeFontstyles()
  777. {
  778. int nEntry = m_FontStyles.GetCurSel();
  779. m_nCurrentStyle = m_FontStyles.GetItemData(nEntry);
  780. m_nActualStyle = m_nCurrentStyle;
  781. // Update the sample font
  782. UpdateSampleFont();
  783. }
  784. void CFontPropPage::OnEditchangeFontstyles()
  785. {
  786. // when the users entry matches an entry in the list, select it
  787. CString str;
  788. m_FontStyles.GetWindowText(str);
  789. int nEntry = m_FontStyles.FindStringExact(-1, str);
  790. if (nEntry != CB_ERR)
  791. {
  792. m_FontStyles.SetCurSel(nEntry);
  793. m_FontStyles.SetEditSel(-1, -1);
  794. // Update the sample text
  795. m_nCurrentStyle = m_FontStyles.GetItemData(nEntry);
  796. m_nActualStyle = m_nCurrentStyle;
  797. UpdateSampleFont();
  798. }
  799. }
  800. void CFontPropPage::SelectFontFromList(CString strFaceName, MERGEOBJECT* pmobj)
  801. {
  802. // Set the effects buttons
  803. CButton* pStrikeOut = (CButton*) GetDlgItem(AFX_IDC_STRIKEOUT);
  804. if (!pmobj->bStrikethroughOK)
  805. pStrikeOut->SetCheck(2);
  806. else if (m_bStrikeOut)
  807. pStrikeOut->SetCheck(1);
  808. else
  809. pStrikeOut->SetCheck(0);
  810. CButton* pUnderline = (CButton*) GetDlgItem(AFX_IDC_UNDERLINE);
  811. if (!pmobj->bUnderlineOK)
  812. pStrikeOut->SetCheck(2);
  813. else if (m_bUnderline)
  814. pUnderline->SetCheck(1);
  815. else
  816. pUnderline->SetCheck(0);
  817. // Set the font facename
  818. if (pmobj->bNameOK)
  819. {
  820. int nEntry1 = m_FontNames.SelectString(-1, strFaceName);
  821. if (nEntry1 == CB_ERR)
  822. return;
  823. }
  824. // Fill the size list appropriately
  825. FillSizeList();
  826. // Set the styles combo box selection
  827. BOOL bFound = FALSE;
  828. int nMaxEntries = m_FontStyles.GetCount();
  829. for (int nEntry3 = 0; nEntry3 < nMaxEntries; nEntry3++)
  830. {
  831. if (m_FontStyles.GetItemData(nEntry3) == m_nActualStyle)
  832. {
  833. m_FontStyles.SetCurSel(nEntry3);
  834. bFound = TRUE;
  835. }
  836. }
  837. if (pmobj->bSizeOK)
  838. {
  839. if (!bFound)
  840. {
  841. m_FontStyles.SetCurSel(0); // Set style to regular
  842. m_nCurrentStyle = NTM_REGULAR;
  843. }
  844. else
  845. m_nCurrentStyle = m_nActualStyle;
  846. }
  847. UpdateSampleFont();
  848. }
  849. void CFontPropPage::OnStrikeout()
  850. {
  851. CButton* pStrikeOut = (CButton*) GetDlgItem(AFX_IDC_STRIKEOUT);
  852. if (pStrikeOut->GetCheck() == 1)
  853. m_bStrikeOut = TRUE;
  854. else
  855. m_bStrikeOut = FALSE;
  856. UpdateSampleFont();
  857. }
  858. void CFontPropPage::OnUnderline()
  859. {
  860. CButton* pUnderline = (CButton*) GetDlgItem(AFX_IDC_UNDERLINE);
  861. if (pUnderline->GetCheck() == 1)
  862. m_bUnderline = TRUE;
  863. else
  864. m_bUnderline = FALSE;
  865. UpdateSampleFont();
  866. }
  867. void CFontPropPage::OnSelchangeFontprop()
  868. {
  869. OnSelchangePropname(m_FontProp);
  870. }
  871. BOOL CFontPropPage::OnEditProperty(DISPID dispid)
  872. {
  873. return CStockPropPage::OnEditProperty(dispid, m_FontProp);
  874. }
  875. void CFontPropPage::OnObjectsChanged()
  876. {
  877. ULONG nObjects;
  878. if (GetObjectArray(&nObjects) != NULL && m_hWnd != NULL)
  879. {
  880. FillPropnameList(IID_IFontDisp, 1, m_FontProp);
  881. if ( m_FontProp.GetCount() > 0 )
  882. FillFacenameList();
  883. else
  884. {
  885. m_FontNames.EnableWindow(FALSE);
  886. m_FontSizes.EnableWindow(FALSE);
  887. m_FontStyles.EnableWindow(FALSE);
  888. GetDlgItem(AFX_IDC_STRIKEOUT)->EnableWindow(FALSE);
  889. GetDlgItem(AFX_IDC_UNDERLINE)->EnableWindow(FALSE);
  890. }
  891. }
  892. if (m_hWnd != NULL)
  893. OnSelchangeFontprop();
  894. }
  895. /////////////////////////////////////////////////////////////////////////////
  896. // Class factory for Font property page
  897. #ifdef _AFXDLL
  898. #ifdef AFXCTL_FACT_SEG
  899. #pragma code_seg(AFXCTL_FACT_SEG)
  900. #endif
  901. IMPLEMENT_OLECREATE_EX(CFontPropPage, "OCxx.CFontPropPage",
  902. 0x0be35200,0x8f91,0x11ce,0x9d,0xe3,0x00,0xaa,0x00,0x4b,0xb8,0x51)
  903. BOOL CFontPropPage::CFontPropPageFactory::UpdateRegistry(BOOL bRegister)
  904. {
  905. if (bRegister)
  906. return AfxOleRegisterPropertyPageClass(AfxGetInstanceHandle(),
  907. m_clsid, AFX_IDS_FONT_PPG);
  908. else
  909. return AfxOleUnregisterClass(m_clsid, NULL);
  910. }
  911. #endif //_AFXDLL
  912. /////////////////////////////////////////////////////////////////////////////
  913. // Force any extra compiler-generated code into AFX_INIT_SEG
  914. #ifdef AFX_INIT_SEG
  915. #pragma code_seg(AFX_INIT_SEG)
  916. #endif
  917. IMPLEMENT_DYNCREATE(CFontPropPage, CStockPropPage)