mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1087 lines
26 KiB
1087 lines
26 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 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* pbmpSaveDst = dcDst.SelectObject(pbmpMask);
|
|
CBitmap* pbmpSaveSrc = 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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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;
|
|
|
|
// 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 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 (_tcscmp(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);
|
|
int rc = 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;
|
|
}
|
|
|
|
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);
|
|
int rc = 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
|
|
static int TTDefaults[] = { 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48 };
|
|
for (int i = 0; i < _countof(TTDefaults); i++)
|
|
m_FontSizes.AddSize(TTDefaults[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;
|
|
}
|
|
|
|
#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 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);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// 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)
|