enedit.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 738 行 · 第 1/2 页
CPP
738 行
// enedit.cpp : implementation file
//
#include "stdafx.h"
#include "enedit.h"
#include "themed.h"
#include "dlgunits.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CEnEdit
const int MENUSIZE = 4;
CEnEdit::CEnEdit(BOOL bComboStyle, LPCTSTR szMask, DWORD dwFlags) :
CMaskEdit(szMask, dwFlags),
m_bComboStyle(bComboStyle),
m_bFirstShow(TRUE),
m_nButtonDown(-1),
m_nBottomBorder(0),
m_nTopBorder(0)
{
}
CEnEdit::~CEnEdit()
{
// cleanup fonts
int nBtn = m_aButtons.GetSize();
while (nBtn--)
::DeleteObject(m_aButtons[nBtn].hFont);
}
BEGIN_MESSAGE_MAP(CEnEdit, CMaskEdit)
//{{AFX_MSG_MAP(CEnEdit)
ON_WM_NCCALCSIZE()
ON_WM_NCLBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_SIZE()
ON_WM_NCPAINT()
ON_WM_NCHITTEST()
//}}AFX_MSG_MAP
ON_REGISTERED_MESSAGE(WM_HTHOTCHANGE, OnHotChange)
ON_WM_ENABLE()
ON_MESSAGE(EM_SETREADONLY, OnSetReadOnly)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEnEdit message handlers
BOOL CEnEdit::AddButton(UINT nID, LPCTSTR szCaption, LPCTSTR szTip, int nWidth, LPCTSTR szFont)
{
return InsertButton(m_aButtons.GetSize(), nID, szCaption, szTip, nWidth, szFont, FALSE);
}
BOOL CEnEdit::AddButton(UINT nID, UINT nChar, LPCTSTR szTip, int nWidth, LPCTSTR szFont)
{
// Valik - cast to TCHAR is necessary or the compiler complains under VC 7.1
return InsertButton(m_aButtons.GetSize(), nID, CString(static_cast<TCHAR>(nChar)), szTip, nWidth, szFont, TRUE);
}
BOOL CEnEdit::InsertButton(int nPos, UINT nID, LPCTSTR szCaption, LPCTSTR szTip, int nWidth, LPCTSTR szFont)
{
return InsertButton(nPos, nID, szCaption, szTip, nWidth, szFont, FALSE);
}
BOOL CEnEdit::InsertButton(int nPos, UINT nID, UINT nChar, LPCTSTR szTip, int nWidth, LPCTSTR szFont)
{
// Valik - cast to TCHAR is necessary or the compiler complains under VC 7.1
return InsertButton(nPos, nID, CString(static_cast<TCHAR>(nChar)), szTip, nWidth, szFont, TRUE);
}
BOOL CEnEdit::InsertButton(int nPos, UINT nID, LPCTSTR szCaption, LPCTSTR szTip, int nWidth, LPCTSTR szFont, BOOL bSymbolFont)
{
if (nWidth < CALC_BTNWIDTH || !nID)
return FALSE;
nPos = max(nPos, 0);
nPos = min(nPos, m_aButtons.GetSize());
EDITBTN eb;
eb.nID = nID;
eb.sCaption = szCaption;
eb.sTip = szTip;
eb.nWidth = nWidth;
eb.hFont = NULL;
eb.bChecked = FALSE;
eb.bEnabled = TRUE;
eb.bDropMenu = FALSE;
if (szFont)
{
LOGFONT lf;
HFONT hDef = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
if (GetObject(hDef, sizeof(lf), &lf))
{
lstrcpy(lf.lfFaceName, szFont);
if (bSymbolFont)
{
lf.lfCharSet = SYMBOL_CHARSET;
lf.lfQuality = ANTIALIASED_QUALITY;
}
eb.hFont = CreateFontIndirect(&lf);
if (!eb.hFont)
return FALSE;
}
}
m_aButtons.InsertAt(nPos, eb);
// add rect to hot tracker
m_hotTrack.AddRect(CRect(0, 0, 0, 0));
if (GetSafeHwnd())
{
if (!eb.sTip.IsEmpty())
m_tooltip.AddTool(this, eb.sTip, CRect(0, 0, 10, 10), nID);
RecalcBtnRects();
// force WM_NCCALCSIZE
if (!m_bFirstShow)
SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
}
return TRUE;
}
void CEnEdit::SetBorders(int nTop, int nBottom)
{
nTop = max(nTop, 0);
nBottom = max(nBottom, 0);
if (m_nTopBorder != nTop || m_nBottomBorder != nBottom)
{
m_nBottomBorder = nBottom;
m_nTopBorder = nTop;
// force WM_NCCALCSIZE
if (GetSafeHwnd())
SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
}
}
void CEnEdit::PreSubclassWindow()
{
CMaskEdit::PreSubclassWindow();
// create tooltip
if (!m_tooltip.GetSafeHwnd() && m_tooltip.Create(this))
{
// add any existing buttons
int nBtn = m_aButtons.GetSize();
while (nBtn--)
{
const EDITBTN& eb = m_aButtons[nBtn];
m_tooltip.AddTool(this, eb.sTip, CRect(), eb.nID);
}
}
RecalcBtnRects();
// hot tracking
if (CThemed().AreControlsThemed())
m_hotTrack.Initialize(this);
}
BOOL CEnEdit::PreTranslateMessage(MSG* pMsg)
{
m_tooltip.RelayEvent(pMsg);
return CMaskEdit::PreTranslateMessage(pMsg);
}
void CEnEdit::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
{
if (!(GetStyle() & ES_MULTILINE))
{
if (bCalcValidRects)
{
m_bFirstShow = FALSE; // in case we get here before OnNcPaint()
int nBtn = m_aButtons.GetSize();
while (nBtn--)
lpncsp->rgrc[0].right -= GetButtonWidth(nBtn);
lpncsp->rgrc[0].top += m_nTopBorder;
lpncsp->rgrc[0].bottom -= m_nBottomBorder;
}
}
CMaskEdit::OnNcCalcSize(bCalcValidRects, lpncsp);
}
void CEnEdit::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
CMaskEdit::OnNcLButtonDown(nHitTest, point);
if (IsWindowEnabled())
{
int nBtn = ButtonHitTest(point);
if (nBtn >= 0)
{
if (m_aButtons[nBtn].bEnabled)
{
SetCapture();
m_nButtonDown = nBtn;
SendMessage(WM_NCPAINT);
}
}
else
SetFocus();
}
}
void CEnEdit::OnLButtonUp(UINT nFlags, CPoint point)
{
CMaskEdit::OnLButtonUp(nFlags, point);
if (m_nButtonDown == -1)
return;
ClientToScreen(&point);
int nBtnDown = m_nButtonDown;
int nBtnUp = ButtonHitTest(point);
// update UI
ReleaseCapture();
m_nButtonDown = -1;
SendMessage(WM_NCPAINT);
// process
if (nBtnDown == nBtnUp)
{
// call derived class first
OnBtnClick(m_aButtons[nBtnUp].nID);
// then parent
GetParent()->SendMessage(WM_EE_BTNCLICK, GetDlgCtrlID(), m_aButtons[nBtnUp].nID);
}
SendMessage(WM_NCPAINT);
}
void CEnEdit::OnMouseMove(UINT nFlags, CPoint point)
{
CMaskEdit::OnMouseMove(nFlags, point);
if (m_nButtonDown != -1)
{
ClientToScreen(&point);
if (ButtonHitTest(point) != m_nButtonDown)
{
ReleaseCapture();
m_nButtonDown = -1;
SendMessage(WM_NCPAINT);
}
}
}
void CEnEdit::OnSize(UINT nType, int cx, int cy)
{
CMaskEdit::OnSize(nType, cx, cy);
// update tool rects
RecalcBtnRects();
}
void CEnEdit::RecalcBtnRects()
{
int nBtn = m_aButtons.GetSize();
while (nBtn--)
{
CRect rBtn = GetButtonRectByIndex(nBtn);
ScreenToClient(rBtn);
m_tooltip.SetToolRect(this, m_aButtons[nBtn].nID, rBtn);
// update hottracker too
m_hotTrack.UpdateRect(nBtn, rBtn);
}
}
CRect CEnEdit::GetButtonRectByIndex(int nBtn) const
{
int nOffset = 0;
for (int nIndex = 0; nIndex < nBtn; nIndex++)
nOffset += GetButtonWidth(nIndex);
CRect rButton;
GetClientRect(rButton);
rButton.left = rButton.right + nOffset;
rButton.right += nOffset + GetButtonWidth(nBtn);
rButton.top -= m_nTopBorder;
rButton.bottom += m_nBottomBorder;
ClientToScreen(rButton);
return rButton;
}
void CEnEdit::OnNcPaint()
{
if (m_bFirstShow)
{
m_bFirstShow = FALSE;
SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
}
Default();
// draw the icon and browse button
CWindowDC dc(this);
CRect rWindow;
GetWindowRect(rWindow);
NcPaint(&dc, rWindow);
}
void CEnEdit::NcPaint(CDC* pDC, const CRect& rWindow)
{
CPoint ptCursor(::GetMessagePos());
int nBtn = m_aButtons.GetSize();
while (nBtn--)
DrawButton(pDC, rWindow, nBtn, ptCursor);
}
int CEnEdit::ButtonHitTest(CPoint ptScreen) const
{
int nBtn = m_aButtons.GetSize();
while (nBtn--)
{
if (GetButtonRectByIndex(nBtn).PtInRect(ptScreen))
return nBtn;
}
return -1;
}
int CEnEdit::ButtonHitTest(UINT nID) const
{
int nBtn = m_aButtons.GetSize();
while (nBtn--)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?