enedit.cpp

来自「管理项目进度工具的原代码」· C++ 代码 · 共 738 行 · 第 1/2 页

CPP
738
字号
		if (m_aButtons[nBtn].nID == nID)
			return nBtn;
	}

	return -1;
}

BOOL CEnEdit::EnableButton(UINT nID, BOOL bEnable)
{
	int nBtn = ButtonHitTest(nID);

	if (nBtn < 0)
		return FALSE;

	if (m_aButtons[nBtn].bEnabled != bEnable)
	{
		m_aButtons[nBtn].bEnabled = bEnable;
		SendMessage(WM_NCPAINT);
	}

	return TRUE;
}

BOOL CEnEdit::SetDropMenuButton(UINT nID, BOOL bDropMenu)
{
	int nBtn = ButtonHitTest(nID);

	if (nBtn < 0)
		return FALSE;

	if (m_aButtons[nBtn].bDropMenu != bDropMenu)
	{
		m_aButtons[nBtn].bDropMenu = bDropMenu;
	
		if (GetSafeHwnd())
			SendMessage(WM_NCPAINT);
	}

	return TRUE;
}

BOOL CEnEdit::CheckButton(UINT nID, BOOL bChecked)
{
	int nBtn = ButtonHitTest(nID);

	if (nBtn < 0)
		return FALSE;

	if (m_aButtons[nBtn].bChecked != bChecked)
	{
		m_aButtons[nBtn].bChecked = bChecked;
		SendMessage(WM_NCPAINT);
	}

	return TRUE;
}

BOOL CEnEdit::SetButtonTip(UINT nID, LPCTSTR szTip)
{
	int nBtn = ButtonHitTest(nID);

	if (nBtn < 0)
		return FALSE;

	if (m_aButtons[nBtn].sTip.Compare(szTip) != 0)
	{
		m_aButtons[nBtn].sTip = szTip;

		if (GetSafeHwnd())
		{
			m_tooltip.UpdateTipText(szTip, this, m_aButtons[nBtn].nID);
			SendMessage(WM_NCPAINT);
		}
	}

	return TRUE;
}

BOOL CEnEdit::SetButtonCaption(UINT nID, LPCTSTR szCaption)
{
	int nBtn = ButtonHitTest(nID);

	if (nBtn < 0)
		return FALSE;

	EDITBTN& eb = m_aButtons[nBtn];

	if (eb.sCaption.Compare(szCaption) != 0)
	{
		eb.sCaption = szCaption;

		// recalc width?
		if (eb.nWidth == CALC_BTNWIDTH)
			RecalcBtnRects();

		if (GetSafeHwnd())
		{
			// force WM_NCCALCSIZE
			SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
			SendMessage(WM_NCPAINT);
		}
	}

	return TRUE;
}

CRect CEnEdit::GetButtonRect(UINT nID)
{
	int nBtn = ButtonHitTest(nID);

	if (nBtn >= 0)
		return GetButtonRectByIndex(nBtn);

	return CRect(0, 0, 0, 0);
}

void CEnEdit::DrawButton(CDC* pDC, const CRect& rWindow, int nBtn, const CPoint& ptCursor) const
{
	const EDITBTN& eb = m_aButtons[nBtn];

	CRect rBtn = GetButtonRectByIndex(nBtn);

	if (rBtn.IsRectEmpty())
		return;

	BOOL bThemed = CThemed().AreControlsThemed();
	BOOL bHot = rBtn.PtInRect(ptCursor);
	BOOL bEnabled = (IsWindowEnabled() && eb.bEnabled);
	BOOL bDown = (m_nButtonDown == nBtn || eb.bChecked);

	rBtn.OffsetRect(-rWindow.TopLeft());

	// nasty business here because the API function DrawThemeEdge() is not theme aware!
	// and drawing a themed combostyle button will also draw the arrow which we don't want
	if (!m_bComboStyle || bThemed)	// draw as button type (for now)
	{
		UINT nFlags = DFCS_ADJUSTRECT | DFCS_BUTTONPUSH;
		
		// note: we do not take account of ES_READONLY as the effect of this
		// is not deterministic at this level so we assume derived classes or 
		// parents have handled it
		if (!bEnabled)
			nFlags |= DFCS_INACTIVE;
		
		else if (bDown)
			nFlags |= DFCS_PUSHED;
		
		else if (bHot)
			nFlags |= DFCS_HOT;
		
		// clip the drawing rect to prevent window getting the parent bkgnd color wrong
		CRect rClip(rBtn);

		if (bThemed)
			rBtn.InflateRect(1, 1);
		
		// for now
		CThemed::DrawFrameControl(this, pDC, rBtn, DFC_BUTTON, nFlags, rClip);
	}
	else // unthemed combo style
	{
		if (bEnabled && bDown)
			pDC->DrawEdge(rBtn, BDR_RAISEDOUTER, BF_ADJUST | BF_RECT | BF_MIDDLE | BF_FLAT);
		else
		{
			pDC->DrawEdge(rBtn, BDR_RAISEDOUTER, BF_ADJUST | BF_RECT | BF_MIDDLE);
			pDC->DrawEdge(rBtn, BDR_RAISEDINNER, BF_ADJUST | BF_RECT | BF_MIDDLE);
		}
	}

	// drop menu arrow
	if (eb.bDropMenu)
	{
		CRect rArrow(rBtn);
		
		if (bDown)
			rArrow.OffsetRect(1, 1);

		// draw menu arrow
		int nMidY = rArrow.CenterPoint().y;

		// if the button has text then place on the RHS
		// else place centrally
		int nLHS = rArrow.CenterPoint().x - 1;

		if (!eb.sCaption.IsEmpty())
			nLHS = rArrow.right - (bThemed ? 8 : 6);

		POINT ptMenu[3] = 
		{
			{ nLHS, nMidY - MENUSIZE },
			{ nLHS, nMidY + MENUSIZE },
			{ nLHS + MENUSIZE, nMidY }
		};

		pDC->SelectStockObject(NULL_PEN);
		pDC->SelectStockObject(bEnabled ? BLACK_BRUSH : GRAY_BRUSH);
		pDC->Polygon(ptMenu, 3);
	}
	
	CString sCaption(eb.sCaption);

	if (!sCaption.IsEmpty())
	{
		// draw custom caption
		if (m_nButtonDown == nBtn || eb.bChecked)
			rBtn.OffsetRect(1, 1);

		CFont* pOld = NULL;
		
		if (eb.hFont)
			pOld = pDC->SelectObject(CFont::FromHandle(eb.hFont));
		else
		{
			CFont* pFont = GetFont();
			pOld = (CFont*)pDC->SelectObject(pFont);
		}
		
		pDC->SetTextAlign(TA_CENTER | TA_TOP);
		pDC->SetBkMode(TRANSPARENT);
		
		BOOL bEnabled = IsWindowEnabled() && eb.bEnabled;

		int CHAR_HEIGHT = pDC->GetTextExtent("A").cy;

		int nVOffset = (rBtn.Height() - CHAR_HEIGHT + 1) / 2 - 1;
		int nHOffset = (rBtn.Width() + 1) / 2;

		// if the button has a drop menu position the text in the 
		// center of what remains
		if (eb.bDropMenu)
			nHOffset = (rBtn.Width() - MENUSIZE) / 2; 

		CPoint ptText(rBtn.left + nHOffset, rBtn.top + nVOffset);

		if (bEnabled)
		{
			pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));
			pDC->ExtTextOut(ptText.x, ptText.y, 0, rBtn, sCaption, NULL);
		}
		else
		{
			// draw embossed: dark over pale
			ptText.Offset(1, 1);
			pDC->SetTextColor(GetSysColor(COLOR_3DHIGHLIGHT));
			pDC->ExtTextOut(ptText.x, ptText.y, 0, rBtn, sCaption, NULL);

			ptText.Offset(-1, -1);
			pDC->SetTextColor(GetSysColor(COLOR_3DSHADOW));
			pDC->ExtTextOut(ptText.x, ptText.y, 0, rBtn, sCaption, NULL);
		}

		// cleanup
		if (pOld)
			pDC->SelectObject(pOld);
	}
}

#if _MSC_VER >= 1400
LRESULT CEnEdit::OnNcHitTest(CPoint point)
#else
UINT CEnEdit::OnNcHitTest(CPoint point)
#endif
{
	int nBtn = ButtonHitTest(point);

	if (nBtn >= 0)
		return HTBORDER;

	return (LRESULT)CMaskEdit::OnNcHitTest(point);
}

LRESULT CEnEdit::OnHotChange(WPARAM wp, LPARAM lp)
{
	LRESULT lr = Default();

	// wp has prev hot rect index
	// lp has new hot rect index
	ASSERT (((int)wp != -1 || (int)lp != -1) && (int)wp != (int)lp);

	CWindowDC dc(this);
	CPoint ptCursor(::GetMessagePos());

	CRect rWindow;
	GetWindowRect(rWindow);

	if ((int)wp != -1 && m_aButtons[wp].bEnabled)
		DrawButton(&dc, rWindow, wp, ptCursor);

	if ((int)lp != -1 && m_aButtons[lp].bEnabled)
		DrawButton(&dc, rWindow, lp, ptCursor);

	return lr;
}

BOOL CEnEdit::SetButtonWidth(UINT nID, int nWidth)
{
	int nBtn = ButtonHitTest(nID);

	if (nBtn < 0)
		return FALSE;

	if (m_aButtons[nBtn].nWidth != nWidth)
	{
		m_aButtons[nBtn].nWidth = nWidth;

		if (GetSafeHwnd())
		{
			RecalcBtnRects();
			SendMessage(WM_NCPAINT);
		}
	}

	return TRUE;
}

int CEnEdit::GetButtonWidth(int nBtn) const
{
	if (nBtn < 0 || nBtn >= m_aButtons.GetSize() || !GetSafeHwnd())
		return 0;

	const EDITBTN& eb = m_aButtons[nBtn];

	if (eb.nWidth > 0)
		return eb.nWidth;
	
	// else calc
	CWindowDC dc(GetParent());
	CFont* pFont = CFont::FromHandle(eb.hFont ? eb.hFont : (HFONT)GetStockObject(DEFAULT_GUI_FONT));
	CFont* pOldFont = dc.SelectObject(pFont);

	int nWidth = dc.GetTextExtent(eb.sCaption).cx + 6;

	if (eb.bDropMenu)
		nWidth += MENUSIZE + 6;

	// cleanup
	dc.SelectObject(pOldFont);

	return nWidth;
}

BOOL CEnEdit::SetButtonWidthDLU(UINT nID, int nDLU)
{
	ASSERT (GetSafeHwnd());

	return SetButtonWidth(nID, CDlgUnits(*GetTopLevelParent()).ToPixelsX(nDLU));
}

LRESULT CEnEdit::OnSetReadOnly(WPARAM wp, LPARAM /*lp*/)
{
	LRESULT lr = Default();

	OnSetReadOnly((BOOL)wp);
	SendMessage(WM_NCPAINT);

	return lr;
}

void CEnEdit::OnEnable(BOOL bEnable) 
{
	CEdit::OnEnable(bEnable);
	
	SendMessage(WM_NCPAINT);	
}



⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?