📄 ppgfont.cpp
字号:
#define DX_BITMAP 20
#define DY_BITMAP 12
/////////////////////////////////////////////////////////////////////////////
// CFontComboBox
CFontComboBox::CFontComboBox() : CComboBox()
{
m_bmpTrueType.LoadBitmap(AFX_IDB_TRUETYPE);
_AfxInitMaskFromBitmap(&m_bmpTrueType, &m_bmpMask);
}
CFontComboBox::~CFontComboBox()
{
}
int CFontComboBox::AddFont(LOGFONT *pLF, DWORD FontType)
{
int nEntry;
FONTITEM_PPG* pFontItem = NULL;
// Font already in the combobox
if (FindString(-1, (LPCTSTR) pLF->lfFaceName) != CB_ERR)
return CB_ERR;
// allocate some memory for the FONTITEM_PPG structure
TRY
{
pFontItem = new FONTITEM_PPG;
}
CATCH( CMemoryException, e )
{
return CB_ERR;
}
END_CATCH
ASSERT( pFontItem );
pFontItem->lf = *pLF;
pFontItem->dwFontType = FontType;
nEntry = AddString( (LPCTSTR) pFontItem->lf.lfFaceName );
if (nEntry == CB_ERR)
delete pFontItem;
else
SetItemData( nEntry, (DWORD) pFontItem );
return nEntry;
}
FONTITEM_PPG* CFontComboBox::GetFontItem(int sel)
{
if (sel == -1)
sel = GetCurSel();
if (sel == -1)
{
CString str;
GetWindowText( str );
sel = FindString( -1, str );
if (sel == CB_ERR)
sel = 0;
}
ASSERT( GetItemData(sel) );
return (FONTITEM_PPG*) GetItemData(sel);
}
LPLOGFONT CFontComboBox::GetLogFont(int sel)
{
return &GetFontItem(sel)->lf;
}
DWORD CFontComboBox::GetFontType(int sel)
{
return GetFontItem(sel)->dwFontType;
}
CString CFontComboBox::GetCurrentName()
{
CString str;
GetWindowText(str);
return str;
}
void CFontComboBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
ASSERT( lpDIS->CtlType == ODT_COMBOBOX );
// make sure this is a *real* item
if (lpDIS->itemID == -1)
return;
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
FONTITEM_PPG* pFI = (FONTITEM_PPG*)lpDIS->itemData; // pointer to a FONTITEM storied in item data
LOGFONT* pLF = &pFI->lf;
COLORREF crBk, crText;
TEXTMETRIC tm;
int x, y;
// Calculate the colors to use
crBk = pDC->SetBkColor(
GetSysColor(lpDIS->itemState & ODS_SELECTED ? COLOR_HIGHLIGHT : COLOR_WINDOW) );
crText = pDC->SetTextColor(
GetSysColor(lpDIS->itemState & ODS_SELECTED ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT) );
// Calculate the position of the text
pDC->GetTextMetrics( &tm );
x = LOWORD(GetDialogBaseUnits()) / 4;
y = (lpDIS->rcItem.bottom + lpDIS->rcItem.top - tm.tmHeight) / 2;
// Draw the text
pDC->ExtTextOut(lpDIS->rcItem.left + DX_BITMAP + 2 * x, y, ETO_CLIPPED | ETO_OPAQUE,
&lpDIS->rcItem,(LPCTSTR) pLF->lfFaceName,
lstrlen((LPCTSTR) pLF->lfFaceName), NULL );
// Put the colors back as they were
pDC->SetTextColor( crText );
pDC->SetBkColor( crBk );
// Draw the TrueType bitmap
if (pFI->dwFontType & TRUETYPE_FONTTYPE)
{
int dy;
dy = ((lpDIS->rcItem.bottom - lpDIS->rcItem.top) - DY_BITMAP) / 2;
_AfxDrawMaskedBitmap(pDC, &m_bmpTrueType, &m_bmpMask,
x, lpDIS->rcItem.top + dy, DX_BITMAP, DY_BITMAP);
}
// Draw the focus rect if needed
if (lpDIS->itemState & ODS_FOCUS)
pDC->DrawFocusRect( &lpDIS->rcItem );
}
void CFontComboBox::DeleteItem(LPDELETEITEMSTRUCT lpDIS)
{
FONTITEM_PPG* pFI;
if (lpDIS->itemID == -1)
return;
ASSERT( lpDIS->CtlType == ODT_COMBOBOX );
pFI = GetFontItem(lpDIS->itemID);
// Free the FONTITEM_PPG created in CFontComboBox::AddFont()
ASSERT(pFI);
delete pFI;
}
/////////////////////////////////////////////////////////////////////////////
// CSizeComboBox
int CSizeComboBox::AddSize(int PointSize, LONG lfHeight)
{
if (lfHeight == 0)
lfHeight = MulDiv( -afxData.cyPixelsPerInch, PointSize, 72 );
CString str;
wsprintf(str.GetBuffer(16), _T("%d"), PointSize);
str.ReleaseBuffer();
int nMaxEntries = GetCount();
int nEntry;
// we use positive height values for non-truetype fonts, negitive for true type
if (lfHeight > 0)
{
for (nEntry = 0; nEntry < nMaxEntries; nEntry++)
{
int iComp = (int)(lfHeight - GetHeight(nEntry));
if (!iComp)
return CB_ERR;
if (iComp < 0)
break;
}
}
else
{
for (nEntry = 0; nEntry < nMaxEntries; nEntry++)
{
int iComp = (int)(lfHeight - GetHeight(nEntry));
if (!iComp)
return CB_ERR;
if (iComp > 0)
break;
}
}
if (nEntry == nMaxEntries)
nEntry = -1;
nEntry = InsertString(nEntry, str);
if (nEntry != CB_ERR)
SetItemData(nEntry, (DWORD)lfHeight);
return nEntry;
}
void CSizeComboBox::GetPointSize(CY& cy)
{
TCHAR szText[20];
GetWindowText(szText, 20);
cy.Lo = 0;
cy.Hi = 0;
_AfxCyFromString(cy, szText);
}
LONG CSizeComboBox::GetHeight(int sel)
{
if (sel == -1)
sel = GetCurSel();
if (sel == -1)
{
TCHAR szText[20];
GetWindowText(szText, 20);
sel = FindString( -1, szText);
if (sel == CB_ERR)
{
CY cyTmp;
cyTmp.Lo = 0;
cyTmp.Hi = 0;
_AfxCyFromString(cyTmp, szText);
int PointSize = (int)((cyTmp.Lo + 5000) / 10000);
if (PointSize != 0)
return MulDiv(-afxData.cyPixelsPerInch, PointSize, 72);
else
sel = 0;
}
}
return (LONG) GetItemData(sel);
}
void CSizeComboBox::UpdateLogFont( LPLOGFONT lpLF, int sel )
{
ASSERT(lpLF);
lpLF->lfHeight = (int)GetHeight(sel);
lpLF->lfWidth = 0;
}
/////////////////////////////////////////////////////////////////////////////
// CFontPropPage message handlers
void CFontPropPage::OnEditupdateFontnames()
{
// When the users entry matches an entry in the list, select it
CString str;
m_FontNames.GetWindowText(str);
int nEntry = m_FontNames.FindStringExact(-1, str);
if (nEntry != CB_ERR)
{
m_FontNames.SetCurSel(nEntry);
m_FontNames.SetEditSel(-1, -1);
// Re-fill the size list
FillSizeList();
}
}
void CFontPropPage::OnEditupdateFontsizes()
{
// when the users entry matches an entry in the list, select it
m_FontSizes.GetWindowText(m_strFontSize);
int nEntry = m_FontSizes.FindStringExact(-1, m_strFontSize);
if (nEntry != CB_ERR)
{
m_FontSizes.SetCurSel(nEntry);
m_FontSizes.SetEditSel(-1, -1);
// Update the sample text
UpdateSampleFont();
}
}
void CFontPropPage::OnSelchangeFontnames()
{
FillSizeList();
}
void CFontPropPage::UpdateSampleFont()
{
ASSERT(m_FontNames.GetFontItem());
LOGFONT lf = *m_FontNames.GetLogFont();
m_FontSizes.UpdateLogFont( &lf );
// Handle styles
if (m_nCurrentStyle & NTM_BOLD)
lf.lfWeight = FW_BOLD;
else
lf.lfWeight = FW_REGULAR;
if (m_nCurrentStyle & NTM_ITALIC)
lf.lfItalic = TRUE;
else
lf.lfItalic = FALSE;
lf.lfStrikeOut = (unsigned char)m_bStrikeOut;
lf.lfUnderline = (unsigned char)m_bUnderline;
SampleFont.DeleteObject();
SampleFont.CreateFontIndirect( &lf );
CRect rcSample;
m_SampleBox.GetWindowRect( &rcSample );
ScreenToClient( &rcSample );
InvalidateRect( rcSample );
UpdateWindow();
}
void CFontPropPage::OnPaint()
{
CPaintDC dc(this);
CRect rcText;
CFont *oldFont;
CSize TextExtent;
COLORREF crText;
TEXTMETRIC tm;
int bkMode, len, x, y;
CString strSample;
strSample.LoadString(AFX_IDS_SAMPLETEXT);
// If there is no sample font abort
if (!SampleFont.GetSafeHandle())
return;
// Get the bounding box
m_SampleBox.GetWindowRect( &rcText );
ScreenToClient( &rcText );
// Select the new font and colors into the dc
oldFont = dc.SelectObject( &SampleFont );
crText = dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
bkMode = dc.SetBkMode(TRANSPARENT);
// Calculate the position of the text
dc.GetTextMetrics( &tm );
len = strSample.GetLength();
TextExtent = dc.GetTextExtent(strSample, len);
TextExtent.cy = tm.tmAscent - tm.tmInternalLeading;
if ((TextExtent.cx >= (rcText.right - rcText.left)) ||
(TextExtent.cx <= 0))
x = rcText.left;
else
x = rcText.left + ((rcText.right - rcText.left) - TextExtent.cx) / 2;
y = min(rcText.bottom,
rcText.bottom - ((rcText.bottom - rcText.top) - TextExtent.cy) / 2);
// Draw it
dc.ExtTextOut(x, y - (tm.tmAscent), ETO_CLIPPED, &rcText,
strSample, len, NULL);
// Put the DC back the way it was
dc.SetBkMode(bkMode);
dc.SetTextColor(crText);
if (oldFont)
dc.SelectObject(oldFont);
}
void CFontPropPage::OnSelchangeFontsizes()
{
int nEntry = m_FontSizes.GetCurSel();
if (nEntry != CB_ERR)
{
m_FontSizes.GetLBText(nEntry, m_strFontSize);
UpdateSampleFont();
}
}
void CFontPropPage::OnSelchangeFontstyles()
{
int nEntry = m_FontStyles.GetCurSel();
m_nCurrentStyle = m_FontStyles.GetItemData(nEntry);
m_nActualStyle = m_nCurrentStyle;
// Update the sample font
UpdateSampleFont();
}
void CFontPropPage::OnEditchangeFontstyles()
{
// when the users entry matches an entry in the list, select it
CString str;
m_FontStyles.GetWindowText(str);
int nEntry = m_FontStyles.FindStringExact(-1, str);
if (nEntry != CB_ERR)
{
m_FontStyles.SetCurSel(nEntry);
m_FontStyles.SetEditSel(-1, -1);
// Update the sample text
m_nCurrentStyle = m_FontStyles.GetItemData(nEntry);
m_nActualStyle = m_nCurrentStyle;
UpdateSampleFont();
}
}
void CFontPropPage::SelectFontFromList(CString strFaceName, MERGEOBJECT* pmobj)
{
// Set the effects buttons
CButton* pStrikeOut = (CButton*) GetDlgItem(AFX_IDC_STRIKEOUT);
if (!pmobj->bStrikethroughOK)
pStrikeOut->SetCheck(2);
else if (m_bStrikeOut)
pStrikeOut->SetCheck(1);
else
pStrikeOut->SetCheck(0);
CButton* pUnderline = (CButton*) GetDlgItem(AFX_IDC_UNDERLINE);
if (!pmobj->bUnderlineOK)
pStrikeOut->SetCheck(2);
else if (m_bUnderline)
pUnderline->SetCheck(1);
else
pUnderline->SetCheck(0);
// Set the font facename
if (pmobj->bNameOK)
{
int nEntry1 = m_FontNames.SelectString(-1, strFaceName);
if (nEntry1 == CB_ERR)
return;
}
// Fill the size list appropriately
FillSizeList();
// Set the styles combo box selection
BOOL bFound = FALSE;
int nMaxEntries = m_FontStyles.GetCount();
for (int nEntry3 = 0; nEntry3 < nMaxEntries; nEntry3++)
{
if (m_FontStyles.GetItemData(nEntry3) == m_nActualStyle)
{
m_FontStyles.SetCurSel(nEntry3);
bFound = TRUE;
}
}
if (pmobj->bSizeOK)
{
if (!bFound)
{
m_FontStyles.SetCurSel(0); // Set style to regular
m_nCurrentStyle = NTM_REGULAR;
}
else
m_nCurrentStyle = m_nActualStyle;
}
UpdateSampleFont();
}
void CFontPropPage::OnStrikeout()
{
CButton* pStrikeOut = (CButton*) GetDlgItem(AFX_IDC_STRIKEOUT);
if (pStrikeOut->GetCheck() == 1)
m_bStrikeOut = TRUE;
else
m_bStrikeOut = FALSE;
UpdateSampleFont();
}
void CFontPropPage::OnUnderline()
{
CButton* pUnderline = (CButton*) GetDlgItem(AFX_IDC_UNDERLINE);
if (pUnderline->GetCheck() == 1)
m_bUnderline = TRUE;
else
m_bUnderline = FALSE;
UpdateSampleFont();
}
void CFontPropPage::OnSelchangeFontprop()
{
OnSelchangePropname(m_FontProp);
}
BOOL CFontPropPage::OnEditProperty(DISPID dispid)
{
return CStockPropPage::OnEditProperty(dispid, m_FontProp);
}
void CFontPropPage::OnObjectsChanged()
{
ULONG nObjects;
if (GetObjectArray(&nObjects) != NULL && m_hWnd != NULL)
{
FillPropnameList(IID_IFontDisp, 1, m_FontProp);
if ( m_FontProp.GetCount() > 0 )
FillFacenameList();
else
{
m_FontNames.EnableWindow(FALSE);
m_FontSizes.EnableWindow(FALSE);
m_FontStyles.EnableWindow(FALSE);
GetDlgItem(AFX_IDC_STRIKEOUT)->EnableWindow(FALSE);
GetDlgItem(AFX_IDC_UNDERLINE)->EnableWindow(FALSE);
}
}
if (m_hWnd != NULL)
OnSelchangeFontprop();
}
/////////////////////////////////////////////////////////////////////////////
// Class factory for Font property page
#ifdef _AFXDLL
#ifdef AFXCTL_FACT_SEG
#pragma code_seg(AFXCTL_FACT_SEG)
#endif
IMPLEMENT_OLECREATE_EX(CFontPropPage, "OCxx.CFontPropPage",
0x0be35200,0x8f91,0x11ce,0x9d,0xe3,0x00,0xaa,0x00,0x4b,0xb8,0x51)
BOOL CFontPropPage::CFontPropPageFactory::UpdateRegistry(BOOL bRegister)
{
if (bRegister)
return AfxOleRegisterPropertyPageClass(AfxGetInstanceHandle(),
m_clsid, AFX_IDS_FONT_PPG);
else
return AfxOleUnregisterClass(m_clsid, NULL);
}
#endif //_AFXDLL
/////////////////////////////////////////////////////////////////////////////
// Force any extra compiler-generated code into AFX_INIT_SEG
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_DYNCREATE(CFontPropPage, CStockPropPage)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -