⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fontcombo.h

📁 remote debug and compile tools
💻 H
字号:
#if !defined(AFX_FONTCOMBO_H__20030528_EF53_EC6F_2CB8_0080AD509054__INCLUDED_)
#define AFX_FONTCOMBO_H__20030528_EF53_EC6F_2CB8_0080AD509054__INCLUDED_

/////////////////////////////////////////////////////////////////////////////
// FontComboPicker - Simple Font picker controls
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2003 Bjarke Viksoe.
//
// Add the following macro to the parent's message map:
//   REFLECT_NOTIFICATIONS()
//
// This code may be used in compiled form in any way you desire. This
// source file may be redistributed by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. 
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//

#ifndef __cplusplus
  #error WTL requires C++ compilation (use a .cpp suffix)
#endif

#ifndef __ATLCTRLS_H__
  #error FontCombo.h requires atlctrls.h to be included first
#endif


/////////////////////////////////////////////////////////////////////////////
// 

// Extended Combo styles
#define FPS_EX_TYPEICON   0x00000001
#define FPS_EX_FIXEDBOLD  0x00000002
#define FPS_EX_SHOWFACE   0x00000004

// TrueType icon
__declspec(selectany) BYTE tt_icon[] = 
{
   0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01,
   0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00,
   0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00,
   0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0x00, 0x80, 0x80,
   0x80, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00,
   0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
   0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
   0x88, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x80, 0x88, 0x08, 0x80, 0x00, 0x00, 0x00, 0x08, 0x88,
   0x88, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
   0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xFF, 0x3F,
   0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xF3, 0x3F, 0x00, 0x00, 0xF3, 0x37,
   0x00, 0x00, 0xF3, 0x37, 0x00, 0x00, 0xF1, 0x27, 0x00, 0x00, 0xB0, 0x07, 0x00, 0x00, 0xB3, 0x7F,
   0x00, 0x00, 0x92, 0x7F, 0x00, 0x00, 0x80, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00
};

// OpenType icon
__declspec(selectany) BYTE ot_icon[] = 
{
   0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01,
   0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00,
   0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00,
   0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0x00, 0x80, 0x80,
   0x80, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00,
   0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
   0x07, 0x77, 0x67, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x76, 0x70, 0x00, 0x00, 0x00, 0x70,
   0x00, 0x00, 0x08, 0x67, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x07, 0x66, 0x00, 0x00, 0x00, 0x70,
   0x07, 0x00, 0x00, 0x66, 0x70, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x66, 0x70, 0x00, 0x00, 0x08,
   0x00, 0x00, 0x00, 0x86, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x70, 0x00, 0x00, 0x00,
   0x70, 0x00, 0x00, 0x86, 0x70, 0x00, 0x00, 0x00, 0x07, 0x08, 0x77, 0x66, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x07, 0x86, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
   0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0xE0, 0x3F,
   0x00, 0x00, 0xC7, 0x1F, 0x00, 0x00, 0xC7, 0x8F, 0x00, 0x00, 0xC7, 0x8F, 0x00, 0x00, 0xC3, 0xC7,
   0x00, 0x00, 0xE3, 0xC7, 0x00, 0x00, 0xE3, 0xC7, 0x00, 0x00, 0xF3, 0xC7, 0x00, 0x00, 0xF1, 0xC7,
   0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 
};


template< class T, class TBase = CComboBox, class TWinTraits = CControlWinTraits >
class ATL_NO_VTABLE CFontPickerImpl : 
   public CWindowImpl< T, TBase, TWinTraits >,
   public COwnerDraw< T >
{
public:
   DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())

   enum 
   {
      s_cxIndent = 3,
      TMPF_OPENTYPE = 0x80,
   };

   CSimpleArray<LOGFONT> m_aFonts;
   CSimpleArray<TEXTMETRIC> m_aMetrics;
   HICON m_hTtIcon;
   HICON m_hOtIcon;
   CFont m_fntBold;
   DWORD m_dwExtStyle;
   // EnumFontFamilies data
   DWORD m_dwFilter;
   TEXTMETRIC m_tm;

   // Operations

   BOOL SubclassWindow(HWND hWnd)
   {
      ATLASSERT(m_hWnd==NULL);
      ATLASSERT(::IsWindow(hWnd));
      BOOL bRet = CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
      if( bRet ) _Init();
      return bRet;
   }
   DWORD SetExtendedFontStyle(DWORD dwStyle)
   {
      ATLASSERT(::IsWindow(m_hWnd));
      ATLASSERT(GetCount()==0); // Before adding items, please!
      DWORD dwOldStyle = m_dwExtStyle;
      m_dwExtStyle = dwStyle;
      Invalidate();
      return dwOldStyle;
   }

   int Dir(DWORD dwType = -1, LPCTSTR pstrFamily = NULL)
   {
      m_aFonts.RemoveAll();
      m_aMetrics.RemoveAll();
      CClientDC dc = m_hWnd;      
      dc.GetTextMetrics(&m_tm);
      m_dwFilter = dwType;
      ::EnumFontFamilies(dc, pstrFamily, _EnumFamCB, (LPARAM) this);
      for( int i = 0; i < m_aFonts.GetSize(); i++ ) {
         int iItem = AddString(m_aFonts[i].lfFaceName);
         // NOTE: Because of possible sorting of the list we store
         //       the index in the item-data.
         SetItemData(iItem, (LPARAM) i);
      }
      return GetCount() - 1;
   }
   BOOL GetLogFont(int iIndex, LOGFONT& lf) const
   {
      if( iIndex < 0 || iIndex >= GetCount() ) return FALSE;
      lf = m_aFonts[GetItemData(iIndex)];
      return TRUE;
   }
   BOOL GetTextMetrics(int iIndex, TEXTMETRIC& tm) const
   {
      if( iIndex < 0 || iIndex >= GetCount() ) return FALSE;
      tm = m_aMetrics[GetItemData(iIndex)];
      return TRUE;
   }

   // Callbacks

   static BOOL CALLBACK _EnumFamCB(CONST LOGFONT* lplf, CONST TEXTMETRIC* lptm, DWORD FontType, LPARAM pThis) 
   {
      T* pT = (T*) pThis;
      CClientDC dc = pT->m_hWnd;
      if( (FontType & pT->m_dwFilter) == 0 ) return TRUE;
      for( int i = 0; i < pT->m_aFonts.GetSize(); i++ ) {
         if( ::lstrcmp(lplf->lfFaceName, pT->m_aFonts[i].lfFaceName) == 0 ) return TRUE;
      }
      LOGFONT lf = *lplf;
      lf.lfWidth = 0;
      lf.lfHeight = pT->m_tm.tmHeight;
      pT->m_aFonts.Add(lf);
      TEXTMETRIC tm = *lptm;
      if( tm.tmPitchAndFamily & TMPF_TRUETYPE ) {
         // HACK: A little hack to determine if this is an OpenType...
         const NEWTEXTMETRIC* lpntm = (const NEWTEXTMETRIC*) lptm;
         if( lpntm->ntmFlags & 0x60000 ) tm.tmPitchAndFamily |= TMPF_OPENTYPE;
      }
      pT->m_aMetrics.Add(tm);
      return TRUE;
   }

   // Implementation

   void _Init()
   {
      ATLASSERT(::IsWindow(m_hWnd));
      // Need to set these in resource editor
      // If it's a ListBox, use LBS_OWNERDRAWVARIABLE.
      ATLASSERT(GetStyle() & CBS_OWNERDRAWVARIABLE);
      ATLASSERT(GetStyle() & CBS_HASSTRINGS);

      m_dwExtStyle = 0;

      CFontHandle font = GetFont();
      LOGFONT lf;
      font.GetLogFont(&lf);
      lf.lfWeight += FW_BOLD;
      if( !m_fntBold.IsNull() ) m_fntBold.DeleteObject();
      m_fntBold.CreateFontIndirect(&lf);

      const DWORD ICO_OFFSET = 6 + 16; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY)
      m_hTtIcon = ::CreateIconFromResource(tt_icon + ICO_OFFSET, sizeof(tt_icon) - ICO_OFFSET, TRUE, 0x00030000);
      ATLASSERT(m_hTtIcon!=NULL);
      m_hOtIcon = ::CreateIconFromResource(ot_icon + ICO_OFFSET, sizeof(ot_icon) - ICO_OFFSET, TRUE, 0x00030000);
      ATLASSERT(m_hOtIcon!=NULL);
   }

   // Message map and handlers

   BEGIN_MSG_MAP(CFontPickerImpl)
      MESSAGE_HANDLER(WM_CREATE, OnCreate)
      MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
      CHAIN_MSG_MAP_ALT( COwnerDraw< T >, 1 )
   END_MSG_MAP()

   LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
   {
      LRESULT lRes = DefWindowProc();
      _Init();
      return lRes;
   }
   LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
   {
      ::DestroyIcon(m_hTtIcon);
      ::DestroyIcon(m_hOtIcon);
      bHandled = FALSE;
      return 0;
   }

   // COwnerDraw

   void MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
   {
      CClientDC dc(m_hWnd);
      TEXTMETRIC tm = m_aMetrics[GetItemData(lpMIS->itemID)]; 
      if( m_dwExtStyle & FPS_EX_SHOWFACE ) {
         // Already initialized 'tm'...
      }
      else if( m_dwExtStyle & FPS_EX_FIXEDBOLD && ((tm.tmPitchAndFamily & 3) == FIXED_PITCH) ) {
         HFONT hOldFont = dc.SelectFont(m_fntBold);
         dc.GetTextMetrics(&tm);
         dc.SelectFont(hOldFont);
      }
      else {
         dc.GetTextMetrics(&tm);
      }
      lpMIS->itemHeight = tm.tmHeight + 1;
   }
   void DrawItem(LPDRAWITEMSTRUCT lpDIS)
   {
      int iIndex = lpDIS->itemID;
      if( iIndex == -1 ) return;
      LOGFONT& lf = m_aFonts[GetItemData(iIndex)];
      TEXTMETRIC& tm = m_aMetrics[GetItemData(iIndex)];

      CDCHandle dc = lpDIS->hDC;
      RECT rc = lpDIS->rcItem;
      bool bSelected = lpDIS->itemState & ODS_SELECTED;

      // Never paint selected colors for edit part
      if( lpDIS->itemState & ODS_COMBOBOXEDIT ) bSelected = false;

      // Fill background and Font item
      CBrushHandle brBack = ::GetSysColorBrush(bSelected ? COLOR_HIGHLIGHT : COLOR_WINDOW);
      dc.FillRect(&rc, brBack);

      ::InflateRect(&rc, -s_cxIndent, 0);

      if( m_dwExtStyle & FPS_EX_TYPEICON ) 
      {
         if( tm.tmPitchAndFamily & TMPF_OPENTYPE ) {
            dc.DrawIconEx(rc.left, rc.top + 1, m_hOtIcon, 16, 16);
         }
         else if( tm.tmPitchAndFamily & TMPF_TRUETYPE ) {
            dc.DrawIconEx(rc.left, rc.top + 1, m_hTtIcon, 16, 16);
         }
         rc.left += 18;
      }

      dc.SetBkMode(TRANSPARENT);
      dc.SetTextColor(::GetSysColor(bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));
      CFont font;
      HFONT hOldFont = NULL;
      if( m_dwExtStyle & FPS_EX_SHOWFACE ) 
      {
         font.CreateFontIndirect(&lf);
         hOldFont = dc.SelectFont(font);
      }
      else if( (m_dwExtStyle & FPS_EX_FIXEDBOLD) != 0 && 
               (tm.tmPitchAndFamily & TMPF_FIXED_PITCH ) == 0 ) 
      {
         hOldFont = dc.SelectFont(m_fntBold);
      }
      dc.DrawText(lf.lfFaceName, -1, &rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_NOPREFIX | DT_EDITCONTROL | DT_END_ELLIPSIS);
      if( hOldFont ) dc.SelectFont(hOldFont);
   }
};

class CFontPickerComboCtrl : public CFontPickerImpl<CFontPickerComboCtrl, CComboBox, CWinTraitsOR<CBS_OWNERDRAWVARIABLE|CBS_DROPDOWNLIST|CBS_HASSTRINGS> >
{
public:
   DECLARE_WND_SUPERCLASS(_T("WTL_FontPickerComboBox"), GetWndClassName())  
};

class CFontPickerListCtrl : public CFontPickerImpl<CFontPickerListCtrl, CListBox, CWinTraitsOR<LBS_OWNERDRAWVARIABLE|LBS_HASSTRINGS> >
{
public:
   DECLARE_WND_SUPERCLASS(_T("WTL_FontPickerListBox"), GetWndClassName())  
};


#endif // !defined(AFX_FONTCOMBO_H__20030528_EF53_EC6F_2CB8_0080AD509054__INCLUDED_)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -