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 + -
显示快捷键?