📄 formatba.cpp
字号:
// formatba.cpp : implementation file
//
// 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"
#include "wordpad.h"
#include "wordpdoc.h"
#include "wordpvw.h"
#include "formatba.h"
#include "strings.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
// reserve lobyte for charset
#define PRINTER_FONT 0x0100
#define TT_FONT 0x0200
#define DEVICE_FONT 0x0400
#define BMW 16
#define BMH 15
static int nFontSizes[] =
{8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72};
int CLocalComboBox::m_nFontHeight = 0;
class CFontDesc
{
public:
CFontDesc(LPCTSTR lpszName, LPCTSTR lpszScript, BYTE nCharSet,
BYTE nPitchAndFamily, DWORD dwFlags);
CString m_strName;
CString m_strScript;
BYTE m_nCharSet;
BYTE m_nPitchAndFamily;
DWORD m_dwFlags;
};
CFontDesc::CFontDesc(LPCTSTR lpszName, LPCTSTR lpszScript, BYTE nCharSet,
BYTE nPitchAndFamily, DWORD dwFlags)
{
m_strName = lpszName;
m_strScript = lpszScript;
m_nCharSet = nCharSet;
m_nPitchAndFamily = nPitchAndFamily;
m_dwFlags = dwFlags;
}
BEGIN_MESSAGE_MAP(CFormatBar, CToolBar)
//{{AFX_MSG_MAP(CFormatBar)
ON_WM_CREATE()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
ON_CBN_DROPDOWN(IDC_FONTSIZE, OnFontSizeDropDown)
ON_CBN_KILLFOCUS(IDC_FONTNAME, OnFontNameKillFocus)
ON_CBN_KILLFOCUS(IDC_FONTSIZE, OnFontSizeKillFocus)
ON_CBN_SETFOCUS(IDC_FONTNAME, OnComboSetFocus)
ON_CBN_SETFOCUS(IDC_FONTSIZE, OnComboSetFocus)
ON_CBN_CLOSEUP(IDC_FONTNAME, OnComboCloseUp)
ON_CBN_CLOSEUP(IDC_FONTSIZE, OnComboCloseUp)
ON_REGISTERED_MESSAGE(CWordPadApp::m_nPrinterChangedMsg, OnPrinterChanged)
// Global help commands
END_MESSAGE_MAP()
static CSize GetBaseUnits(CFont* pFont)
{
ASSERT(pFont != NULL);
ASSERT(pFont->GetSafeHandle() != NULL);
pFont = theApp.m_dcScreen.SelectObject(pFont);
TEXTMETRIC tm;
VERIFY(theApp.m_dcScreen.GetTextMetrics(&tm));
theApp.m_dcScreen.SelectObject(pFont);
// return CSize(tm.tmAveCharWidth, tm.tmHeight+tm.tmDescent);
return CSize(tm.tmAveCharWidth, tm.tmHeight);
}
CFormatBar::CFormatBar()
{
CFont fnt;
fnt.Attach(GetStockObject(theApp.m_nDefFont));
m_szBaseUnits = GetBaseUnits(&fnt);
CLocalComboBox::m_nFontHeight = m_szBaseUnits.cy;
}
void CFormatBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
CToolBar::OnUpdateCmdUI(pTarget, bDisableIfNoHndler);
// don't update combo boxes if either one has the focus
if (!m_comboFontName.HasFocus() && !m_comboFontSize.HasFocus())
SyncToView();
}
void CFormatBar::SyncToView()
{
USES_CONVERSION;
// get the current font from the view and update
CHARHDR fh;
CHARFORMAT& cf = fh.cf;
fh.hwndFrom = m_hWnd;
fh.idFrom = GetDlgCtrlID();
fh.code = FN_GETFORMAT;
VERIFY(GetOwner()->SendMessage(WM_NOTIFY, fh.idFrom, (LPARAM)&fh));
// the selection must be same font and charset to display correctly
if ((cf.dwMask & (CFM_FACE|CFM_CHARSET)) == (CFM_FACE|CFM_CHARSET))
m_comboFontName.MatchFont(A2T(cf.szFaceName), cf.bCharSet);
else
m_comboFontName.SetTheText(_T(""));
// SetTwipSize only updates if different
// -1 means selection is not a single point size
m_comboFontSize.SetTwipSize( (cf.dwMask & CFM_SIZE) ? cf.yHeight : -1);
}
void CFormatBar::OnFontSizeDropDown()
{
CString str;
m_comboFontName.GetTheText(str);
LPCTSTR lpszName = NULL;
BOOL bPrinterFont;
int nIndex = m_comboFontName.FindStringExact(-1, str);
if (nIndex != CB_ERR)
{
CFontDesc* pDesc = (CFontDesc*)m_comboFontName.GetItemData(nIndex);
ASSERT(pDesc != NULL);
bPrinterFont = pDesc->m_dwFlags & PRINTER_FONT;
lpszName = pDesc->m_strName;
}
int nSize = m_comboFontSize.GetTwipSize();
if (nSize == -2) // error
{
AfxMessageBox(IDS_INVALID_NUMBER, MB_OK|MB_ICONINFORMATION);
nSize = m_comboFontSize.m_nTwipsLast;
}
else if ((nSize >= 0 && nSize < 20) || nSize > 32760)
{
AfxMessageBox(IDS_INVALID_FONTSIZE, MB_OK|MB_ICONINFORMATION);
nSize = m_comboFontSize.m_nTwipsLast;
}
if (bPrinterFont)
m_comboFontSize.EnumFontSizes(m_dcPrinter, lpszName);
else
m_comboFontSize.EnumFontSizes(theApp.m_dcScreen, lpszName);
m_comboFontSize.SetTwipSize(nSize);
}
void CFormatBar::OnComboCloseUp()
{
NotifyOwner(NM_RETURN);
}
void CFormatBar::OnComboSetFocus()
{
NotifyOwner(NM_SETFOCUS);
}
void CFormatBar::OnFontNameKillFocus()
{
USES_CONVERSION;
// get the current font from the view and update
NotifyOwner(NM_KILLFOCUS);
CCharFormat cf;
cf.szFaceName[0] = NULL;
// this will retrieve the font entered in the edit control
// it tries to match the font to something already present in the combo box
// this effectively ignores case of a font the user enters
// if a user enters arial, this will cause it to become Arial
CString str;
m_comboFontName.GetTheText(str); // returns "arial"
m_comboFontName.SetTheText(str); // selects "Arial"
m_comboFontName.GetTheText(str); // returns "Arial"
// if font name box is not empty
if (str[0] != NULL)
{
cf.dwMask = CFM_FACE | CFM_CHARSET;
int nIndex = m_comboFontName.FindStringExact(-1, str);
if (nIndex != CB_ERR)
{
CFontDesc* pDesc = (CFontDesc*)m_comboFontName.GetItemData(nIndex);
ASSERT(pDesc != NULL);
ASSERT(pDesc->m_strName.GetLength() < LF_FACESIZE);
lstrcpynA(cf.szFaceName,
T2A((LPTSTR) (LPCTSTR) pDesc->m_strName), LF_FACESIZE);
cf.bCharSet = pDesc->m_nCharSet;
cf.bPitchAndFamily = pDesc->m_nPitchAndFamily;
}
else // unknown font
{
ASSERT(str.GetLength() < LF_FACESIZE);
lstrcpynA(cf.szFaceName,
T2A((LPTSTR) (LPCTSTR) str), LF_FACESIZE);
cf.bCharSet = DEFAULT_CHARSET;
cf.bPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
}
SetCharFormat(cf);
}
}
void CFormatBar::OnFontSizeKillFocus()
{
NotifyOwner(NM_KILLFOCUS);
int nSize = m_comboFontSize.GetTwipSize();
if (nSize == -2)
{
AfxMessageBox(IDS_INVALID_NUMBER, MB_OK|MB_ICONINFORMATION);
nSize = m_comboFontSize.m_nTwipsLast;
}
else if ((nSize >= 0 && nSize < 20) || nSize > 32760)
{
AfxMessageBox(IDS_INVALID_FONTSIZE, MB_OK|MB_ICONINFORMATION);
nSize = m_comboFontSize.m_nTwipsLast;
}
else if (nSize > 0)
{
CCharFormat cf;
cf.dwMask = CFM_SIZE;
cf.yHeight = nSize;
SetCharFormat(cf);
}
}
LONG CFormatBar::OnPrinterChanged(UINT, LONG)
{
theApp.CreatePrinterDC(m_dcPrinter);
m_comboFontName.EnumFontFamiliesEx(m_dcPrinter);
return 0;
}
int CFormatBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CToolBar::OnCreate(lpCreateStruct) == -1)
return -1;
theApp.m_listPrinterNotify.AddTail(m_hWnd);
CRect rect(0,0, (3*LF_FACESIZE*m_szBaseUnits.cx)/2, 200);
if (!m_comboFontName.Create(WS_TABSTOP|WS_VISIBLE|WS_TABSTOP|
WS_VSCROLL|CBS_DROPDOWN|CBS_SORT|CBS_AUTOHSCROLL|CBS_HASSTRINGS|
CBS_OWNERDRAWFIXED, rect, this, IDC_FONTNAME))
{
TRACE0("Failed to create fontname combo-box\n");
return -1;
}
m_comboFontName.LimitText(LF_FACESIZE);
rect.SetRect(0, 0, 10*m_szBaseUnits.cx, 200);
if (!m_comboFontSize.Create(WS_TABSTOP|WS_VISIBLE|WS_TABSTOP|
WS_VSCROLL|CBS_DROPDOWN, rect, this, IDC_FONTSIZE))
{
TRACE0("Failed to create fontsize combo-box\n");
return -1;
}
m_comboFontSize.LimitText(4);
m_comboFontName.EnumFontFamiliesEx(m_dcPrinter);
return 0;
}
void CFormatBar::OnDestroy()
{
CToolBar::OnDestroy();
POSITION pos = theApp.m_listPrinterNotify.Find(m_hWnd);
ASSERT(pos != NULL);
theApp.m_listPrinterNotify.RemoveAt(pos);
}
void CFormatBar::PositionCombos()
{
CRect rect;
// make font name box same size as font size box
// this is necessary since font name box is owner draw
m_comboFontName.SetItemHeight(-1, m_comboFontSize.GetItemHeight(-1));
m_comboFontName.GetWindowRect(&rect);
int nHeight = rect.Height();
m_comboFontName.GetWindowRect(&rect);
SetButtonInfo(0, IDC_FONTNAME, TBBS_SEPARATOR, rect.Width());
GetItemRect(0, &rect); // FontName ComboBox
m_comboFontName.SetWindowPos(NULL, rect.left,
((rect.Height() - nHeight) / 2) + rect.top, 0, 0,
SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
m_comboFontSize.GetWindowRect(&rect);
SetButtonInfo(2, IDC_FONTSIZE, TBBS_SEPARATOR, rect.Width());
GetItemRect(2, &rect); // FontSize ComboBox
m_comboFontSize.SetWindowPos(NULL, rect.left,
((rect.Height() - nHeight) / 2) + rect.top, 0, 0,
SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
}
/////////////////////////////////////////////////////////////////////////////
// CFontComboBox
BEGIN_MESSAGE_MAP(CFontComboBox, CLocalComboBox)
//{{AFX_MSG_MAP(CFontComboBox)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
// Global help commands
END_MESSAGE_MAP()
CFontComboBox::CFontComboBox()
{
VERIFY(m_bmFontType.LoadBitmap(IDB_FONTTYPE));
}
void CFontComboBox::OnDestroy()
{
// destroy all the CFontDesc's
EmptyContents();
CLocalComboBox::OnDestroy();
}
void CFontComboBox::EmptyContents()
{
// destroy all the CFontDesc's
int nCount = GetCount();
for (int i=0;i<nCount;i++)
delete (CFontDesc*)GetItemData(i);
}
void CFontComboBox::EnumFontFamiliesEx(CDC& dc, BYTE nCharSet)
{
CMapStringToPtr map;
CString str;
GetTheText(str);
EmptyContents();
ResetContent();
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfCharSet = nCharSet;
if (dc.m_hDC != NULL)
{
if (theApp.m_bWin4)
{
::EnumFontFamiliesEx(dc.m_hDC, &lf,
(FONTENUMPROC) EnumFamPrinterCallBackEx, (LPARAM) this, NULL);
}
else
{
::EnumFontFamilies(dc.m_hDC, NULL,
(FONTENUMPROC) EnumFamPrinterCallBack, (LPARAM) this);
}
}
else
{
HDC hDC = theApp.m_dcScreen.m_hDC;
ASSERT(hDC != NULL);
if (theApp.m_bWin4)
{
::EnumFontFamiliesEx(hDC, &lf,
(FONTENUMPROC) EnumFamScreenCallBackEx, (LPARAM) this, NULL);
}
else
{
::EnumFontFamilies(hDC, NULL,
(FONTENUMPROC) EnumFamScreenCallBack, (LPARAM) this);
}
}
// now walk through the fonts and remove (charset) from fonts with only one
int nCount = m_arrayFontDesc.GetSize();
// walk through fonts adding names to string map
// first time add value 0, after that add value 1
for (int i = 0; i<nCount;i++)
{
CFontDesc* pDesc = (CFontDesc*)m_arrayFontDesc[i];
void* pv = NULL;
if (map.Lookup(pDesc->m_strName, pv)) // found it
{
if (pv == NULL) // only one entry so far
{
map.RemoveKey(pDesc->m_strName);
map.SetAt(pDesc->m_strName, (void*)1);
}
}
else // not found
map.SetAt(pDesc->m_strName, (void*)0);
}
for (i = 0; i<nCount;i++)
{
CFontDesc* pDesc = (CFontDesc*)m_arrayFontDesc[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -