正在自绘一个ListViewCtrl控件,ListItem需要一个AutoHideCloseBtn,用到了一点数学计算,感觉有点意思 :)
先贴上按钮效果:
一点数学分析
示意图:
其中左上角的点的坐标(圆心坐标为(x0, y0), 半径为r0):
其他点类似推出,主要是正方形太特殊了,都是45°,所以特别的简单。
最终的按钮效果:
附录1 关闭按钮绘制相关代码:
void DrawSkyRoundEarthSquare(Graphics& g)
{
Color oColor(97, 102, 114);
SolidBrush oBkBrush(oColor); //(97,102,114)
Rect rcBtn;
rcBtn.X = 100;
rcBtn.Y = 100;
rcBtn.Width = 50;
rcBtn.Height = 50;
g.FillEllipse(&oBkBrush, rcBtn);
Pen oWhitePen(Color::White, 1.7F);
double x0 = rcBtn.X + rcBtn.Width / 2.0;
double y0 = rcBtn.Y + rcBtn.Height / 2.0;
double r0 = rcBtn.Width / 2.0;
PointF pt1;
pt1.X = x0 - sqrt(2.0) / 2.0 * r0 + 1.0; //(x0-sqrt(2)/2*r0, y0-sqrt(2)/2*r0) (x0,y0)为圆心 r0为半径 1.0为padding
pt1.Y = y0 - sqrt(2.0) / 2.0 * r0 + 1.0;
PointF pt2;
pt2.X = x0 + sqrt(2.0) / 2.0 * r0 - 1.0;
pt2.Y = y0 + sqrt(2.0) / 2.0 * r0 - 1.0;
g.DrawLine(&oWhitePen, pt1, pt2);
//pt1.X = x0 - sqrt(2.0) / 2.0 * r0;
pt1.Y = y0 + sqrt(2.0) / 2.0 * r0 - 1.0;
pt2.Y = y0 - sqrt(2.0) / 2.0 * r0 + 1.0;
g.DrawLine(&oWhitePen, pt1, pt2);
}
附录2 数学分析图的简单代码:
void DrawSkyRoundEarthSquare2(Graphics& g)
{
RectF oRect;
oRect.X = 200.0f;
oRect.Y = 200.0f;
oRect.Width = 200.0f;
oRect.Height = 200.0f;
//draw bkground
SolidBrush oBkBrush(Color::Gray);
g.FillRectangle(&oBkBrush, oRect);
//"□" and "〇"
Pen oWirePen(Color::Blue);
g.DrawRectangle(&oWirePen, oRect);
Pen oArcPen(Color::Magenta);
g.DrawEllipse(&oArcPen, oRect); // 90-->0 绘不出来(DrawArc()第二个参数是跨度!!逆时针)
//init "+" line points
PointF oPt1;
oPt1.X = oRect.X;
oPt1.Y = oRect.Y + oRect.Height / 2.0f;
PointF oPt2;
oPt2.X = oRect.X + oRect.Width;
oPt2.Y = oPt1.Y;
PointF oPt3;
oPt3.X = oRect.X + oRect.Width / 2.0f;
oPt3.Y = oRect.Y;
PointF oPt4;
oPt4.X = oPt3.X;
oPt4.Y = oRect.Y + oRect.Height;
g.DrawLine(&oWirePen, oPt1, oPt2);
g.DrawLine(&oWirePen, oPt3, oPt4);
//init "×" line points
PointF ptCenter;
ptCenter.X = oRect.X + oRect.Width / 2.0f;
ptCenter.Y = oRect.Y + oRect.Height / 2.0f;
REAL r0 = oRect.Width / 2.0f; //radius
PointF ptLeft;
ptLeft.X = ptCenter.X - sqrt(2.0) / 2.0f * r0;
ptLeft.Y = ptCenter.Y - sqrt(2.0) / 2.0f * r0;
PointF ptRight;
ptRight.X = ptCenter.X + sqrt(2.0) / 2.0f * r0;
ptRight.Y = ptCenter.Y + sqrt(2.0) / 2.0f * r0;
Pen oSpecPen(Color::Red);
g.DrawLine(&oSpecPen, ptLeft, ptRight);
ptLeft.Y = ptCenter.Y + sqrt(2.0) / 2.0f * r0;
ptRight.Y = ptCenter.Y - sqrt(2.0) / 2.0f * r0;
g.DrawLine(&oSpecPen, ptLeft, ptRight);
}