📄 ppgfont.cpp
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#ifdef AFXCTL_PAGE_SEG
#pragma code_seg(AFXCTL_PAGE_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
/////////////////////////////////////////////////////////////////////////////
// CFontPropPage implementation
BEGIN_MESSAGE_MAP(CFontPropPage, CStockPropPage)
//{{AFX_MSG_MAP(CFontPropPage)
ON_WM_PAINT()
ON_CBN_SELCHANGE(AFX_IDC_FONTPROP, OnSelchangeFontprop)
ON_CBN_EDITUPDATE(AFX_IDC_FONTNAMES, OnEditupdateFontnames)
ON_CBN_EDITUPDATE(AFX_IDC_FONTSIZES, OnEditupdateFontsizes)
ON_CBN_SELCHANGE(AFX_IDC_FONTNAMES, OnSelchangeFontnames)
ON_CBN_SELCHANGE(AFX_IDC_FONTSIZES, OnSelchangeFontsizes)
ON_CBN_SELCHANGE(AFX_IDC_FONTSTYLES, OnSelchangeFontstyles)
ON_CBN_EDITCHANGE(AFX_IDC_FONTSTYLES, OnEditchangeFontstyles)
ON_BN_CLICKED(AFX_IDC_STRIKEOUT, OnStrikeout)
ON_BN_CLICKED(AFX_IDC_UNDERLINE, OnUnderline)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CFontPropPage::CFontPropPage() :
CStockPropPage(IDD, AFX_IDS_FONT_PPG_CAPTION)
{
//{{AFX_DATA_INIT(CFontPropPage)
//}}AFX_DATA_INIT
}
BOOL _AfxStringFromCy(CString& str, CY& cy)
{
VARIANTARG varCy;
VARIANTARG varBstr;
AfxVariantInit(&varCy);
AfxVariantInit(&varBstr);
V_VT(&varCy) = VT_CY;
V_CY(&varCy) = cy;
if (FAILED(VariantChangeType(&varBstr, &varCy, 0, VT_BSTR)))
{
VariantClear(&varCy);
VariantClear(&varBstr);
return FALSE;
}
str = V_BSTR(&varBstr);
VariantClear(&varCy);
VariantClear(&varBstr);
return TRUE;
}
BOOL _AfxCyFromString(CY& cy, LPCTSTR psz)
{
USES_CONVERSION;
VARIANTARG varBstr;
VARIANTARG varCy;
AfxVariantInit(&varBstr);
AfxVariantInit(&varCy);
V_VT(&varBstr) = VT_BSTR;
V_BSTR(&varBstr) = SysAllocString(T2COLE(psz));
if (FAILED(VariantChangeType(&varCy, &varBstr, 0, VT_CY)))
{
VariantClear(&varBstr);
VariantClear(&varCy);
return FALSE;
}
cy = V_CY(&varCy);
VariantClear(&varBstr);
VariantClear(&varCy);
return TRUE;
}
#define DSx 0x00660046L
#define DSna 0x00220326L
void _AfxDrawMaskedBitmap(CDC* pDC, CBitmap* pbmp, CBitmap* pbmpMask,
int x, int y, int cx, int cy)
{
COLORREF oldBkColor = pDC->SetBkColor(RGB(255, 255, 255));
COLORREF oldTextColor = pDC->SetTextColor(RGB(0, 0, 0));
CDC dcCompat;
dcCompat.CreateCompatibleDC(pDC);
CBitmap* pbmpSave = dcCompat.SelectObject(pbmp);
pDC->BitBlt(x, y, cx, cy, &dcCompat, 0, 0, DSx);
dcCompat.SelectObject(pbmpMask);
pDC->BitBlt(x, y, cx, cy, &dcCompat, 0, 0, DSna);
dcCompat.SelectObject(pbmp);
pDC->BitBlt(x, y, cx, cy, &dcCompat, 0, 0, DSx);
dcCompat.SelectObject(pbmpSave);
pDC->SetBkColor(oldBkColor);
pDC->SetTextColor(oldTextColor);
}
void _AfxInitMaskFromBitmap(CBitmap* pbmp, CBitmap* pbmpMask)
{
BITMAP bmp;
pbmp->GetObject(sizeof (BITMAP), &bmp);
pbmpMask->CreateBitmap(bmp.bmWidth, bmp.bmHeight, 1, 1, NULL);
CDC dcDst;
dcDst.CreateCompatibleDC(NULL);
CDC dcSrc;
dcSrc.CreateCompatibleDC(NULL);
CBitmap* pOldDst = dcDst.SelectObject(pbmpMask);
CBitmap* pOldSrc = dcSrc.SelectObject(pbmp);
COLORREF oldBkColor = dcSrc.SetBkColor(dcSrc.GetPixel(0, 0));
dcDst.BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &dcSrc, 0, 0, NOTSRCCOPY);
dcSrc.SetBkColor(oldBkColor);
dcDst.SelectObject(pOldDst);
dcSrc.SelectObject(pOldSrc);
}
void CFontPropPage::DoDataExchange(CDataExchange* pDX)
{
//{{AFX_DATA_MAP(CFontPropPage)
DDX_Control(pDX, AFX_IDC_FONTPROP, m_FontProp);
DDX_Control(pDX, AFX_IDC_SAMPLEBOX, m_SampleBox);
DDX_Control(pDX, AFX_IDC_FONTSTYLES, m_FontStyles);
DDX_Control(pDX, AFX_IDC_FONTSIZES, m_FontSizes);
DDX_Control(pDX, AFX_IDC_FONTNAMES, m_FontNames);
//}}AFX_DATA_MAP
if (pDX->m_bSaveAndValidate)
{
FONTOBJECT fobj;
fobj.strName = m_FontNames.GetCurrentName();
if (fobj.strName.IsEmpty())
return;
m_FontSizes.GetPointSize(fobj.cySize);
if (m_nCurrentStyle & NTM_REGULAR)
fobj.sWeight = FW_REGULAR;
if (m_nCurrentStyle & NTM_BOLD)
{
fobj.sWeight = FW_BOLD;
fobj.bBold = TRUE;
}
else
fobj.bBold = FALSE;
if (m_nCurrentStyle & NTM_ITALIC)
fobj.bItalic = TRUE;
else
fobj.bItalic = FALSE;
fobj.bUnderline = m_bUnderline;
fobj.bStrikethrough = m_bStrikeOut;
SetFontProps(pDX, fobj, m_strPropName);
}
else
{
FONTOBJECT fobj;
MERGEOBJECT mobj;
if (!m_strPropName.IsEmpty() && GetFontProps(pDX, &fobj, m_strPropName, &mobj))
{
if (fobj.bBold && fobj.bItalic)
m_nCurrentStyle = NTM_BOLD | NTM_ITALIC;
else if (fobj.bBold)
m_nCurrentStyle = NTM_BOLD;
else if (fobj.bItalic)
m_nCurrentStyle = NTM_ITALIC;
else
m_nCurrentStyle = NTM_REGULAR;
m_nActualStyle = m_nCurrentStyle;
m_bUnderline = fobj.bUnderline;
m_bStrikeOut = fobj.bStrikethrough;
mobj.bNameOK = TRUE;
mobj.bSizeOK = TRUE;
mobj.bStyleOK = TRUE;
mobj.bUnderlineOK = TRUE;
mobj.bStrikethroughOK = TRUE;
_AfxStringFromCy(m_strFontSize, fobj.cySize);
SelectFontFromList(fobj.strName, &mobj);
}
}
}
BOOL CFontPropPage::SetFontProps(CDataExchange* pDX, FONTOBJECT fobj, LPCTSTR pszPropName)
{
USES_CONVERSION;
BOOL bStatus = FALSE;
COleDispatchDriver PropDispDriver;
// Set the properties for all the objects
ASSERT_KINDOF(COlePropertyPage, pDX->m_pDlgWnd);
COlePropertyPage* propDialog = (COlePropertyPage*)(pDX->m_pDlgWnd);
ULONG nObjects;
LPDISPATCH* ppDisp = GetObjectArray(&nObjects);
for (ULONG i = 0; i < nObjects; i++)
{
DISPID dwDispID;
// Get the Dispatch ID for the property and if successful set the value
LPCOLESTR lpOleStr = T2COLE(pszPropName);
if (SUCCEEDED(ppDisp[i]->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpOleStr,
1, m_lcid, &dwDispID)))
{
LPDISPATCH pFontDisp = NULL;
// Get property
PropDispDriver.AttachDispatch(ppDisp[i], FALSE);
TRY
PropDispDriver.GetProperty(dwDispID, VT_DISPATCH, &pFontDisp);
END_TRY
PropDispDriver.DetachDispatch();
if (pFontDisp == NULL)
continue;
// Get font interface
IFont * pFont;
HRESULT hresult = pFontDisp->QueryInterface(IID_IFont, (void**)&pFont);
if (hresult == S_OK)
{
// Set font characteristics
if (propDialog->GetControlStatus(AFX_IDC_FONTNAMES))
{
BSTR bstrName = fobj.strName.AllocSysString();
pFont->put_Name(bstrName);
SysFreeString(bstrName);
}
if (propDialog->GetControlStatus(AFX_IDC_FONTSIZES))
pFont->put_Size(fobj.cySize);
if (propDialog->GetControlStatus(AFX_IDC_FONTSTYLES))
{
pFont->put_Bold(fobj.bBold);
pFont->put_Italic(fobj.bItalic);
pFont->put_Weight(fobj.sWeight);
}
if (propDialog->GetControlStatus(AFX_IDC_UNDERLINE))
pFont->put_Underline(fobj.bUnderline);
if (propDialog->GetControlStatus(AFX_IDC_STRIKEOUT))
pFont->put_Strikethrough(fobj.bStrikethrough);
// Release the font interface
RELEASE(pFont);
bStatus = TRUE;
}
// Release the font dispatch interface
RELEASE(pFontDisp);
}
}
return bStatus;
}
BOOL CFontPropPage::GetFontProps(CDataExchange* /* pDX */,
FONTOBJECT* pfobj, LPCTSTR pszPropName, MERGEOBJECT* pmobj)
{
USES_CONVERSION;
BOOL bStatus = FALSE;
COleDispatchDriver PropDispDriver;
ULONG nObjects;
LPDISPATCH* ppDisp = GetObjectArray(&nObjects);
for (ULONG i = 0; i < nObjects; i++)
{
DISPID dwDispID;
// Get the Dispatch ID for the property and if successful get the value
LPCOLESTR lpOleStr = T2COLE(pszPropName);
if (SUCCEEDED(ppDisp[i]->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpOleStr,
1, m_lcid, &dwDispID)))
{
LPDISPATCH pFontDisp;
// Get property
PropDispDriver.AttachDispatch(ppDisp[i], FALSE);
PropDispDriver.GetProperty(dwDispID, VT_DISPATCH, &pFontDisp);
PropDispDriver.DetachDispatch();
if (pFontDisp == NULL)
continue;
// Get font interface
IFont * pFont;
HRESULT hresult = pFontDisp->QueryInterface(IID_IFont, (void**)&pFont);
if (hresult == S_OK)
{
BOOL bTemp;
// Set font characteristics
OLECHAR *pszName;
pFont->get_Name(&pszName);
if (lstrcmp(OLE2CT(pszName), pfobj->strName) != 0 && i != 0)
pmobj->bNameOK = FALSE;
pfobj->strName = pszName;
SysFreeString(pszName);
CY cyTemp;
pFont->get_Size(&cyTemp);
if ((cyTemp.Lo != pfobj->cySize.Lo || cyTemp.Hi != pfobj->cySize.Hi) && i != 0)
pmobj->bSizeOK = FALSE;
pfobj->cySize = cyTemp;
pFont->get_Bold(&bTemp);
if (pfobj->bBold != bTemp && i != 0)
pmobj->bStyleOK = FALSE;
pfobj->bBold = bTemp;
pFont->get_Italic(&bTemp);
if (pfobj->bItalic != bTemp && i != 0)
pmobj->bStyleOK = FALSE;
pfobj->bItalic = bTemp;
pFont->get_Underline(&bTemp);
if (pfobj->bUnderline != bTemp && i != 0)
pmobj->bUnderlineOK = FALSE;
pfobj->bUnderline = bTemp;
pFont->get_Strikethrough(&bTemp);
if (pfobj->bStrikethrough != bTemp && i != 0)
pmobj->bStrikethroughOK = FALSE;
pfobj->bStrikethrough = bTemp;
short sTemp;
pFont->get_Weight(&sTemp);
if (pfobj->sWeight != sTemp && i != 0)
pmobj->bStyleOK = FALSE;
pfobj->sWeight = sTemp;
// Release the font interface
RELEASE(pFont);
bStatus = TRUE;
}
// Release font interface
RELEASE(pFontDisp);
}
}
return bStatus;
}
BOOL CFontPropPage::OnInitDialog()
{
CStockPropPage::OnInitDialog();
OnObjectsChanged();
IgnoreApply(AFX_IDC_FONTPROP);
return TRUE; // return TRUE unless you set the focus to a control
}
void CFontPropPage::FillFacenameList()
{
// Clear the list
m_FontNames.ResetContent();
// Create a DC to enumerate
CClientDC dc(NULL);
EnumFontFamilies(dc.GetSafeHdc(), (LPCTSTR) NULL,
(FONTENUMPROC)CFontPropPage::EnumFontFamiliesCallBack, (LPARAM) this);
// Select the first one
if (m_FontNames.SetCurSel(0) != CB_ERR)
{
// Fill the size list
FillSizeList();
}
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);
}
}
int CALLBACK CFontPropPage::EnumFontFamiliesCallBack(ENUMLOGFONT *lpelf, NEWTEXTMETRIC *, int FontType, LPARAM lParam)
{
CFontPropPage *pDlg = (CFontPropPage *)lParam;
ASSERT(pDlg);
pDlg->m_FontNames.AddFont(&lpelf->elfLogFont, FontType);
return 1;
}
AFX_STATIC_DATA int _afxTTDefaults[] = { 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48 };
void CFontPropPage::FillSizeList()
{
// Clear the size list
m_FontSizes.ResetContent();
m_FontStyles.ResetContent();
m_nStyles = 0L;
// Fill with "real" sizes
CString strFaceName;
m_FontNames.GetLBText(m_FontNames.GetCurSel(), strFaceName);
CClientDC dc(NULL);
EnumFontFamilies(dc.GetSafeHdc(), (LPCTSTR) strFaceName, (FONTENUMPROC) CFontPropPage::EnumFontFamiliesCallBack2, (LPARAM) this);
// Check if we have a font that is either a vector or Truettype font
if (m_FontNames.GetFontType() != RASTER_FONTTYPE)
{
// Fill with "common" sizes
for (int i = 0; i < _countof(_afxTTDefaults); i++)
m_FontSizes.AddSize(_afxTTDefaults[i], 0);
}
// See what fonts are native
BOOL bRegular = (BOOL)(m_nStyles & NTM_REGULAR);
BOOL bBold = (BOOL)(m_nStyles & NTM_BOLD);
BOOL bItalic = (BOOL)(m_nStyles & NTM_ITALIC);
BOOL bBoldItalic = (BOOL)((m_nStyles & NTM_BOLD) &&
(m_nStyles & NTM_ITALIC));
// Allow for "synthesized" italic && bold variants
if (bRegular)
bBold = bItalic = TRUE;
if (bBold || bItalic)
bBoldItalic = TRUE;
// Fill the styles list box
CString strStyle;
int nEntry;
if (bRegular)
{
strStyle.LoadString(AFX_IDS_REGULAR);
nEntry = m_FontStyles.AddString(strStyle);
m_FontStyles.SetItemData(nEntry, (DWORD)NTM_REGULAR);
}
if (bBold)
{
strStyle.LoadString(AFX_IDS_BOLD);
nEntry = m_FontStyles.AddString(strStyle);
m_FontStyles.SetItemData(nEntry, (DWORD)NTM_BOLD);
}
if (bItalic)
{
strStyle.LoadString(AFX_IDS_ITALIC);
nEntry = m_FontStyles.AddString(strStyle);
m_FontStyles.SetItemData(nEntry, (DWORD)NTM_ITALIC);
}
if (bBoldItalic)
{
strStyle.LoadString(AFX_IDS_BOLDITALIC);
nEntry = m_FontStyles.AddString(strStyle);
m_FontStyles.SetItemData(nEntry, (DWORD)NTM_ITALIC|NTM_BOLD);
}
// Set the point size
if (m_FontSizes.FindString(-1, m_strFontSize) != CB_ERR)
{
nEntry = m_FontSizes.SelectString(-1, m_strFontSize);
if (nEntry == CB_ERR)
return;
}
else
{
// Point size is not in the list so just fill the edit box
// and don't select anything from the list
m_FontSizes.SetCurSel(-1);
m_FontSizes.SetWindowText(m_strFontSize);
}
// 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 (!bFound)
{
m_FontStyles.SetCurSel(0); // Set style to regular
m_nCurrentStyle = NTM_REGULAR;
}
else
m_nCurrentStyle = m_nActualStyle;
// Redraw the sample
UpdateSampleFont();
}
int CALLBACK CFontPropPage::EnumFontFamiliesCallBack2(
ENUMLOGFONT* lpelf, NEWTEXTMETRIC* lpntm, int FontType, LPARAM lParam)
{
CFontPropPage *pDlg = (CFontPropPage *)lParam;
ASSERT(pDlg != NULL);
if (FontType & TRUETYPE_FONTTYPE)
{
if (!(lpntm->ntmFlags & (NTM_BOLD | NTM_ITALIC)))
pDlg->m_nStyles |= NTM_REGULAR;
if (lpntm->ntmFlags & NTM_ITALIC)
pDlg->m_nStyles |= NTM_ITALIC;
if (lpntm->ntmFlags & NTM_BOLD)
pDlg->m_nStyles |= NTM_BOLD;
}
else
{
if (FontType & RASTER_FONTTYPE)
{
int height = lpntm->tmHeight - lpntm->tmInternalLeading;
pDlg->m_FontSizes.AddSize(MulDiv(height, 72, afxData.cyPixelsPerInch), height);
}
if (lpelf->elfLogFont.lfWeight >= FW_BOLD && lpelf->elfLogFont.lfItalic)
pDlg->m_nStyles |= NTM_BOLD | NTM_ITALIC;
else if (lpelf->elfLogFont.lfWeight >= FW_BOLD)
pDlg->m_nStyles |= NTM_BOLD;
else if (lpelf->elfLogFont.lfItalic)
pDlg->m_nStyles |= NTM_ITALIC;
else
pDlg->m_nStyles |= NTM_REGULAR;
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -