可以改变三角形大小,顶点角度,是否填充和填充颜色等
但是画出的箭头还是不够美观....呵呵,还好吧
其中填充是代表箭头内是否填充颜色
先来看声明和实现
-
//使用一个结构体来存储相关的信息
-
//Defines the attributes of an arrow.
-
typedef struct tARROWSTRUCT {
-
int nWidth; // width (in pixels) of the full base of the arrowhead
-
float fTheta; // angle (in radians) at the arrow tip between the two
-
// sides of the arrowhead
-
bool bFill; // flag indicating whether or not the arrowhead should be
-
// filled
-
} ARROWSTRUCT;
-
-
///
-
//函数声明
-
// Draws an arrow, using the current pen and brush, from the current position
-
// to the passed point using the attributes defined in the ARROWSTRUCT.
-
void ArrowTo (HDC hDC, int x, int y, ARROWSTRUCT *pArrow );
-
void ArrowTo (HDC hDC, const POINT *lpTo, ARROWSTRUCT *pArrow );
-
-
///
-
//画箭头函数实现
-
void CMyDialog:: ArrowTo (HDC hDC, int x, int y, ARROWSTRUCT *pA ) {
-
-
POINT ptTo = {x, y };
-
-
ArrowTo (hDC, &ptTo, pA );
-
}
-
-
void CMyDialog:: ArrowTo (HDC hDC, const POINT *lpTo, ARROWSTRUCT *pA ) {
-
-
POINT pFrom;
-
POINT pBase;
-
POINT aptPoly [ 3 ];
-
float vecLine [ 2 ];
-
float vecLeft [ 2 ];
-
float fLength;
-
float th;
-
float ta;
-
-
// get from point
-
MoveToEx (hDC, 0, 0, &pFrom );
-
-
// set to point
-
aptPoly [ 0 ]. x = lpTo->x;
-
aptPoly [ 0 ]. y = lpTo->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 ] );
-
th = pA->nWidth / ( 2.0f * fLength );
-
ta = pA->nWidth / ( 2.0f * (tanf (pA->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 (hDC, pFrom. x, pFrom. y, NULL );
-
-
// draw we're fillin'...
-
if (pA->bFill ) {
-
LineTo (hDC, aptPoly [ 0 ]. x, aptPoly [ 0 ]. y );
-
Polygon (hDC, aptPoly, 3 );
-
}
-
-
// ... or even jes chillin'...
-
else {
-
LineTo (hDC, pBase. x, pBase. y );
-
LineTo (hDC, aptPoly [ 1 ]. x, aptPoly [ 1 ]. y );
-
LineTo (hDC, aptPoly [ 0 ]. x, aptPoly [ 0 ]. y );
-
LineTo (hDC, aptPoly [ 2 ]. x, aptPoly [ 2 ]. y );
-
LineTo (hDC, pBase. x, pBase. y );
-
MoveToEx (hDC, aptPoly [ 0 ]. x, aptPoly [ 0 ]. y, NULL );
-
}
-
}
再来看调用实现(加一层封装更加适用)
-
/
-
//封装调用函数实现(其实还是有很大的扩展空间的)
-
void CMyDialog:: ArrowTo (
-
CDC *pDC, //画刷
-
CPoint point, //终点坐标
-
int nPenStyle, //线样式
-
int nPenWidth, //线宽度
-
COLORREF color, //颜色
-
int nWidth, //三角形底边宽度
-
float fTheta, //三角形顶角角度
-
bool bFill //是否填充颜色
-
)
-
{
-
ARROWSTRUCT a;
-
a. nWidth = nWidth; //三角形底边宽度
-
a. fTheta = fTheta; //三角形顶角角度
-
a. bFill = bFill; //是否填充颜色
-
-
CPen* pOldPen;
-
CPen pen (nPenStyle,nPenWidth,color );
-
pOldPen = pDC->SelectObject (&pen );
-
-
CBrush br,*pbrOld;
-
br. CreateSolidBrush (color );
-
pbrOld = pDC->SelectObject (&br );
-
-
ArrowTo (*pDC,point. x,point. y,&a ); //调用画箭头函数
-
-
pDC->SelectObject (pOldPen );
-
pDC->SelectObject (pbrOld );
-
}