📄 formatbar.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.
// Modified by Zhang Yong
#include "stdafx.h"
#include "FormatBar.h"
#include "CNIcq.h"
extern CCNIcqApp theApp;
#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 IDC_FONTSIZE 1001
#define IDC_FONTNAME 1002
#define BMW 16
#define BMH 15
static UINT BASED_CODE format[] =
{
// same order as in the bitmap 'format.bmp'
ID_CHAR_BOLD,
ID_CHAR_ITALIC,
ID_CHAR_UNDERLINE,
ID_CHAR_COLOR,
ID_CHAR_EMOTION,
ID_SEPARATOR, // font name combo box
ID_SEPARATOR,
ID_SEPARATOR, // font size combo box
ID_SEPARATOR,
};
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)
// 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;
}
BOOL CFormatBar::create(CWnd *parent)
{
if (!CreateEx(parent, TBSTYLE_FLAT,
WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_SIZE_FIXED) ||
!LoadBitmap(IDB_FORMATBAR) ||
!SetButtons(format, sizeof(format)/sizeof(UINT)))
{
return FALSE; // fail to create
}
for (int i = 0; i < 3; ++i) {
UINT id, style;
int image;
GetButtonInfo(i, id, style, image);
SetButtonInfo(i, id, style | TBBS_CHECKBOX, image);
}
SetSizes(CSize(23,22), CSize(16,16));
PositionCombos();
return TRUE;
}
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()
{
// get the current font from the view and update
CHARHDR fh;
CHARFORMAT& cf = fh.cf;
cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_COLOR | CFM_FACE | CFM_SIZE;
fh.hwndFrom = m_hWnd;
fh.idFrom = GetDlgCtrlID();
fh.code = FN_GETFORMAT;
CWnd *pWnd = GetOwner();
VERIFY(GetOwner()->SendMessage(WM_NOTIFY, fh.idFrom, (LPARAM)&fh));
GetToolBarCtrl().CheckButton(ID_CHAR_BOLD, cf.dwEffects & CFE_BOLD);
GetToolBarCtrl().CheckButton(ID_CHAR_ITALIC, cf.dwEffects & CFE_ITALIC);
GetToolBarCtrl().CheckButton(ID_CHAR_UNDERLINE, cf.dwEffects & CFE_UNDERLINE);
// 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(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 = FALSE;
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
{
nSize = m_comboFontSize.m_nTwipsLast;
}
else if ((nSize >= 0 && nSize < 20) || nSize > 32760)
{
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()
{
// 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,
(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,
(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)
{
nSize = m_comboFontSize.m_nTwipsLast;
}
else if ((nSize >= 0 && nSize < 20) || nSize > 32760)
{
nSize = m_comboFontSize.m_nTwipsLast;
}
else if (nSize > 0)
{
CCharFormat cf;
cf.dwMask = CFM_SIZE;
cf.yHeight = nSize;
SetCharFormat(cf);
}
}
int CFormatBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CToolBar::OnCreate(lpCreateStruct) == -1)
return -1;
CRect rect(0,0, (4*LF_FACESIZE*m_szBaseUnits.cx)/5, 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, 8*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();
}
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();
int index = 5;
m_comboFontName.GetWindowRect(&rect);
SetButtonInfo(index, IDC_FONTNAME, TBBS_SEPARATOR, rect.Width());
GetItemRect(index, &rect); // FontName ComboBox
m_comboFontName.SetWindowPos(NULL, rect.left,
((rect.Height() - nHeight) / 2) + rect.top, 0, 0,
SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
index = 7;
m_comboFontSize.GetWindowRect(&rect);
SetButtonInfo(index, IDC_FONTSIZE, TBBS_SEPARATOR, rect.Width());
GetItemRect(index, &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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -