//////////////////////////////////////////////////////////////////////////////// // BlueMatrix Excel Addin // Copyright (c) 2005, // // File : FontCombobox.cpp // // Contents : Combo box for a choice of a font // // Implementation details: // // Author : BlueMatrix // // TODO : // //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "FontCombobox.h" /* static */ FONTVECTOR CFontCombobox::s_aFonts; /* static */ HBITMAP CFontCombobox::s_hBitmap; /* static */ void CFontCombobox::MeasureItem(LPMEASUREITEMSTRUCT pmis) { if (pmis->itemHeight < CY_FONT) pmis->itemHeight = CY_FONT + 2; } /* static */ void CFontCombobox::DrawItem(LPDRAWITEMSTRUCT pdis) { if (pdis->itemID == -1) return; ::SaveDC(pdis->hDC); // The colors depend on whether the item is selected. ::SetTextColor( pdis->hDC, ::GetSysColor( pdis->itemState & ODS_SELECTED ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT)); ::SetBkColor( pdis->hDC, ::GetSysColor( pdis->itemState & ODS_SELECTED ? COLOR_HIGHLIGHT : COLOR_WINDOW)); int lpy; LOGFONT lf = {0}; HFONT hFont = NULL; if (_tcscmp( (LPCTSTR)s_aFonts[pdis->itemID].elfScript, _T("Symbol"))) { // Get the vertical DPI of the device lpy = ::GetDeviceCaps(pdis->hDC, LOGPIXELSY); // Create regular (non-italic) font. lf.lfHeight = -MulDiv(8, lpy, 72); lf.lfItalic = FALSE; lf.lfCharSet = DEFAULT_CHARSET; _tcscpy(lf.lfFaceName, s_aFonts[pdis->itemID].elfLogFont.lfFaceName); hFont = ::CreateFontIndirect(&lf); ::SelectObject(pdis->hDC, hFont); } RECT rcTxt; ::CopyRect(&rcTxt, &pdis->rcItem); rcTxt.left += CX_TTBITMAP; ::ExtTextOut( pdis->hDC, pdis->rcItem.left + CX_TTBITMAP, pdis->rcItem.top, ETO_CLIPPED | ETO_OPAQUE, &rcTxt, // &pdis->rcItem, s_aFonts[pdis->itemID].elfLogFont.lfFaceName, _tcslen(s_aFonts[pdis->itemID].elfLogFont.lfFaceName), NULL); // Display the bitmap associated with the item. if (s_hBitmap) { HDC hdcMem = ::CreateCompatibleDC(pdis->hDC); ::SaveDC(hdcMem); ::SelectObject(hdcMem, s_hBitmap); ::BitBlt( pdis->hDC, pdis->rcItem.left, pdis->rcItem.top, pdis->rcItem.right - pdis->rcItem.left, pdis->rcItem.bottom - pdis->rcItem.top, hdcMem, 0, 0, SRCCOPY); ::RestoreDC(hdcMem, -1); ::DeleteObject(hdcMem); } ::RestoreDC(pdis->hDC, -1); if (hFont) ::DeleteObject(hFont); } /* static */ int CALLBACK CFontCombobox::EnumFontFamiliesExProc( ENUMLOGFONTEX* lpelfe, NEWTEXTMETRICEX* lpntme, int FontType, LPARAM lParam) { if ((FontType & TRUETYPE_FONTTYPE) && ( //(!_tcsicmp(_T("Western"), (LPCTSTR)lpelfe->elfScript)) || (!_tcsicmp(_T("Кириллический"), (LPCTSTR)lpelfe->elfScript)) || // (!_tcsicmp(_T("Symbol"), (LPCTSTR)lpelfe->elfScript)) (!_tcsicmp(_T("Символьный"), (LPCTSTR)lpelfe->elfScript)) ) && (lpelfe->elfLogFont.lfFaceName[0] != TCHAR('@')) ) { // ATLTRACE( // _T("%s - %s\n"), // (LPCTSTR)lpelfe->elfFullName, // (LPCTSTR)lpelfe->elfLogFont.lfFaceName); s_aFonts.push_back(*lpelfe); } return 1; } // Return whether first element is greater that the second /*static*/ bool CFontCombobox::UDgreater( ENUMLOGFONTEX elf, ENUMLOGFONTEX elf2) { return _tcscmp( elf.elfLogFont.lfFaceName, elf2.elfLogFont.lfFaceName) < 0 ? true : false; } /*static*/ void CFontCombobox::InitFont() { // Add an items if (::IsWindow(m_hWnd)) { ::SendMessage(m_hWnd, CB_RESETCONTENT, 0, 0); /* if (s_aFonts.empty()) // ? { HDC hDC = ::GetDC(NULL); LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0}; ::EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROC)EnumFontFamiliesExProc, 0, 0); ::ReleaseDC(NULL, hDC); // A user-defined (UD) binary predicate are used sort(s_aFonts.begin(), s_aFonts.end(), UDgreater); } */ EnumAllFonts(); FONTVECTOR::const_iterator it; for (it = s_aFonts.begin(); it != s_aFonts.end(); it++) ::SendMessage(m_hWnd, CB_ADDSTRING, 0, (LPARAM)_T("")); } } /*static*/ void CFontCombobox::EnumAllFonts() { if (!s_aFonts.empty()) return; CClientDC dc(NULL); LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0}; ::EnumFontFamiliesEx( dc.m_hDC, &lf, (FONTENUMPROC)EnumFontFamiliesExProc, 0, 0); // A user-defined (UD) binary predicate are used // sort(s_aFonts.begin(), s_aFonts.end(), UDgreater); }