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

📄 fontcombo.cpp

📁 Visual C++图形用户界面开发指南 李博轩等编著 配套源码光盘
💻 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 + -