一些常规形几何形状的绘制和效果填充(三)
下面以实现钟和旋转文字为例具体讲解CShape的使用方法:
钟由表盘,指针和刻度组成。具体绘图函数在OnPaint()函数里实现,由于刷新较快,而所以绘图都需要计算得到,故要占一定的CPU使用率,避免cpu过高的方法是把不变的部分如表盘,刻度等绘制成一张背景位图,在OnPaint函数里载入背景位图,这样做可大大减低cpu使用率。另外绕一定圆旋转一定角度的文字是一个一个字符计算位置和输出的,顾若输出过多的字符则cpu的使用率也很高,当然可以用位图背景的方法来提高效率。效果图如下:
1.初始化时绘制时钟背景位图
p.DeleteObject();
CDC *pDC=GetDC();
CRect rect;
GetClientRect(&rect);
CPoint pt;
pt.x=500;
pt.y=500;
CBitmap *oldbitmap;
p.CreateCompatibleBitmap(pDC, rect.Width(),
rect.Height());//生成空间的内存位图
CDC me;
me.CreateCompatibleDC(pDC);//生成内存cd
oldbitmap=me.SelectObject(&p);
CBrush *oldbrush,b(RGB(120,0,0));
oldbrush=me.SelectObject(&b);
CPen *oldpen,pen(0,2,RGB(0*rand()/RAND_MAX,0,255));
oldpen=me.SelectObject(&pen);
CShape shap;
pt.x=400;
pt.y=300;
shap.DrawConeGradientCenterToSide
(&me,pt,200,130,0,360,RGB(0,0,255),RGB(0,0,0));
shap.DrawConeGradientSideToSide
(&me,pt,120,0,0,360,RGB(255,255,0),RGB(0,0,0));
shap.DrawConeGradientSideToSide
(&me,pt,100,50,45,90,RGB(120,111,200),RGB(0,0,0));
for ( int i=0;i<12*5;i++)
{
shap.DrawLine_CenterPoint_Len_Angle
(&me,pt,162,175,RGB(120,111,200),i*6,2);
}
for ( i=0;i<12;i++)
{
shap.DrawLine_CenterPoint_Len_Angle
(&me,pt,160,180,RGB(0,255,0),i*30,5);
}
b.DeleteObject();
b.CreateSolidBrush(RGB(0,255,0));
oldbrush=me.SelectObject(&b);
me.SelectObject(oldbrush);
b.DeleteObject();
b.CreateSolidBrush(RGB(0,0,255));
oldbrush=me.SelectObject(&b);
me.SelectObject(oldbrush);
CString str;
me.SelectObject(oldbrush);
me.SelectObject(oldpen);
me.SetROP2(R2_WHITE);
pDC->BitBlt(0, 0, rect.Width(), rect.Height(),
& me, 0, 0, SRCCOPY);
me.SelectObject(oldbitmap);
me.DeleteDC();
pDC->DeleteDC();
2.钟的实现
CDC *pDC=GetDC();
CFont *oldfont;
double h,m,s;
FormatTime(m,h,s);
//从当前时间里获得时针,分针,秒针的角度h,m和s
CRect rect;
GetClientRect(&rect);
CPoint pt;//时钟中心
pt.x=500;
pt.y=500;
CBitmap bitmap;
CBitmap *oldbitmap;
bitmap.CreateCompatibleBitmap(pDC, rect.Width(),
rect.Height());
//生成空间的内存位图
CDC me;
me.CreateCompatibleDC(pDC);//生成内存cd
oldbitmap=me.SelectObject(&bitmap);//载入背景位图
CBrush *oldbrush,b(&p);
oldbrush=me.SelectObject(&b);
me.FillRect(rect,&b);//绘制背景
me.SelectObject(oldbrush);
CPen *oldpen,pen(0,2,RGB(0,0,255));
oldpen=me.SelectObject(&pen);
CShape shap;
pt.x=400;
pt.y=300;
b.DeleteObject();
b.CreateSolidBrush(RGB(0,255,0));
oldbrush=me.SelectObject(&b);
me.SelectObject(oldbrush);
//////////画分针,颜色为绿色渐变到黑色
shap.DrawDiamondGradient(&me,pt,190,40,m,RGB
(0,255,0),RGB(0,0,0),TOP_MIDDLE_BOTTOM,.8);
me.SetTextColor(RGB(0,255,0));
me.SetBkMode(TRANSPARENT);
CTime t=CTime::GetCurrentTime();
me.TextOut(370,220,t.Format("%H:%M:%S"));
//////////画时针,
shap.DrawDiamondGradient(&me,pt,120,35,h,RGB
(120,111,200),
RGB(0,0,0),TOP_MIDDLE_BOTTOM,.8);
//////////画秒针,颜色为绿色渐变到黑色
shap.DrawDiamondGradient(&me,pt,225,20,s,RGB
(255,0,0),
RGB(0,0,0),TOP_MIDDLE_BOTTOM,.7);
me.SelectObject(oldbrush);
//画螺丝
shap.DrawPoint(&me,pt,RGB(0,0,255),6);
shap.DrawPoint(&me,pt,RGB(255,255,255),3);
static double angg=s;//外围中文汉字旋转角度
angg=angg+0.5;
shap.SetFontWide(50);//设置文字宽度和高度
shap.SwtFontHeight(60);
/////输出非中文字符 shap.DrawCircleABCText
(&me,pt,255,angg,"[email protected]",RGB
(0,255,0),10,FONT_CLOCKWISE);
shap.SetFontWide(30);
shap.SwtFontHeight(40);
//////输出中文字符
shap.DrawCircleChineseText(&me,pt,300,-angg,
"南京航空航天大学能源与动力学院",
RGB(0,0,255),10,FONT_CLOCKWISE);
me.SelectObject(oldbrush);
me.SelectObject(oldpen);
me.SetROP2(R2_WHITE);
pDC->BitBlt(0, 0, rect.Width(), rect.Height(),
& me, 0, 0, SRCCOPY);
me.SelectObject(oldbitmap);
bitmap.DeleteObject();
me.DeleteDC();
pDC->DeleteDC();
实现总体效果如下:
总结:
CShape类可实现常规的几何图形的绘制和效果填充,但是能实现的几何图形的种类是有限的,但是可根据类似的原理添加不同的几何图形。填充效果也仅限于有限的几种,前些天看到一个仪表程序的介绍,它所实现的玻璃效果特别好看,但是没有源码。我还不知道如何实现玻璃效果,还有待于研究。
在实现各种效果时,对于这些要定时刷新的函数来说,一定不能让内存泄露,所以我在编写每一个函数时特别注意。所以每实现一个效果,就一定要检查一下也没有内存泄露。到目前还未发现内存有泄露。祝大家学习进步!