home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 21 / IOPROG_21.ISO / SOFT / FONTC.ZIP / TEMP / FontTest / FontCombo.cpp next >
Encoding:
C/C++ Source or Header  |  1998-09-25  |  14.3 KB  |  644 lines

  1. // FontBox.cpp : implementation file
  2. //
  3.  
  4. #include "Stdafx.h"
  5. #include "resource.h"
  6. #include "FontCombo.h"
  7.  
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13.  
  14. // Constant and should not be changed unless 
  15. // image IDB_GLYPH is changed
  16. #define GLYPH_WIDTH 15 
  17.  
  18. //////////////////////////////////////////////////////////////////////////
  19. // ⌐ Paramax Technology Limited                                         // 
  20. // ----------------------------                                         //
  21. //                                                                      //
  22. // The author accepts no liablility for injury or loss of profits       // 
  23. // if this software is used. You willingness to use this software       //
  24. // indicates you accept total liability                                 //
  25. //                                                                      // 
  26. //////////////////////////////////////////////////////////////////////////
  27.  
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CFontCombo
  30.  
  31. ////////////////////////////////////////////////////////////////////////////////
  32. //
  33. // FUNCTION:    CACFontCombo::CFontCombo
  34. //
  35. // DESCRIPTION:    Constructor
  36. //
  37. // INPUTS:        
  38. //
  39. // RETURNS:     
  40. //
  41. // NOTES:       
  42. //
  43. // MODIFICATIONS:
  44. //
  45. // Name            Date      Version    Comments
  46. // N T ALMOND   25/09/98  1.0        Origin
  47. //
  48. ////////////////////////////////////////////////////////////////////////////////
  49. CFontCombo::CFontCombo()
  50. {
  51.     // Load up glyphs
  52.     m_img.Create(IDB_GLYPHS,15,1,RGB(255,0,255));
  53.  
  54. }
  55.  
  56. ////////////////////////////////////////////////////////////////////////////////
  57. //
  58. // FUNCTION:    CFontCombo::~CFontCombo
  59. //
  60. // DESCRIPTION:    Constructor
  61. //
  62. // INPUTS:        
  63. //
  64. // RETURNS:     
  65. //
  66. // NOTES:       
  67. //
  68. // MODIFICATIONS:
  69. //
  70. // Name            Date      Version    Comments
  71. // N T ALMOND   25/09/98  1.0        Origin
  72. //
  73. ////////////////////////////////////////////////////////////////////////////////
  74. CFontCombo::~CFontCombo()
  75. {
  76. }
  77.  
  78. BEGIN_MESSAGE_MAP(CFontCombo, CComboBox)
  79.     //{{AFX_MSG_MAP(CFontCombo)
  80.     ON_WM_CREATE()
  81.     ON_WM_DESTROY()
  82.     ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillfocus)
  83.     ON_CONTROL_REFLECT(CBN_SETFOCUS, OnSetfocus)
  84.     ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseUp)
  85.     ON_WM_TIMER()
  86.     //}}AFX_MSG_MAP
  87. END_MESSAGE_MAP()
  88.  
  89. /////////////////////////////////////////////////////////////////////////////
  90. // CFontCombo message handlers
  91. // Overridables for onwerdraw combos
  92. void CFontCombo::DeleteItem(LPDELETEITEMSTRUCT) 
  93. {
  94. }
  95. // Overridables for onwerdraw combos
  96. void CFontCombo::MeasureItem(LPMEASUREITEMSTRUCT) 
  97. {
  98. }
  99.  
  100. // Initialize fonts for combo
  101. int CFontCombo::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  102. {
  103.     if (CComboBox::OnCreate(lpCreateStruct) == -1)
  104.         return -1;
  105.  
  106.     Initialize();
  107.  
  108.     return 0;
  109. }
  110.  
  111. ////////////////////////////////////////////////////////////////////////////////
  112. //
  113. // FUNCTION:    CFontCombo::DrawItem
  114. //
  115. // DESCRIPTION:    Owner draw to render bitmap and font name
  116. //
  117. // INPUTS:        
  118. //
  119. // RETURNS:     
  120. //
  121. // NOTES:       
  122. //
  123. // MODIFICATIONS:
  124. //
  125. // Name            Date      Version    Comments
  126. // N T ALMOND   25/09/98  1.0        Origin
  127. //
  128. ////////////////////////////////////////////////////////////////////////////////
  129. void CFontCombo::DrawItem(LPDRAWITEMSTRUCT lpDIS) 
  130. {
  131.     ASSERT(lpDIS->CtlType == ODT_COMBOBOX); // We've gotta be a combo
  132.  
  133.     // Lets make a CDC for ease of use
  134.     CDC *pDC = CDC::FromHandle(lpDIS->hDC);
  135.     
  136.     ASSERT(pDC); // Attached failed
  137.     
  138.     CRect rc(lpDIS->rcItem);
  139.     
  140.     // Draw focus rectangle
  141.     if (lpDIS->itemState & ODS_FOCUS)
  142.         pDC->DrawFocusRect(rc);
  143.     
  144.     // Save off context attributes
  145.     int nIndexDC = pDC->SaveDC();
  146.  
  147.     CBrush brushFill;
  148.     
  149.     // Draw selection state
  150.     if (lpDIS->itemState & ODS_SELECTED)
  151.     {
  152.         brushFill.CreateSolidBrush(::GetSysColor(COLOR_HIGHLIGHT));
  153.         pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
  154.     }
  155.     else
  156.         brushFill.CreateSolidBrush(pDC->GetBkColor());
  157.  
  158.     pDC->SetBkMode(TRANSPARENT);
  159.     pDC->FillRect(rc, &brushFill);
  160.  
  161.     CString strCurFont,strNextFont;
  162.     GetLBText(lpDIS->itemID,strCurFont);
  163.  
  164.     CFontObj* pFontObj;
  165.     m_mapFonts.Lookup(strCurFont,pFontObj);
  166.  
  167.     ASSERT(pFontObj != NULL);
  168.     DWORD dwData = pFontObj->GetFlags();
  169.     
  170.     // Render Bitmaps
  171.     if (dwData & TRUETYPE_FONT)
  172.         m_img.Draw(pDC,1, CPoint(rc.left,rc.top),ILD_TRANSPARENT);
  173.  
  174.     if (dwData & PRINTER_FONT)
  175.         m_img.Draw(pDC,0, CPoint(rc.left,rc.top),ILD_TRANSPARENT);
  176.     
  177.     int nX = rc.left; // Save for lines
  178.  
  179.     rc.left += GLYPH_WIDTH + 2; // Text Position
  180.     pDC->TextOut(rc.left,rc.top,strCurFont);
  181.  
  182.     // GetItemData - return font in use
  183.     if (GetItemData(lpDIS->itemID))
  184.     {
  185.         GetLBText(lpDIS->itemID+1,strNextFont);
  186.         CFontObj* pFontObjNext;
  187.         m_mapFonts.Lookup(strNextFont,pFontObjNext);
  188.  
  189.         if (!GetItemData(lpDIS->itemID+1))
  190.         {
  191.             // Draw font MRU separator ==============
  192.             //                         
  193.             TEXTMETRIC tm;
  194.             pDC->GetTextMetrics(&tm);
  195.  
  196.             pDC->MoveTo(nX,rc.top+tm.tmHeight);
  197.             pDC->LineTo(rc.right,rc.top+tm.tmHeight);
  198.  
  199.             pDC->MoveTo(nX,rc.top+tm.tmHeight+2);
  200.             pDC->LineTo(rc.right,rc.top+tm.tmHeight+2);
  201.     
  202.         }
  203.     }
  204.  
  205.     // Restore State of context
  206.     pDC->RestoreDC(nIndexDC);
  207. }
  208.  
  209.  
  210. // As it says...EnumerateFonts on the system
  211. BOOL CFontCombo::EnumerateFonts()
  212. {
  213.     HDC hDC;
  214.     
  215.     // Get screen fonts
  216.     hDC = ::GetWindowDC(NULL);
  217.     
  218.     LOGFONT lf;
  219.     
  220.     ZeroMemory(&lf,sizeof(lf));
  221.     lf.lfCharSet = ANSI_CHARSET;
  222.  
  223.     if (!EnumFontFamiliesEx(
  224.             hDC,    // handle to device context
  225.             &lf,    // pointer to logical font information
  226.             (FONTENUMPROC)EnumFamScreenCallBackEx,    // pointer to callback function
  227.             (LPARAM) this,    // application-supplied data
  228.             (DWORD) 0))
  229.         return FALSE;
  230.  
  231.     ::ReleaseDC(NULL,hDC);    
  232.  
  233.     // Now get printer fonts
  234.     CPrintDialog dlg(FALSE);
  235.     if (AfxGetApp()->GetPrinterDeviceDefaults(&dlg.m_pd))
  236.     {
  237.         // GetPrinterDC returns a HDC so attach it
  238.         hDC= dlg.CreatePrinterDC();
  239.         ASSERT(hDC != NULL);
  240.  
  241.         ZeroMemory(&lf,sizeof(lf));
  242.         lf.lfCharSet = ANSI_CHARSET;
  243.  
  244.         if (!EnumFontFamiliesEx(
  245.                 hDC,    // handle to device context
  246.                 &lf,    // pointer to logical font information
  247.                 (FONTENUMPROC)EnumFamPrinterCallBackEx,    // pointer to callback function
  248.                 (LPARAM) this,    // application-supplied data
  249.                 (DWORD) 0))
  250.             return FALSE;
  251.  
  252.     }
  253.     
  254.     return TRUE; // All's ok
  255. }
  256.  
  257.  
  258. ////////////////////////////////////////////////////////////////////////////////
  259. //
  260. // FUNCTION:    CFontCombo::OnDestroy
  261. //
  262. // DESCRIPTION:    Destroys font objects
  263. //
  264. // INPUTS:        
  265. //
  266. // RETURNS:     
  267. //
  268. // NOTES:       
  269. //
  270. // MODIFICATIONS:
  271. //
  272. // Name            Date      Version    Comments
  273. // N T ALMOND   25/09/98  1.0        Origin
  274. //
  275. ////////////////////////////////////////////////////////////////////////////////
  276. void CFontCombo::OnDestroy() 
  277. {
  278.     POSITION pos = m_mapFonts.GetStartPosition();
  279.     
  280.     while (pos)
  281.     {
  282.         CString strKey;
  283.         CFontObj* pFontObj;
  284.         m_mapFonts.GetNextAssoc(pos,strKey,pFontObj);
  285.         delete pFontObj;
  286.     }
  287.  
  288.     CComboBox::OnDestroy();
  289. }
  290.  
  291.  
  292. ////////////////////////////////////////////////////////////////////////////////
  293. //
  294. // FUNCTION:    CFontCombo::SetFontInUse
  295. //
  296. // DESCRIPTION:    Flags a font that is in use, similar to MS Words font MRU list
  297. //
  298. // INPUTS:        
  299. //
  300. // RETURNS:     
  301. //
  302. // NOTES:       
  303. //
  304. // MODIFICATIONS:
  305. //
  306. // Name            Date      Version    Comments
  307. // N T ALMOND   25/09/98  1.0        Origin
  308. //
  309. ////////////////////////////////////////////////////////////////////////////////
  310. void CFontCombo::SetFontInUse(const CString& strFont)
  311. {
  312.     CFontObj *pFontObj;
  313.     CString strFontDesc;
  314.     
  315.     // Find the desired font
  316.     if (m_mapFonts.Lookup(strFont,pFontObj))
  317.     {
  318.         // Check the font is not already in use
  319.         if (!pFontObj->GetFontInUse())
  320.         {
  321.             // Set the font as the top most and selected font
  322.             pFontObj->SetFontInUse(TRUE);
  323.             InsertString(0,strFont);
  324.             SetItemData(0,DWORD(1));
  325.  
  326.             // Only hold six MRU'ed fonts
  327.             // so drop the 7th.
  328.             if (GetItemData(6))
  329.             {
  330.                 GetLBText(6,strFontDesc);
  331.                 if (!strFontDesc.IsEmpty())
  332.                 {
  333.                     if (m_mapFonts.Lookup(strFontDesc,pFontObj))
  334.                     {
  335.                         pFontObj->SetFontInUse(FALSE);
  336.                         DeleteString(6);
  337.                     }
  338.                 }
  339.             }
  340.         }
  341.         else
  342.         {
  343.             // If font is aleady MRU'ed position it as the first font
  344.             int nSel = FindString(-1,strFont);
  345.     
  346.             if (nSel != CB_ERR)
  347.             {
  348.                 // Remove from original position
  349.                 DeleteString(nSel);
  350.                 // Restore to begining of list
  351.             
  352.                 InsertString(0,strFont);
  353.                 SetItemData(0,TRUE); // Mark as selected
  354.                 SetCurSel(0);    // Bring as current selection
  355.             }
  356.         }
  357.     }
  358. }
  359.  
  360. ////////////////////////////////////////////////////////////////////////////////
  361. //
  362. // FUNCTION:    CFontCombo::OnKillfocus
  363. //
  364. // DESCRIPTION:    Set up the current font
  365. //
  366. // INPUTS:        
  367. //
  368. // RETURNS:     
  369. //
  370. // NOTES:       
  371. //
  372. // MODIFICATIONS:
  373. //
  374. // Name            Date      Version    Comments
  375. // N T ALMOND   25/09/98  1.0        Origin
  376. //
  377. ////////////////////////////////////////////////////////////////////////////////
  378. void CFontCombo::OnKillfocus() 
  379. {
  380.     SetCurrentFont();
  381. }
  382.  
  383. ////////////////////////////////////////////////////////////////////////////////
  384. //
  385. // FUNCTION:    CFontCombo::OnSetfocus
  386. //
  387. // DESCRIPTION:    Save current font
  388. //
  389. // INPUTS:        
  390. //
  391. // RETURNS:     
  392. //
  393. // NOTES:       
  394. //
  395. // MODIFICATIONS:
  396. //
  397. // Name            Date      Version    Comments
  398. // N T ALMOND   25/09/98  1.0        Origin
  399. //
  400. ////////////////////////////////////////////////////////////////////////////////
  401. void CFontCombo::OnSetfocus() 
  402. {
  403.     // Save off original font
  404.     GetWindowText(m_strFontSave);    
  405. }
  406.  
  407. ////////////////////////////////////////////////////////////////////////////////
  408. //
  409. // FUNCTION:    CFontCombo::SetCurrentFont
  410. //
  411. // DESCRIPTION:    Set up the current font
  412. //
  413. // INPUTS:        
  414. //
  415. // RETURNS:     
  416. //
  417. // NOTES:       
  418. //
  419. // MODIFICATIONS:
  420. //
  421. // Name            Date      Version    Comments
  422. // N T ALMOND   25/09/98  1.0        Origin
  423. //
  424. ////////////////////////////////////////////////////////////////////////////////
  425. void CFontCombo::SetCurrentFont()
  426. {
  427.     CString strSelFont;
  428.  
  429.     // Change font in edit box is a known font
  430.     // otherwise reject and restore orginal
  431.     int nSel = GetCurSel();
  432.  
  433.     if (nSel == CB_ERR)
  434.     {
  435.         GetWindowText(strSelFont);
  436.         nSel = FindStringExact(-1,strSelFont);
  437.         
  438.         if (nSel == CB_ERR)
  439.         {
  440.             SetWindowText(m_strFontSave);
  441.         }
  442.     }
  443. }
  444.  
  445. ////////////////////////////////////////////////////////////////////////////////
  446. //
  447. // FUNCTION:    CFontCombo::OnCloseUp
  448. //
  449. // DESCRIPTION:    Hide tip window and set font name
  450. //
  451. // INPUTS:        
  452. //
  453. // RETURNS:     
  454. //
  455. // NOTES:       
  456. //
  457. // MODIFICATIONS:
  458. //
  459. // Name            Date      Version    Comments
  460. // N T ALMOND   25/09/98  1.0        Origin
  461. //
  462. ////////////////////////////////////////////////////////////////////////////////
  463. void CFontCombo::OnCloseUp()
  464. {
  465.     int nSel;    
  466.  
  467.     CString strFont;
  468.     // Set Face Name
  469.     SetCurrentFont();
  470.     nSel = GetCurSel();
  471.     if (nSel != CB_ERR)
  472.         GetLBText(nSel,strFont);
  473.  
  474.     SetFontInUse(strFont);
  475.     m_wndTip.ShowWindow(SW_HIDE);
  476. }
  477.  
  478. ////////////////////////////////////////////////////////////////////////////////
  479. //
  480. // FUNCTION:    CFontCombo::Initialize
  481. //
  482. // DESCRIPTION:    Initials combo box
  483. //
  484. // INPUTS:        
  485. //
  486. // RETURNS:     
  487. //
  488. // NOTES:       
  489. //
  490. // MODIFICATIONS:
  491. //
  492. // Name            Date      Version    Comments
  493. // N T ALMOND   25/09/98  1.0        Origin
  494. //
  495. ////////////////////////////////////////////////////////////////////////////////
  496. void CFontCombo::Initialize()
  497. {
  498.     // Yep tip window is created here
  499.     m_wndTip.Create(this);
  500.  
  501.     // Set default font name
  502.     CString strDefault = "";
  503.     
  504.     CFontObj* pFontObj;
  505.     CString strKey,strComp;
  506.     EnumerateFonts();
  507.  
  508.     POSITION pos = m_mapFonts.GetStartPosition();
  509.     
  510.     while (pos)
  511.     {
  512.         m_mapFonts.GetNextAssoc(pos,strKey,pFontObj);
  513.  
  514.         int nMax = GetCount();
  515.         BOOL bInsert = FALSE;
  516.         for (int nIdx=0;nIdx < nMax;nIdx++)
  517.         {            
  518.             GetLBText(nIdx,strComp);
  519.             
  520.             if (strComp.Collate(strKey) == 1)
  521.             {
  522.                 bInsert = TRUE;
  523.                 InsertString(nIdx,strKey);
  524.                 break;
  525.             }
  526.         }        
  527.  
  528.         if (!bInsert)
  529.             AddString(strKey);
  530.     }
  531.  
  532.     // We set the timer because its the only way we know when a selection
  533.     // has changed - use for tip window
  534.     SetTimer(1, 500, NULL);
  535. }
  536.  
  537. ////////////////////////////////////////////////////////////////////////////////
  538. //
  539. // FUNCTION:    CFontCombo::AddFont
  540. //
  541. // DESCRIPTION:    Adds a font to the internal array
  542. //
  543. // INPUTS:        
  544. //
  545. // RETURNS:     
  546. //
  547. // NOTES:       
  548. //
  549. // MODIFICATIONS:
  550. //
  551. // Name            Date      Version    Comments
  552. // N T ALMOND   25/09/98  1.0        Origin
  553. //
  554. ////////////////////////////////////////////////////////////////////////////////
  555. void CFontCombo::AddFont(CString strName, DWORD dwFlags)
  556. {
  557.     CFontObj* pFontObj;    
  558.  
  559.     // Check fonts not aleady in the array
  560.     if (!m_mapFonts.Lookup(strName,pFontObj))
  561.         m_mapFonts.SetAt(strName,new CFontObj(dwFlags));
  562. }
  563.  
  564. ////////////////////////////////////////////////////////////////////////////////
  565. //
  566. // FUNCTION:    CFontCombo::OnTimer
  567. //
  568. // DESCRIPTION:    Positions tip window against selected font
  569. //
  570. // INPUTS:        
  571. //
  572. // RETURNS:     
  573. //
  574. // NOTES:       
  575. //
  576. // MODIFICATIONS:
  577. //
  578. // Name            Date      Version    Comments
  579. // N T ALMOND   25/09/98  1.0        Origin
  580. //
  581. ////////////////////////////////////////////////////////////////////////////////
  582. void CFontCombo::OnTimer(UINT nIDEvent) 
  583. {
  584.     
  585.     // Is combo open
  586.     if (GetDroppedState( ))
  587.     {
  588.         int nSel = GetCurSel();
  589.         
  590.         // Selected
  591.         if (nSel != -1)
  592.         {
  593.             CString str;
  594.             GetLBText(nSel,str);
  595.             CRect rc;
  596.             GetDroppedControlRect(rc);
  597.  
  598.             int nHeight = GetItemHeight(0) * ((nSel - GetTopIndex()) + 1);
  599.             
  600.             CPoint pt(rc.right + 5,rc.top + nHeight);
  601.  
  602.             // Show tip in correct position
  603.             m_wndTip.ShowTips(pt,str);
  604.         }
  605.     }
  606.     
  607.     
  608.     CComboBox::OnTimer(nIDEvent);
  609. }
  610.  
  611. BOOL CALLBACK AFX_EXPORT CFontCombo::EnumFamScreenCallBackEx(ENUMLOGFONTEX* pelf, 
  612.     NEWTEXTMETRICEX* /*lpntm*/, int FontType, LPVOID pThis)
  613.  
  614. {
  615.     // don't put in non-printer raster fonts
  616.     if (FontType & RASTER_FONTTYPE)
  617.         return 1;
  618.     
  619.     DWORD dwData;
  620.     
  621.     dwData = (FontType & TRUETYPE_FONTTYPE) ? TRUETYPE_FONT : 0;
  622.     ((CFontCombo*)pThis)->AddFont(pelf->elfLogFont.lfFaceName, dwData);
  623.     
  624.     return 1; // Call me back
  625. }
  626.  
  627. BOOL CALLBACK AFX_EXPORT CFontCombo::EnumFamPrinterCallBackEx(ENUMLOGFONTEX* pelf, 
  628.     NEWTEXTMETRICEX* /* lpntm */, int FontType, LPVOID pThis)
  629. {
  630.     
  631.     if (!(FontType & DEVICE_FONTTYPE))
  632.         return 1;
  633.  
  634.     if ((FontType & TRUETYPE_FONTTYPE))
  635.         return 1;
  636.  
  637.     DWORD dwData = PRINTER_FONT;
  638.     
  639.     ((CFontCombo*)pThis)->AddFont(pelf->elfLogFont.lfFaceName, dwData);
  640.     
  641.     return 1; // Call me back
  642. }
  643.  
  644.