📄 rotatebutton.cpp
字号:
lError -= --lXoffset * 2;
} while (lYoffset <= lXoffset); //Continue until halfway point
}
/////////////////////////////////////////////////////////////////////////////
// CRotateButton
CRotateButton::CRotateButton()
{
m_bDrawDashedFocusCircle = TRUE;
m_bLighted = FALSE;
m_nAngle = 0;
m_bCapture = FALSE;
m_dbMin = 0.0;
m_dbMax = 1.0;
}
CRotateButton::~CRotateButton()
{
m_rgn.DeleteObject();
}
BEGIN_MESSAGE_MAP(CRotateButton, CButton)
//{{AFX_MSG_MAP(CRotateButton)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRotateButton message handlers
void CRotateButton::PreSubclassWindow()
{
CButton::PreSubclassWindow();
ModifyStyle(0, BS_OWNERDRAW);
CRect rect;
GetClientRect(rect);
// Resize the window to make it square
rect.bottom = rect.right = min(rect.bottom,rect.right);
// Get the vital statistics of the window
m_ptCentre = rect.CenterPoint();
m_nRadius = rect.bottom/2-1;
// Set the window region so mouse clicks only activate the round section
// of the button
m_rgn.DeleteObject();
SetWindowRgn(NULL, FALSE);
m_rgn.CreateEllipticRgnIndirect(rect);
SetWindowRgn(m_rgn, TRUE);
// Convert client coords to the parents client coords
ClientToScreen(rect);
CWnd* pParent = GetParent();
if (pParent) pParent->ScreenToClient(rect);
// Resize the window
MoveWindow(rect.left, rect.top, rect.Width(), rect.Height(), TRUE);
}
void CRotateButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct != NULL);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
UINT state = lpDrawItemStruct->itemState;
UINT nStyle = GetStyle();
int nRadius = m_nRadius;
int nSavedDC = pDC->SaveDC();
pDC->SelectStockObject(NULL_BRUSH);
CBrush brush, *pBrush;
brush.CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));
pBrush = pDC->SelectObject(&brush);
pDC->Ellipse(rect);
brush.DeleteObject();
brush.CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));
pDC->SelectObject(&brush);
// pDC->Ellipse(rect.left + 5, rect.top + 5, rect.right - 5, rect.bottom - 5);
pDC->SelectObject(pBrush);
// Draw the focus circle around the button
//绘制有焦点时的外圆
if(m_bCapture)
{
if ((state & ODS_FOCUS) && m_bDrawDashedFocusCircle)
DrawCircle(pDC, m_ptCentre, nRadius--, RGB(0,0,255));
nRadius -= 20;
}
// Draw the raised/sunken edges of the button (unless flat)
if (nStyle & BS_FLAT)
{
// DrawCircle(pDC, m_ptCentre, nRadius--, RGB(0,0,0));
// DrawCircle(pDC, m_ptCentre, nRadius--, ::GetSysColor(COLOR_3DHIGHLIGHT));
}
else
{
if ((state & ODS_SELECTED))
{
DrawCircle(pDC, m_ptCentre, nRadius--,
::GetSysColor(COLOR_3DDKSHADOW), ::GetSysColor(COLOR_3DHIGHLIGHT));
DrawCircle(pDC, m_ptCentre, nRadius--,
::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DLIGHT));
DrawCircle(pDC, m_ptCentre, nRadius--,
::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DLIGHT));
DrawCircle(pDC, m_ptCentre, nRadius--,
::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DLIGHT));
}
else
{
DrawCircle(pDC, m_ptCentre, nRadius--,
::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
DrawCircle(pDC, m_ptCentre, nRadius--,
::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));
DrawCircle(pDC, m_ptCentre, nRadius--,
::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));
DrawCircle(pDC, m_ptCentre, nRadius--,
::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));
}
}
DrawText(pDC, state);
// Draw the focus circle on the inside of the button
if ((state & ODS_FOCUS) && m_bDrawDashedFocusCircle)
// DrawCircle(pDC, m_ptCentre, nRadius-2, RGB(0,0,0), TRUE);
pDC->RestoreDC(nSavedDC);
}
void CRotateButton::SetLighted(BOOL b)
{
m_bLighted = b;
Invalidate();
}
void CRotateButton::DrawText(CDC *pDC, UINT state)
{
// draw the text if there is any
CString strText;
GetWindowText(strText);
CString s;
s.Format("%2.1f", GetData());
if (m_bCapture)
strText = s;
else
strText += s;
if (!strText.IsEmpty())
{
CRgn rgn;
rgn.CreateEllipticRgn(m_ptCentre.x-m_nRadius, m_ptCentre.y-m_nRadius,
m_ptCentre.x+m_nRadius, m_ptCentre.y+m_nRadius);
pDC->SelectClipRgn(&rgn);
CSize Extent = pDC->GetTextExtent(strText);
CPoint pt = CPoint( m_ptCentre.x - Extent.cx/2, m_ptCentre.x - Extent.cy/2 );
if (state & ODS_SELECTED) pt.Offset(1,1);
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,0,0));
if (state & ODS_DISABLED)
pDC->DrawState(pt, Extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
else
pDC->TextOut(pt.x, pt.y, strText);
pDC->SelectClipRgn(NULL);
rgn.DeleteObject();
}
}
void CRotateButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_bCapture = TRUE;
m_nAngle = GetAngle(point, m_ptCentre);
SetCapture();
CButton::OnLButtonDown(nFlags, point);
}
void CRotateButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (m_bCapture)
{
m_nAngle = GetAngle(point, m_ptCentre);
// InvalidateRgn(&m_rgn, FALSE);
Invalidate(FALSE);
}
CButton::OnMouseMove(nFlags, point);
}
int CRotateButton::GetAngle(CPoint ptCur, CPoint ptCenter)
{
CPoint pt = ptCur - ptCenter;
pt.y = -pt.y;
//取得tan值
double diff;
if(pt.x == 0 && pt.y ==0)
{
diff = 0.0;return int(diff);
}
else if(pt.x == 0 && pt.y > 0)
{
diff = 0.0;return int(diff);
}
else if(pt.x > 0 && pt.y ==0)
{
diff = 90;return int(diff);
}
else if(pt.x == 0 && pt.y < 0)
{
diff = 180;return int(diff);
}
else if(pt.x < 0 && pt.y == 0)
{
diff = 270;return int(diff);
}
diff = atan2(pt.y, pt.x);
diff = diff * 180 / 3.14;
//如果在第二象限,则用180-d1得到正确的度数
//如果在第三象限,则用-180-d1得到正确的度数
if (pt.x > 0 && pt.y > 0)
diff = 90 - diff;
else if (pt.x<0 && pt.y >0)
diff = 360 - diff + 90;
else if(pt.x<0 && pt.y<0)
diff = 180 - (diff + 90);
else if(pt.x > 0 && pt.y < 0)
diff = 90 - diff;
return int(diff);
}
void CRotateButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_bCapture = FALSE;
CButton::OnLButtonUp(nFlags, point);
}
void CRotateButton::SetRange(double min, double max)
{
ASSERT(max > min);
m_dbMin = min;
m_dbMax = max;
}
double CRotateButton::GetData()
{
return double(m_dbMin+(m_nAngle)*(m_dbMax - m_dbMin)/360.0);
}
void CRotateButton::SetData(double data)
{
m_nAngle = int((data-m_dbMin) * 360.0 / (m_dbMax - m_dbMin));
Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -