工序打扎流程(箭头实现、刷新画面)

三、箭头实现。


/////////////////////
//画箭头封装调用函数实现
void CButtonTestDlg::ArrowTo(
CDC *pDC,              //画刷
CPoint point,          //终点坐标
int nPenStyle,          //线样式
int nPenWidth,          //线宽度
COLORREF color, //颜色
int nWidth,            //三角形底边宽度
float fTheta,          //三角形顶角角度
bool bFill              //是否填充颜色
)
{
CPen* pOldPen;
CPen pen(nPenStyle,nPenWidth,color);
pOldPen = pDC->SelectObject(&pen);

CBrush br,*pbrOld;
br.CreateSolidBrush(color);
pbrOld = pDC->SelectObject(&br);

//开始绘图
POINT pFrom;
POINT pBase;
POINT aptPoly[3];
float vecLine[2];
float vecLeft[2];
float fLength;
float th;
float ta;

// get from point
MoveToEx(*pDC, 0, 0, &pFrom);

// set to point
aptPoly[0].x = point.x;
aptPoly[0].y = point.y;

// build the line vector
vecLine[0] = (float) aptPoly[0].x - pFrom.x;
vecLine[1] = (float) aptPoly[0].y - pFrom.y;

// build the arrow base vector - normal to the line
vecLeft[0] = -vecLine[1];
vecLeft[1] = vecLine[0];

// setup length parameters
fLength = (float) sqrt(vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1]);
if (fLength < 0.1)
{
fLength = 0.1f;
}
th = nWidth / (2.0f * fLength);
ta = nWidth / (2.0f * (tanf(fTheta) / 2.0f) * fLength);

// find the base of the arrow
pBase.x = (int) (aptPoly[0].x + -ta * vecLine[0]);
pBase.y = (int) (aptPoly[0].y + -ta * vecLine[1]);

// build the points on the sides of the arrow
aptPoly[1].x = (int) (pBase.x + th * vecLeft[0]);
aptPoly[1].y = (int) (pBase.y + th * vecLeft[1]);
aptPoly[2].x = (int) (pBase.x + -th * vecLeft[0]);
aptPoly[2].y = (int) (pBase.y + -th * vecLeft[1]);

MoveToEx(*pDC, pFrom.x, pFrom.y, NULL);

// draw we're fillin'...
if(bFill) {
LineTo(*pDC, aptPoly[0].x, aptPoly[0].y);
Polygon(*pDC, aptPoly, 3); //画实体三角形
}
// ... or even jes chillin'...
else
{
LineTo(*pDC, pBase.x, pBase.y);
LineTo(*pDC, aptPoly[1].x, aptPoly[1].y);
LineTo(*pDC, aptPoly[0].x, aptPoly[0].y);
LineTo(*pDC, aptPoly[2].x, aptPoly[2].y);
LineTo(*pDC, pBase.x, pBase.y);
MoveToEx(*pDC, aptPoly[0].x, aptPoly[0].y, NULL);
}
//结束绘图

pDC->SelectObject(pOldPen);
pDC->SelectObject(pbrOld);
}

////////////////////////调用:
dc.MoveTo(points[0].x,points[0].y);
ArrowTo(&dc,points[1],PS_SOLID,1,RGB(0,0,0),10,45,false);


二、刷新画面。

DIALOG 属性:clip children 设置为true。意思是在绘制对话框时剪辑子窗口,
也就是在调用Invalidate();的时候,不会重绘子窗口。可以保证在Invalidate();的时候,界面不会闪。

void CButtonTestDlg::OnPaint()
{
if (IsIconic())
{
///....
}
else
{
Invalidate();//必须先Invalidate,后CPaintDC dc(this);
CPaintDC dc(this); // 用于绘制的设备上下文

CPoint points[2];
GetLinePoints((RFMSStepButton*)GetDlgItem(124),(RFMSStepButton*)GetDlgItem(125),points);

dc.MoveTo(points[0].x,points[0].y);
ArrowTo(&dc,points[1],PS_SOLID,1,RGB(0,0,0),10,45,false);

GetLinePoints((RFMSStepButton*)GetDlgItem(123),(RFMSStepButton*)GetDlgItem(125),points);
dc.MoveTo(points[0].x,points[0].y);
ArrowTo(&dc,points[1],PS_SOLID,1,RGB(0,0,0),10,45,true);

CDialog::OnPaint();
}
}

原文地址:https://www.cnblogs.com/aoyihuashao/p/1623714.html