FORMATBA.CPP
上传用户:aakk678
上传日期:2022-07-09
资源大小:406k
文件大小:21k
源码类别:

界面编程

开发平台:

Visual C++

  1. // formatba.cpp : implementation file
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1997 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12. #include "stdafx.h"
  13. #include "wordpad.h"
  14. #include "wordpdoc.h"
  15. #include "wordpvw.h"
  16. #include "formatba.h"
  17. #include "strings.h"
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char BASED_CODE THIS_FILE[] = __FILE__;
  21. #endif
  22. // reserve lobyte for charset
  23. #define PRINTER_FONT 0x0100
  24. #define TT_FONT 0x0200
  25. #define DEVICE_FONT 0x0400
  26. #define BMW 16
  27. #define BMH 15
  28. static int nFontSizes[] = 
  29. {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72};
  30. int CLocalComboBox::m_nFontHeight = 0;
  31. class CFontDesc
  32. {
  33. public:
  34. CFontDesc(LPCTSTR lpszName, LPCTSTR lpszScript, BYTE nCharSet, 
  35. BYTE nPitchAndFamily, DWORD dwFlags);
  36. CString m_strName;
  37. CString m_strScript;
  38. BYTE m_nCharSet;
  39. BYTE m_nPitchAndFamily;
  40. DWORD m_dwFlags;
  41. };
  42. CFontDesc::CFontDesc(LPCTSTR lpszName, LPCTSTR lpszScript, BYTE nCharSet, 
  43. BYTE nPitchAndFamily, DWORD dwFlags)
  44. {
  45. m_strName = lpszName;
  46. m_strScript = lpszScript;
  47. m_nCharSet = nCharSet;
  48. m_nPitchAndFamily = nPitchAndFamily;
  49. m_dwFlags = dwFlags;
  50. }
  51. BEGIN_MESSAGE_MAP(CFormatBar, CToolBar)
  52. //{{AFX_MSG_MAP(CFormatBar)
  53. ON_WM_CREATE()
  54. ON_WM_DESTROY()
  55. //}}AFX_MSG_MAP
  56. ON_CBN_DROPDOWN(IDC_FONTSIZE, OnFontSizeDropDown)
  57. ON_CBN_KILLFOCUS(IDC_FONTNAME, OnFontNameKillFocus)
  58. ON_CBN_KILLFOCUS(IDC_FONTSIZE, OnFontSizeKillFocus)
  59. ON_CBN_SETFOCUS(IDC_FONTNAME, OnComboSetFocus)
  60. ON_CBN_SETFOCUS(IDC_FONTSIZE, OnComboSetFocus)
  61. ON_CBN_CLOSEUP(IDC_FONTNAME, OnComboCloseUp)
  62. ON_CBN_CLOSEUP(IDC_FONTSIZE, OnComboCloseUp)
  63. ON_REGISTERED_MESSAGE(CWordPadApp::m_nPrinterChangedMsg, OnPrinterChanged)
  64. // Global help commands
  65. END_MESSAGE_MAP()
  66. static CSize GetBaseUnits(CFont* pFont)
  67. {
  68. ASSERT(pFont != NULL);
  69. ASSERT(pFont->GetSafeHandle() != NULL);
  70. pFont = theApp.m_dcScreen.SelectObject(pFont);
  71. TEXTMETRIC tm;
  72. VERIFY(theApp.m_dcScreen.GetTextMetrics(&tm));
  73. theApp.m_dcScreen.SelectObject(pFont);
  74. // return CSize(tm.tmAveCharWidth, tm.tmHeight+tm.tmDescent);
  75. return CSize(tm.tmAveCharWidth, tm.tmHeight);
  76. }
  77. CFormatBar::CFormatBar()
  78. {
  79. CFont fnt;
  80.    fnt.Attach(GetStockObject(theApp.m_nDefFont));
  81. m_szBaseUnits = GetBaseUnits(&fnt);
  82. CLocalComboBox::m_nFontHeight = m_szBaseUnits.cy;
  83. }
  84. void CFormatBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
  85. {
  86. CToolBar::OnUpdateCmdUI(pTarget, bDisableIfNoHndler);
  87. // don't update combo boxes if either one has the focus
  88. if (!m_comboFontName.HasFocus() && !m_comboFontSize.HasFocus())
  89. SyncToView();
  90. }
  91. void CFormatBar::SyncToView()
  92. {
  93. USES_CONVERSION;
  94. // get the current font from the view and update
  95. CHARHDR fh;
  96. CHARFORMAT& cf = fh.cf;
  97. fh.hwndFrom = m_hWnd;
  98. fh.idFrom = GetDlgCtrlID();
  99. fh.code = FN_GETFORMAT;
  100. VERIFY(GetOwner()->SendMessage(WM_NOTIFY, fh.idFrom, (LPARAM)&fh));
  101. // the selection must be same font and charset to display correctly
  102. if ((cf.dwMask & (CFM_FACE|CFM_CHARSET)) == (CFM_FACE|CFM_CHARSET))
  103. m_comboFontName.MatchFont(A2T(cf.szFaceName), cf.bCharSet);
  104. else
  105. m_comboFontName.SetTheText(_T(""));
  106. // SetTwipSize only updates if different
  107. // -1 means selection is not a single point size
  108. m_comboFontSize.SetTwipSize( (cf.dwMask & CFM_SIZE) ? cf.yHeight : -1);
  109. }
  110. void CFormatBar::OnFontSizeDropDown()
  111. {
  112. CString str;
  113. m_comboFontName.GetTheText(str);
  114. LPCTSTR lpszName = NULL;
  115. BOOL bPrinterFont;
  116. int nIndex = m_comboFontName.FindStringExact(-1, str);
  117. if (nIndex != CB_ERR)
  118. {
  119. CFontDesc* pDesc = (CFontDesc*)m_comboFontName.GetItemData(nIndex);
  120. ASSERT(pDesc != NULL);
  121. bPrinterFont = pDesc->m_dwFlags & PRINTER_FONT;
  122. lpszName = pDesc->m_strName;
  123. }
  124. int nSize = m_comboFontSize.GetTwipSize();
  125. if (nSize == -2) // error
  126. {
  127. AfxMessageBox(IDS_INVALID_NUMBER, MB_OK|MB_ICONINFORMATION);
  128. nSize = m_comboFontSize.m_nTwipsLast;
  129. }
  130. else if ((nSize >= 0 && nSize < 20) || nSize > 32760)
  131. {
  132. AfxMessageBox(IDS_INVALID_FONTSIZE, MB_OK|MB_ICONINFORMATION);
  133. nSize = m_comboFontSize.m_nTwipsLast;
  134. }
  135. if (bPrinterFont)
  136. m_comboFontSize.EnumFontSizes(m_dcPrinter, lpszName);
  137. else
  138. m_comboFontSize.EnumFontSizes(theApp.m_dcScreen, lpszName);
  139. m_comboFontSize.SetTwipSize(nSize);
  140. }
  141. void CFormatBar::OnComboCloseUp()
  142. {
  143. NotifyOwner(NM_RETURN);
  144. }
  145. void CFormatBar::OnComboSetFocus()
  146. {
  147. NotifyOwner(NM_SETFOCUS);
  148. }
  149. void CFormatBar::OnFontNameKillFocus()
  150. {
  151. USES_CONVERSION;
  152. // get the current font from the view and update
  153. NotifyOwner(NM_KILLFOCUS);
  154. CCharFormat cf;
  155. cf.szFaceName[0] = NULL;
  156. // this will retrieve the font entered in the edit control
  157. // it tries to match the font to something already present in the combo box
  158. // this effectively ignores case of a font the user enters
  159. // if a user enters arial, this will cause it to become Arial
  160. CString str;
  161. m_comboFontName.GetTheText(str); // returns "arial"
  162. m_comboFontName.SetTheText(str); // selects "Arial"
  163. m_comboFontName.GetTheText(str); // returns "Arial"
  164. // if font name box is not empty
  165. if (str[0] != NULL)
  166. {
  167. cf.dwMask = CFM_FACE | CFM_CHARSET;
  168. int nIndex = m_comboFontName.FindStringExact(-1, str);
  169. if (nIndex != CB_ERR)
  170. {
  171. CFontDesc* pDesc = (CFontDesc*)m_comboFontName.GetItemData(nIndex);
  172. ASSERT(pDesc != NULL);
  173. ASSERT(pDesc->m_strName.GetLength() < LF_FACESIZE);
  174. lstrcpynA(cf.szFaceName,
  175. T2A((LPTSTR) (LPCTSTR) pDesc->m_strName), LF_FACESIZE);
  176. cf.bCharSet = pDesc->m_nCharSet;
  177. cf.bPitchAndFamily = pDesc->m_nPitchAndFamily;
  178. }
  179. else // unknown font
  180. {
  181. ASSERT(str.GetLength() < LF_FACESIZE);
  182. lstrcpynA(cf.szFaceName,
  183. T2A((LPTSTR) (LPCTSTR) str), LF_FACESIZE);
  184. cf.bCharSet = DEFAULT_CHARSET;
  185. cf.bPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  186. }
  187. SetCharFormat(cf);
  188. }
  189. }
  190. void CFormatBar::OnFontSizeKillFocus()
  191. {
  192. NotifyOwner(NM_KILLFOCUS);
  193. int nSize = m_comboFontSize.GetTwipSize();
  194. if (nSize == -2)
  195. {
  196. AfxMessageBox(IDS_INVALID_NUMBER, MB_OK|MB_ICONINFORMATION);
  197. nSize = m_comboFontSize.m_nTwipsLast;
  198. }
  199. else if ((nSize >= 0 && nSize < 20) || nSize > 32760)
  200. {
  201. AfxMessageBox(IDS_INVALID_FONTSIZE, MB_OK|MB_ICONINFORMATION);
  202. nSize = m_comboFontSize.m_nTwipsLast;
  203. }
  204. else if (nSize > 0)
  205. {
  206. CCharFormat cf;
  207. cf.dwMask = CFM_SIZE;
  208. cf.yHeight = nSize;
  209. SetCharFormat(cf);
  210. }
  211. }
  212. LONG CFormatBar::OnPrinterChanged(UINT, LONG)
  213. {
  214. theApp.CreatePrinterDC(m_dcPrinter);
  215. m_comboFontName.EnumFontFamiliesEx(m_dcPrinter);
  216. return 0;
  217. }
  218. int CFormatBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
  219. {
  220. if (CToolBar::OnCreate(lpCreateStruct) == -1)
  221. return -1;
  222. theApp.m_listPrinterNotify.AddTail(m_hWnd);
  223. CRect rect(0,0, (3*LF_FACESIZE*m_szBaseUnits.cx)/2, 200);
  224. if (!m_comboFontName.Create(WS_TABSTOP|WS_VISIBLE|WS_TABSTOP|
  225. WS_VSCROLL|CBS_DROPDOWN|CBS_SORT|CBS_AUTOHSCROLL|CBS_HASSTRINGS|
  226. CBS_OWNERDRAWFIXED, rect, this, IDC_FONTNAME))
  227. {
  228. TRACE0("Failed to create fontname combo-boxn");
  229. return -1;
  230. }
  231. m_comboFontName.LimitText(LF_FACESIZE);
  232. rect.SetRect(0, 0, 10*m_szBaseUnits.cx, 200);
  233. if (!m_comboFontSize.Create(WS_TABSTOP|WS_VISIBLE|WS_TABSTOP|
  234. WS_VSCROLL|CBS_DROPDOWN, rect, this, IDC_FONTSIZE))
  235. {
  236. TRACE0("Failed to create fontsize combo-boxn");
  237. return -1;
  238. }
  239. m_comboFontSize.LimitText(4);
  240. m_comboFontName.EnumFontFamiliesEx(m_dcPrinter);
  241. return 0;
  242. }
  243. void CFormatBar::OnDestroy() 
  244. {
  245. CToolBar::OnDestroy();
  246. POSITION pos = theApp.m_listPrinterNotify.Find(m_hWnd);
  247. ASSERT(pos != NULL);
  248. theApp.m_listPrinterNotify.RemoveAt(pos);
  249. }
  250. void CFormatBar::PositionCombos()
  251. {
  252. CRect rect;
  253. // make font name box same size as font size box
  254. // this is necessary since font name box is owner draw
  255. m_comboFontName.SetItemHeight(-1, m_comboFontSize.GetItemHeight(-1));
  256. m_comboFontName.GetWindowRect(&rect);
  257. int nHeight = rect.Height();
  258. m_comboFontName.GetWindowRect(&rect);
  259. SetButtonInfo(0, IDC_FONTNAME, TBBS_SEPARATOR, rect.Width());
  260. GetItemRect(0, &rect); // FontName ComboBox
  261. m_comboFontName.SetWindowPos(NULL, rect.left, 
  262. ((rect.Height() - nHeight) / 2) + rect.top, 0, 0, 
  263. SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
  264. m_comboFontSize.GetWindowRect(&rect);
  265. SetButtonInfo(2, IDC_FONTSIZE, TBBS_SEPARATOR, rect.Width());
  266. GetItemRect(2, &rect); // FontSize ComboBox
  267. m_comboFontSize.SetWindowPos(NULL, rect.left, 
  268. ((rect.Height() - nHeight) / 2) + rect.top, 0, 0, 
  269. SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
  270. }
  271. /////////////////////////////////////////////////////////////////////////////
  272. // CFontComboBox 
  273. BEGIN_MESSAGE_MAP(CFontComboBox, CLocalComboBox)
  274. //{{AFX_MSG_MAP(CFontComboBox)
  275. ON_WM_DESTROY()
  276. //}}AFX_MSG_MAP
  277. // Global help commands
  278. END_MESSAGE_MAP()
  279. CFontComboBox::CFontComboBox()
  280. {
  281. VERIFY(m_bmFontType.LoadBitmap(IDB_FONTTYPE));
  282. }
  283. void CFontComboBox::OnDestroy() 
  284. {
  285. // destroy all the CFontDesc's
  286. EmptyContents();
  287. CLocalComboBox::OnDestroy();
  288. }
  289. void CFontComboBox::EmptyContents()
  290. {
  291. // destroy all the CFontDesc's
  292. int nCount = GetCount();
  293. for (int i=0;i<nCount;i++)
  294. delete (CFontDesc*)GetItemData(i);
  295. }
  296. void CFontComboBox::EnumFontFamiliesEx(CDC& dc, BYTE nCharSet)
  297. {
  298. CMapStringToPtr map;
  299. CString str;
  300. GetTheText(str);
  301. EmptyContents();
  302. ResetContent();
  303. LOGFONT lf;
  304. memset(&lf, 0, sizeof(LOGFONT));
  305. lf.lfCharSet = nCharSet;
  306. if (dc.m_hDC != NULL)
  307. {
  308. if (theApp.m_bWin4)
  309. {
  310. ::EnumFontFamiliesEx(dc.m_hDC, &lf,
  311. (FONTENUMPROC) EnumFamPrinterCallBackEx, (LPARAM) this, NULL);
  312. }
  313. else
  314. {
  315. ::EnumFontFamilies(dc.m_hDC, NULL,
  316. (FONTENUMPROC) EnumFamPrinterCallBack, (LPARAM) this);
  317. }
  318. }
  319. else
  320. {
  321. HDC hDC = theApp.m_dcScreen.m_hDC;
  322. ASSERT(hDC != NULL);
  323. if (theApp.m_bWin4)
  324. {
  325. ::EnumFontFamiliesEx(hDC, &lf,
  326. (FONTENUMPROC) EnumFamScreenCallBackEx, (LPARAM) this, NULL);
  327. }
  328. else
  329. {
  330. ::EnumFontFamilies(hDC, NULL,
  331. (FONTENUMPROC) EnumFamScreenCallBack, (LPARAM) this);
  332. }
  333. }
  334. // now walk through the fonts and remove (charset) from fonts with only one
  335. int nCount = m_arrayFontDesc.GetSize();
  336. // walk through fonts adding names to string map
  337. // first time add value 0, after that add value 1
  338. for (int i = 0; i<nCount;i++)
  339. {
  340. CFontDesc* pDesc = (CFontDesc*)m_arrayFontDesc[i];
  341. void* pv = NULL;
  342. if (map.Lookup(pDesc->m_strName, pv)) // found it
  343. {
  344. if (pv == NULL) // only one entry so far
  345. {
  346. map.RemoveKey(pDesc->m_strName);
  347. map.SetAt(pDesc->m_strName, (void*)1);
  348. }
  349. }
  350. else // not found
  351. map.SetAt(pDesc->m_strName, (void*)0);
  352. }
  353. for (i = 0; i<nCount;i++)
  354. {
  355. CFontDesc* pDesc = (CFontDesc*)m_arrayFontDesc[i];
  356. CString str = pDesc->m_strName;
  357. void* pv = NULL;
  358. VERIFY(map.Lookup(str, pv));
  359. if (pv != NULL && !pDesc->m_strScript.IsEmpty())
  360. {
  361. str += " (";
  362. str += pDesc->m_strScript;
  363. str += ")";
  364. }
  365. int nIndex = AddString(str);
  366. ASSERT(nIndex >=0);
  367. if (nIndex >=0) //no error
  368. SetItemData(nIndex, (DWORD)pDesc);
  369. }
  370. SetTheText(str);
  371. m_arrayFontDesc.RemoveAll();
  372. }
  373. void CFontComboBox::AddFont(ENUMLOGFONT* pelf, DWORD dwType, LPCTSTR lpszScript)
  374. {
  375. LOGFONT& lf = pelf->elfLogFont;
  376. if (lf.lfCharSet == MAC_CHARSET) // don't put in MAC fonts, commdlg doesn't either
  377. return;
  378. // Don't display vertical font for FE platform
  379. if ((GetSystemMetrics(SM_DBCSENABLED)) && (lf.lfFaceName[0] == '@'))
  380. return;
  381. // don't put in non-printer raster fonts
  382. CFontDesc* pDesc = new CFontDesc(lf.lfFaceName, lpszScript, 
  383. lf.lfCharSet, lf.lfPitchAndFamily, dwType);
  384. m_arrayFontDesc.Add(pDesc);
  385. }
  386. BOOL CALLBACK AFX_EXPORT CFontComboBox::EnumFamScreenCallBack(ENUMLOGFONT* pelf, 
  387. NEWTEXTMETRICEX* /*lpntm*/, int FontType, LPVOID pThis)
  388. {
  389. // don't put in non-printer raster fonts
  390. if (FontType & RASTER_FONTTYPE)
  391. return 1;
  392. DWORD dwData = (FontType & TRUETYPE_FONTTYPE) ? TT_FONT : 0;
  393. ((CFontComboBox *)pThis)->AddFont(pelf, dwData);
  394. return 1;
  395. }
  396. BOOL CALLBACK AFX_EXPORT CFontComboBox::EnumFamPrinterCallBack(ENUMLOGFONT* pelf, 
  397. NEWTEXTMETRICEX* /*lpntm*/, int FontType, LPVOID pThis)
  398. {
  399. DWORD dwData = PRINTER_FONT;
  400. if (FontType & TRUETYPE_FONTTYPE)
  401. dwData |= TT_FONT;
  402. else if (FontType & DEVICE_FONTTYPE)
  403. dwData |= DEVICE_FONT;
  404. ((CFontComboBox *)pThis)->AddFont(pelf, dwData);
  405. return 1;
  406. }
  407. BOOL CALLBACK AFX_EXPORT CFontComboBox::EnumFamScreenCallBackEx(ENUMLOGFONTEX* pelf, 
  408. NEWTEXTMETRICEX* /*lpntm*/, int FontType, LPVOID pThis)
  409. {
  410. // don't put in non-printer raster fonts
  411. if (FontType & RASTER_FONTTYPE)
  412. return 1;
  413. DWORD dwData = (FontType & TRUETYPE_FONTTYPE) ? TT_FONT : 0;
  414. ((CFontComboBox *)pThis)->AddFont((ENUMLOGFONT*)pelf, dwData, CString(pelf->elfScript));
  415. return 1;
  416. }
  417. BOOL CALLBACK AFX_EXPORT CFontComboBox::EnumFamPrinterCallBackEx(ENUMLOGFONTEX* pelf, 
  418. NEWTEXTMETRICEX* /*lpntm*/, int FontType, LPVOID pThis)
  419. {
  420. DWORD dwData = PRINTER_FONT;
  421. if (FontType & TRUETYPE_FONTTYPE)
  422. dwData |= TT_FONT;
  423. else if (FontType & DEVICE_FONTTYPE)
  424. dwData |= DEVICE_FONT;
  425. ((CFontComboBox *)pThis)->AddFont((ENUMLOGFONT*)pelf, dwData, CString(pelf->elfScript));
  426. return 1;
  427. }
  428. void CFontComboBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  429. {
  430. ASSERT(lpDIS->CtlType == ODT_COMBOBOX);
  431. int id = (int)(WORD)lpDIS->itemID;
  432. CDC *pDC = CDC::FromHandle(lpDIS->hDC);
  433. CRect rc(lpDIS->rcItem);
  434. if (lpDIS->itemState & ODS_FOCUS)
  435. pDC->DrawFocusRect(rc);
  436. int nIndexDC = pDC->SaveDC();
  437. CBrush brushFill;
  438. if (lpDIS->itemState & ODS_SELECTED)
  439. {
  440. brushFill.CreateSolidBrush(::GetSysColor(COLOR_HIGHLIGHT));
  441. pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
  442. }
  443. else
  444. brushFill.CreateSolidBrush(pDC->GetBkColor());
  445. pDC->SetBkMode(TRANSPARENT);
  446. pDC->FillRect(rc, &brushFill);
  447. CFontDesc* pDesc= (CFontDesc*)lpDIS->itemData;
  448. ASSERT(pDesc != NULL);
  449. DWORD dwData = pDesc->m_dwFlags;
  450. if (dwData & (TT_FONT|DEVICE_FONT)) // truetype or device flag set by SetItemData
  451. {
  452. CDC dc;
  453. dc.CreateCompatibleDC(pDC);
  454. CBitmap* pBitmap = dc.SelectObject(&m_bmFontType);
  455. if (dwData & TT_FONT)
  456. pDC->BitBlt(rc.left, rc.top, BMW, BMH, &dc, BMW, 0, SRCAND);
  457. else // DEVICE_FONT
  458. pDC->BitBlt(rc.left, rc.top, BMW, BMH, &dc, 0, 0, SRCAND);
  459. dc.SelectObject(pBitmap);
  460. }
  461. rc.left += BMW + 6;
  462. CString strText;
  463. GetLBText(id, strText);
  464. pDC->TextOut(rc.left,rc.top,strText,strText.GetLength());
  465. pDC->RestoreDC(nIndexDC);
  466. }
  467. void CFontComboBox::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
  468. {
  469. ASSERT(lpMIS->CtlType == ODT_COMBOBOX);
  470. ASSERT(m_nFontHeight > 0);
  471. CRect rc;
  472. GetWindowRect(&rc);
  473. lpMIS->itemWidth = rc.Width();
  474. lpMIS->itemHeight = max(BMH, m_nFontHeight);
  475. }
  476. int CFontComboBox::CompareItem(LPCOMPAREITEMSTRUCT lpCIS)
  477. {
  478. ASSERT(lpCIS->CtlType == ODT_COMBOBOX);
  479. int id1 = (int)(WORD)lpCIS->itemID1;
  480. int id2 = (int)(WORD)lpCIS->itemID2;
  481. CString str1,str2;
  482. if (id1 == -1)
  483. return -1;
  484. if (id2 == -1)
  485. return 1;
  486. GetLBText(id1, str1);
  487. GetLBText(id2, str2);
  488. return str1.Collate(str2);
  489. }
  490. // find a font with the face name and charset
  491. void CFontComboBox::MatchFont(LPCTSTR lpszName, BYTE nCharSet)
  492. {
  493. int nFirstIndex = FindString(-1, lpszName);
  494. if (nFirstIndex != CB_ERR)
  495. {
  496. int nIndex = nFirstIndex;
  497. do
  498. CFontDesc* pDesc = (CFontDesc*)GetItemData(nIndex);
  499. ASSERT(pDesc != NULL);
  500. // check the actual font name to avoid matching Courier western
  501. // to Courier New western
  502. if ((nCharSet == DEFAULT_CHARSET || pDesc->m_nCharSet == nCharSet) && 
  503. lstrcmp(lpszName, pDesc->m_strName)==0)
  504. {
  505. //got a match
  506. if (GetCurSel() != nIndex)
  507. SetCurSel(nIndex);
  508. return;
  509. }
  510. nIndex = FindString(nIndex, lpszName);
  511. } while (nIndex != nFirstIndex);
  512. // loop until found or back to first item again
  513. }
  514. //enter font name
  515. SetTheText(lpszName, TRUE);
  516. }
  517. /////////////////////////////////////////////////////////////////////////////
  518. // CSizeComboBox 
  519. CSizeComboBox::CSizeComboBox()
  520. {
  521. m_nTwipsLast = 0;
  522. }
  523. void CSizeComboBox::EnumFontSizes(CDC& dc, LPCTSTR pFontName)
  524. {
  525. ResetContent();
  526. if (pFontName == NULL)
  527. return;
  528. if (pFontName[0] == NULL)
  529. return;
  530. ASSERT(dc.m_hDC != NULL);
  531. m_nLogVert = dc.GetDeviceCaps(LOGPIXELSY);
  532. ::EnumFontFamilies(dc.m_hDC, pFontName,
  533. (FONTENUMPROC) EnumSizeCallBack, (LPARAM) this);
  534. }
  535. void CSizeComboBox::TwipsToPointString(LPTSTR lpszBuf, int nTwips)
  536. {
  537. ASSERT(lpszBuf != NULL);
  538. lpszBuf[0] = NULL;
  539. if (nTwips >= 0)
  540. {
  541. // round to nearest half point
  542. nTwips = (nTwips+5)/10;
  543. if ((nTwips%2) == 0)
  544. _stprintf(lpszBuf, _T("%ld"), nTwips/2);
  545. else
  546. _stprintf(lpszBuf, _T("%.1f"), (float)nTwips/2.F);
  547. }
  548. }
  549. void CSizeComboBox::SetTwipSize(int nTwips)
  550. {
  551. if (nTwips != GetTwipSize())
  552. {
  553. TCHAR buf[10];
  554. TwipsToPointString(buf, nTwips);
  555. SetTheText(buf, TRUE);
  556. }
  557. m_nTwipsLast = nTwips;
  558. }
  559. int CSizeComboBox::GetTwipSize()
  560. {
  561. // return values
  562. // -2 -- error
  563. // -1 -- edit box empty
  564. // >=0 -- font size in twips
  565. CString str;
  566. GetTheText(str);
  567. LPCTSTR lpszText = str;
  568. while (*lpszText == ' ' || *lpszText == 't')
  569. lpszText++;
  570. if (lpszText[0] == NULL)
  571. return -1; // no text in control
  572. double d = _tcstod(lpszText, (LPTSTR*)&lpszText);
  573. while (*lpszText == ' ' || *lpszText == 't')
  574. lpszText++;
  575. if (*lpszText != NULL)
  576. return -2;   // not terminated properly
  577. return (d<0.) ? 0 : (int)(d*20.);
  578. }
  579. BOOL CALLBACK AFX_EXPORT CSizeComboBox::EnumSizeCallBack(LOGFONT FAR* /*lplf*/, 
  580. LPNEWTEXTMETRIC lpntm, int FontType, LPVOID lpv)
  581. {
  582. CSizeComboBox* pThis = (CSizeComboBox*)lpv;
  583. ASSERT(pThis != NULL);
  584. TCHAR buf[10];
  585. if (
  586. (FontType & TRUETYPE_FONTTYPE) || 
  587. !( (FontType & TRUETYPE_FONTTYPE) || (FontType & RASTER_FONTTYPE) )
  588. ) // if truetype or vector font
  589. {
  590. // this occurs when there is a truetype and nontruetype version of a font
  591. if (pThis->GetCount() != 0)
  592. pThis->ResetContent();
  593. for (int i = 0; i < 16; i++)
  594. {
  595. wsprintf(buf, _T("%d"), nFontSizes[i]);
  596. pThis->AddString(buf);
  597. }
  598. return FALSE; // don't call me again
  599. }
  600. // calc character height in pixels
  601. pThis->InsertSize(MulDiv(lpntm->tmHeight-lpntm->tmInternalLeading, 
  602. 1440, pThis->m_nLogVert));
  603. return TRUE; // call me again
  604. }
  605. void CSizeComboBox::InsertSize(int nSize)
  606. {
  607. ASSERT(nSize > 0);
  608. DWORD dwSize = (DWORD)nSize;
  609. TCHAR buf[10];
  610. TwipsToPointString(buf, nSize);
  611. if (FindStringExact(-1, buf) == CB_ERR)
  612. {
  613. int nIndex = -1;
  614. int nPos = 0;
  615. DWORD dw;
  616. while ((dw = GetItemData(nPos)) != CB_ERR)
  617. {
  618. if (dw > dwSize)
  619. {
  620. nIndex = nPos;
  621. break;
  622. }
  623. nPos++;
  624. }
  625. nIndex = InsertString(nIndex, buf);
  626. ASSERT(nIndex != CB_ERR);
  627. if (nIndex != CB_ERR)
  628. SetItemData(nIndex, dwSize);
  629. }
  630. }
  631. /////////////////////////////////////////////////////////////////////////////
  632. // CLocalComboBox 
  633. BEGIN_MESSAGE_MAP(CLocalComboBox, CComboBox)
  634. //{{AFX_MSG_MAP(CLocalComboBox)
  635. ON_WM_CREATE()
  636. //}}AFX_MSG_MAP
  637. // Global help commands
  638. END_MESSAGE_MAP()
  639. void CLocalComboBox::GetTheText(CString& str)
  640. {
  641. int nIndex = GetCurSel();
  642. if (nIndex == CB_ERR)
  643. GetWindowText(str);
  644. else
  645. GetLBText(nIndex, str);
  646. }
  647. void CLocalComboBox::SetTheText(LPCTSTR lpszText,BOOL bMatchExact)
  648. {
  649. int idx = (bMatchExact) ? FindStringExact(-1,lpszText) : 
  650. FindString(-1, lpszText);
  651. SetCurSel( (idx==CB_ERR) ? -1 : idx);
  652. if (idx == CB_ERR)
  653. SetWindowText(lpszText);
  654. }
  655. BOOL CLocalComboBox::LimitText(int nMaxChars)
  656. {
  657. BOOL b = CComboBox::LimitText(nMaxChars);
  658. if (b)
  659. m_nLimitText = nMaxChars;
  660. return b;
  661. }
  662. int CLocalComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
  663. {
  664. if (CComboBox::OnCreate(lpCreateStruct) == -1)
  665. return -1;
  666.    SendMessage(WM_SETFONT, (WPARAM)GetStockObject(theApp.m_nDefFont));
  667. return 0;
  668. }
  669. BOOL CLocalComboBox::PreTranslateMessage(MSG* pMsg)
  670. {
  671. if (pMsg->message == WM_KEYDOWN)
  672. {
  673. CFormatBar* pBar = (CFormatBar*)GetParent();
  674. switch (pMsg->wParam)
  675. {
  676. case VK_ESCAPE:
  677. pBar->SyncToView();
  678. pBar->NotifyOwner(NM_RETURN);
  679. return TRUE;
  680. case VK_RETURN:
  681. pBar->NotifyOwner(NM_RETURN);
  682. return TRUE;
  683. case VK_TAB:
  684. pBar->GetNextDlgTabItem(this)->SetFocus();
  685. return TRUE;
  686. case VK_UP:
  687. case VK_DOWN:
  688. if ((GetKeyState(VK_MENU) >= 0) && (GetKeyState(VK_CONTROL) >=0) && 
  689. !GetDroppedState())
  690. {
  691. ShowDropDown();
  692. return TRUE;
  693. }
  694. }
  695. }
  696. return CComboBox::PreTranslateMessage(pMsg);
  697. }
  698. void CFormatBar::NotifyOwner(UINT nCode)
  699. {
  700. NMHDR nm;
  701. nm.hwndFrom = m_hWnd;
  702. nm.idFrom = GetDlgCtrlID();
  703. nm.code = nCode;
  704. GetOwner()->SendMessage(WM_NOTIFY, nm.idFrom, (LPARAM)&nm);
  705. }
  706. void CFormatBar::SetCharFormat(CCharFormat& cf)
  707. {
  708. CHARHDR fnm;
  709. fnm.hwndFrom = m_hWnd;
  710. fnm.idFrom = GetDlgCtrlID();
  711. fnm.code = FN_SETFORMAT;
  712. fnm.cf = cf;
  713. VERIFY(GetOwner()->SendMessage(WM_NOTIFY, fnm.idFrom, (LPARAM)&fnm));
  714. }