当前位置:C++技术网 > 资讯 > GDI+实现自定义画笔的线帽及画笔的深入理解

GDI+实现自定义画笔的线帽及画笔的深入理解

更新时间:2016-01-06 17:15:25浏览次数:1+次

画笔的线帽除了系统为我们设定之外,开发人员还可以通过编程来自定义画笔的线帽,这里谈谈如何自定义线帽。
自定义线帽是用户自己绘制出来的线帽的外观。GDI+用CustomLineCap类来自定义线帽,该类的构造函数:
CustomLineCap(const Graphics* fillPath,const Graphics* strokePath,LineCap baseCap,REAL baseInset);
在上述的构造函数中,开发者用一个包含有线帽外观的路径创建一个自定义线帽。使用SetCustomStartCap和SetCustomEndPath两个函数可以将由CustomLineCap函数创建的自定义线帽与画笔相关联。

需要说明的是,无论是使用系统提供的默认线帽,还是自定义线帽,只要将这些线帽的属性赋予画笔,线帽就是画笔的一部分,对画笔属性的任何设置都会使得线帽与画笔的外观同步改变。 

对于系统为我们准备好的,请看《GDI+学习记录5》。下面我们看看自定义的:

Graphics graphics(this->m_hWnd);
	//Pen pen(Color::Blue,8);
	//pen.SetEndCap(LineCapArrowAnchor);
	//graphics.DrawLine(&pen,Point(0,0),Point(30,30));
	GraphicsPath StartPath,EndPath;
	/////在路径中添加一个矩形
	StartPath.AddRectangle(Rect(-10,-5,20,10));
	/////构造结束点线帽的外观:箭头
	EndPath.AddLine(0,-20,10,0);
	EndPath.AddLine(0,-20,-10,0);
	EndPath.AddLine(0,-10,10,0);
	EndPath.AddLine(0,-10,-10,0);

	Rect rect(10,-5,20,10);
	Pen pen(Color(255,0,0,255),2);
	/////将路径作为线帽外观
	CustomLineCap custCap(NULL,&StartPath);
	CustomLineCap EndCap(NULL,&EndPath);
	////设置画笔起点,终点的自定义线帽
	pen.SetCustomStartCap(&custCap);
	pen.SetCustomEndCap(&EndCap);
	graphics.DrawLine(&pen,20,30,300,30);
	/////以点(300.300)为圆心绘制直线
	for(float i=0; i<6.28; i+=0.15)
	{
		graphics.DrawLine(&pen,Point(300,300),Point(300+200*cos(i),300+200*sin(i)));
	}
代码是实现:

在进行GDI+编程绘图的时候,对于某些已预定义好的区域信息,我们可以很简单的进行绘图。但是,在待填充区域未知的情况下,应该如何定制需要填充的区域?GDI+中提供的"图形路径对象"(GraphicsPath)可以很好的简化对这个问题的处理,在使用GraphicsPath时,所有的绘图操作都是在这个路径中进行的,直到使用FillPath类的函数之后,原来在路径中绘制的图形在绘图平面才变得可见。

我们用代码写一个"正叶曲线"验证路径的概念:

void CGDIView::OnGdi8()
{
	// TODO: 在此添加命令处理程序代码
	this->RedrawWindow();
	Graphics graphics(this->m_hWnd);
	///创建绿色的画刷
	SolidBrush greenbrush(Color(255,0,255,0));
	int cx,cy;
	CRect rect;
	this->GetClientRect(&rect);
	///以当前窗口的中心点绘制正叶曲线
	cx=rect.Width()/2;
	cy=rect.Height()/2;
	///设置"叶"长
	int LeafLength=100;
	///设置叶片的数量
	int LeafNum=5;
	float PI=3.14;
	int x2,y2;
	int x,y,r;
	/////创建一个图片路径对象,用来容纳正叶曲线
	GraphicsPath tmpPath(FillModeAlternate);
	///////生成曲线边界数据:角度变化为一周PI*2
	for(float i=0.0f; i<PI*2+0.1; i+=PI/180)
	{
		r=abs(LeafLength*cos(LeafNum * i));
		x=r*cos(i);
		y=r*sin(i);
		x2=cx+x;
		y2=cy+y;
		//将曲线的边界信息驯如临时路径,如果想要查看这些信息所构成的区域
		///可以在此处加入graphics.DrawLine(&pen,x2,y2,x2-1,y2-1)
		tmpPath.AddLine(x2,y2,x2,y2);
	}
	//填充路径
	graphics.FillPath(&greenbrush,&tmpPath);
	//绘制中心坐标轴
	Pen pen(Color::Gray,3);
	graphics.DrawLine(&pen,0,cy,cx*2,cy);
	graphics.DrawLine(&pen,cx,0,cx,cy*2);
}