📄 fontcombo.cpp
字号:
// FontBox.cpp : implementation file
//
#include "Stdafx.h"
#include "resource.h"
#include "FontCombo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define GLYPH_WIDTH 15
CFontCombo::CFontCombo()
{
m_img.Create(IDB_GLYPHS,15,1,RGB(255,0,255));
}
CFontCombo::~CFontCombo()
{
}
BEGIN_MESSAGE_MAP(CFontCombo, CComboBox)
//{{AFX_MSG_MAP(CFontCombo)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillfocus)
ON_CONTROL_REFLECT(CBN_SETFOCUS, OnSetfocus)
ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseUp)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CFontCombo::DeleteItem(LPDELETEITEMSTRUCT)
{
}
void CFontCombo::MeasureItem(LPMEASUREITEMSTRUCT)
{
}
int CFontCombo::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CComboBox::OnCreate(lpCreateStruct) == -1)
return -1;
Initialize();
return 0;
}
void CFontCombo::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
ASSERT(lpDIS->CtlType == ODT_COMBOBOX);
CDC *pDC = CDC::FromHandle(lpDIS->hDC);
ASSERT(pDC);
CRect rc(lpDIS->rcItem);
if (lpDIS->itemState & ODS_FOCUS)
pDC->DrawFocusRect(rc);
int nIndexDC = pDC->SaveDC();
CBrush brushFill;
if (lpDIS->itemState & ODS_SELECTED)
{
brushFill.CreateSolidBrush(::GetSysColor(COLOR_HIGHLIGHT));
pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
}
else
brushFill.CreateSolidBrush(pDC->GetBkColor());
pDC->SetBkMode(TRANSPARENT);
pDC->FillRect(rc, &brushFill);
CString strCurFont,strNextFont;
GetLBText(lpDIS->itemID,strCurFont);
CFontObj* pFontObj;
m_mapFonts.Lookup(strCurFont,pFontObj);
ASSERT(pFontObj != NULL);
DWORD dwData = pFontObj->GetFlags();
if (dwData & TRUETYPE_FONT)
m_img.Draw(pDC,1, CPoint(rc.left,rc.top),ILD_TRANSPARENT);
if (dwData & PRINTER_FONT)
m_img.Draw(pDC,0, CPoint(rc.left,rc.top),ILD_TRANSPARENT);
int nX = rc.left;
rc.left += GLYPH_WIDTH + 2;
pDC->TextOut(rc.left,rc.top,strCurFont);
if (GetItemData(lpDIS->itemID))
{
GetLBText(lpDIS->itemID+1,strNextFont);
CFontObj* pFontObjNext;
m_mapFonts.Lookup(strNextFont,pFontObjNext);
if (!GetItemData(lpDIS->itemID+1))
{
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm);
pDC->MoveTo(nX,rc.top+tm.tmHeight);
pDC->LineTo(rc.right,rc.top+tm.tmHeight);
pDC->MoveTo(nX,rc.top+tm.tmHeight+2);
pDC->LineTo(rc.right,rc.top+tm.tmHeight+2);
}
}
pDC->RestoreDC(nIndexDC);
}
BOOL CFontCombo::EnumerateFonts()
{
HDC hDC;
hDC = ::GetWindowDC(NULL);
LOGFONT lf;
ZeroMemory(&lf,sizeof(lf));
lf.lfCharSet = ANSI_CHARSET;
if (!EnumFontFamiliesEx(
hDC,
&lf,
(FONTENUMPROC)EnumFamScreenCallBackEx,
(LPARAM) this,
(DWORD) 0))
return FALSE;
::ReleaseDC(NULL,hDC);
CPrintDialog dlg(FALSE);
if (AfxGetApp()->GetPrinterDeviceDefaults(&dlg.m_pd))
{
hDC= dlg.CreatePrinterDC();
ASSERT(hDC != NULL);
ZeroMemory(&lf,sizeof(lf));
lf.lfCharSet = ANSI_CHARSET;
if (!EnumFontFamiliesEx(
hDC,
&lf,
(FONTENUMPROC)EnumFamPrinterCallBackEx,
(LPARAM) this,
(DWORD) 0))
return FALSE;
}
return TRUE;
}
void CFontCombo::OnDestroy()
{
POSITION pos = m_mapFonts.GetStartPosition();
while (pos)
{
CString strKey;
CFontObj* pFontObj;
m_mapFonts.GetNextAssoc(pos,strKey,pFontObj);
delete pFontObj;
}
CComboBox::OnDestroy();
}
void CFontCombo::SetFontInUse(const CString& strFont)
{
CFontObj *pFontObj;
CString strFontDesc;
if (m_mapFonts.Lookup(strFont,pFontObj))
{
if (!pFontObj->GetFontInUse())
{
pFontObj->SetFontInUse(TRUE);
InsertString(0,strFont);
SetItemData(0,DWORD(1));
if (GetItemData(6))
{
GetLBText(6,strFontDesc);
if (!strFontDesc.IsEmpty())
{
if (m_mapFonts.Lookup(strFontDesc,pFontObj))
{
pFontObj->SetFontInUse(FALSE);
DeleteString(6);
}
}
}
}
else
{
int nSel = FindString(-1,strFont);
if (nSel != CB_ERR)
{
DeleteString(nSel);
InsertString(0,strFont);
SetItemData(0,TRUE);
SetCurSel(0);
}
}
}
}
void CFontCombo::OnKillfocus()
{
SetCurrentFont();
}
void CFontCombo::OnSetfocus()
{
GetWindowText(m_strFontSave);
}
void CFontCombo::SetCurrentFont()
{
CString strSelFont;
int nSel = GetCurSel();
if (nSel == CB_ERR)
{
GetWindowText(strSelFont);
nSel = FindStringExact(-1,strSelFont);
if (nSel == CB_ERR)
{
SetWindowText(m_strFontSave);
}
}
}
void CFontCombo::OnCloseUp()
{
int nSel;
CString strFont;
SetCurrentFont();
nSel = GetCurSel();
if (nSel != CB_ERR)
GetLBText(nSel,strFont);
SetFontInUse(strFont);
m_wndTip.ShowWindow(SW_HIDE);
}
void CFontCombo::Initialize()
{
m_wndTip.Create(this);
CString strDefault = "";
CFontObj* pFontObj;
CString strKey,strComp;
EnumerateFonts();
POSITION pos = m_mapFonts.GetStartPosition();
while (pos)
{
m_mapFonts.GetNextAssoc(pos,strKey,pFontObj);
int nMax = GetCount();
BOOL bInsert = FALSE;
for (int nIdx=0;nIdx < nMax;nIdx++)
{
GetLBText(nIdx,strComp);
if (strComp.Collate(strKey) == 1)
{
bInsert = TRUE;
InsertString(nIdx,strKey);
break;
}
}
if (!bInsert)
AddString(strKey);
}
SetTimer(1, 500, NULL);
}
void CFontCombo::AddFont(CString strName, DWORD dwFlags)
{
CFontObj* pFontObj;
if (!m_mapFonts.Lookup(strName,pFontObj))
m_mapFonts.SetAt(strName,new CFontObj(dwFlags));
}
void CFontCombo::OnTimer(UINT nIDEvent)
{
if (GetDroppedState( ))
{
int nSel = GetCurSel();
if (nSel != -1)
{
CString str;
GetLBText(nSel,str);
CRect rc;
GetDroppedControlRect(rc);
int nHeight = GetItemHeight(0) * ((nSel - GetTopIndex()) + 1);
CPoint pt(rc.right + 5,rc.top + nHeight);
m_wndTip.ShowTips(pt,str);
}
}
CComboBox::OnTimer(nIDEvent);
}
BOOL CALLBACK AFX_EXPORT CFontCombo::EnumFamScreenCallBackEx(ENUMLOGFONTEX* pelf,
NEWTEXTMETRICEX* /*lpntm*/, int FontType, LPVOID pThis)
{
if (FontType & RASTER_FONTTYPE)
return 1;
DWORD dwData;
dwData = (FontType & TRUETYPE_FONTTYPE) ? TRUETYPE_FONT : 0;
((CFontCombo*)pThis)->AddFont(pelf->elfLogFont.lfFaceName, dwData);
return 1;
}
BOOL CALLBACK AFX_EXPORT CFontCombo::EnumFamPrinterCallBackEx(ENUMLOGFONTEX* pelf,
NEWTEXTMETRICEX* /* lpntm */, int FontType, LPVOID pThis)
{
if (!(FontType & DEVICE_FONTTYPE))
return 1;
if ((FontType & TRUETYPE_FONTTYPE))
return 1;
DWORD dwData = PRINTER_FONT;
((CFontCombo*)pThis)->AddFont(pelf->elfLogFont.lfFaceName, dwData);
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -