MFC 实现圆形进度图以及一些其他图形绘画

可能一些皮肤库也可以实现这种功能,已经破解出来的皮肤库,我是没有找到这种功能,所以在闲暇时间来研究研究一些绘画、绘图
在这里使用到了GDI+绘图,所有程序需要先加载GDI+。不会加载GDI+的朋友可以在我的博客中找一下,我有写过这方面。

在头文件中定义一些公共变量,最好在类构造函数中初始化一下。

CRect   m_clrRect;      ///显示进度条进度
CRect   m_clrRectPercent; ///显示进度条百分比
CString m_StrPercentage;
CPoint  m_ArcPoint[3];

REAL m_StartAngle ; // 设置起点角度为60度  以圆心水平线顺时针60 半径 R 地方开始画圆弧
REAL m_SweepAngle ; // 设置旋转角度为150度 如果旋转360则是圆,如果为负数则逆势针开始画圆弧
void CXXX::OnPaint()
{
    CPaintDC dc(this); // device context for painting

    CRect rc;
    GetClientRect(&rc);
    // Do not call CDialog::OnPaint() for painting messages
    CDC             MemDC;  ///首先定义一个显示设备对象
    CBitmap     MemBmp;     ///定义一个位图对象
    CDC *pDC=GetDC();
    ///随后建立与屏幕显示兼容的内存显示设备
    MemDC.CreateCompatibleDC(pDC);
    ///这时还不能绘图,因为没有地方画
    ///下面建立一个与屏幕显示兼容的位图,至于位图的大小,可以用窗口的大小,也可以自定义
    MemBmp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());

    ///将位图选入到内存显示设备中
    ///只有选入位图的内存显示设备才有地方绘图,画到指定的位图上
    CBitmap *pOldBit = MemDC.SelectObject(&MemBmp);

    //绘图,接下来所有的图片、点、线、圆、文字都要绘制在这个上面
    ///划线
    MemDC.MoveTo(CPoint(0, 28));///移动开始坐标到 (0, 28) 位置
    MemDC.LineTo(CPoint(800, 28));

    // 画矩形
    pDC->Rectangle(0, 0, 20, 20);

    // 画箭头
    pDC->MoveTo(93,55);
    pDC->LineTo(136,55);
    pDC->MoveTo(140,55);
    pDC->LineTo(130,51);
    pDC->MoveTo(140,55);
    pDC->LineTo(130,59);

    // 画圆
    pDC->Ellipse(20, 0, 40, 20);

    ///Gdi+ 画圆
    Gdiplus::Graphics gdiplusdc(dc.GetSafeHdc());
    CRect m_rcWindow(0, 60, 128, 188);
    COLORREF m_crOuterClr=RGB(255,0,0);  
    COLORREF m_crInnerClr=RGB(0,255,0);
    CSize m_sizeInnerPos=CSize(20,20);

    gdiplusdc.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);//抗锯齿
    //外圆  
    Gdiplus::Pen pen(Gdiplus::Color(255, GetRValue(m_crOuterClr), GetGValue(m_crOuterClr), GetBValue(m_crOuterClr)));  
    gdiplusdc.DrawEllipse(&pen, m_rcWindow.left, m_rcWindow.top, m_rcWindow.Width(), m_rcWindow.Height());  

    Gdiplus::SolidBrush brush(Gdiplus::Color(255, GetRValue(m_crOuterClr), GetGValue(m_crOuterClr), GetBValue(m_crOuterClr)));  
    gdiplusdc.FillEllipse(&brush, m_rcWindow.left, m_rcWindow.top, m_rcWindow.Width(), m_rcWindow.Height());  

    //内圆  
    Gdiplus::SolidBrush brush2(Gdiplus::Color(255, GetRValue(m_crInnerClr), GetGValue(m_crInnerClr), GetBValue(m_crInnerClr)));  
    gdiplusdc.FillEllipse(&brush2,   
        m_rcWindow.left+m_sizeInnerPos.cx,   
        m_rcWindow.top+m_sizeInnerPos.cy,   
        m_rcWindow.Width() - m_sizeInnerPos.cx*2,   
        m_rcWindow.Height() - m_sizeInnerPos.cy*2);

    ///gdi+ 画扇形 画圆环 创建宽 Pen 实现动态进度显示
    m_rcWindow = CRect(140, 60, 258, 180);
    m_crOuterClr=RGB(255,0,0);
    m_crInnerClr=RGB(0,255,0);
    m_sizeInnerPos=CSize(10,10);

    //圆弧
    Gdiplus::Pen pen2(Gdiplus::Color(255, GetRValue(m_crOuterClr), GetGValue(m_crOuterClr), GetBValue(m_crOuterClr)), 16.0f);
    Rect ellipseRect(m_rcWindow.left, m_rcWindow.top, m_rcWindow.Width(), m_rcWindow.Height()); ///规定圆弧所在外切矩形大小 x, y width, height
    gdiplusdc.DrawArc(&pen2, ellipseRect, m_StartAngle, m_SweepAngle);

    //内圆
    brush2=Gdiplus::SolidBrush(Gdiplus::Color(255, GetRValue(m_crInnerClr), GetGValue(m_crInnerClr), GetBValue(m_crInnerClr)));  
    gdiplusdc.FillEllipse(&brush2,   
        m_rcWindow.left+m_sizeInnerPos.cx,   
        m_rcWindow.top+m_sizeInnerPos.cy,   
        m_rcWindow.Width() - m_sizeInnerPos.cx*2,   
        m_rcWindow.Height() - m_sizeInnerPos.cy*2);

    // 画箭头
    pDC->MoveTo(219,55);
    pDC->LineTo(262,55);
    pDC->MoveTo(266,55);
    pDC->LineTo(256,51);
    pDC->MoveTo(266,55);
    pDC->LineTo(256,59);

    // 动态绘制三角形
//  pDC->MoveTo(m_ArcPoint[0]);
//  pDC->LineTo(m_ArcPoint[1]);
//  pDC->LineTo(m_ArcPoint[2]);

    ////////////////////////////////////////////////////////////////////////// 画字
    CRect m_PercentRect(m_rcWindow.left+m_sizeInnerPos.cx,   
        m_rcWindow.top+m_sizeInnerPos.cy,   
        m_rcWindow.Width() - m_sizeInnerPos.cx*2,   
        m_rcWindow.Height() - m_sizeInnerPos.cy*2);

    CFont* pOldFont = MemDC.SelectObject(myFont);
    MemDC.SetBkMode(TRANSPARENT);
    CPen cpen(PS_SOLID, 1, RGB(255,0,0));
    CPen *pOldPen=MemDC.SelectObject(&cpen);
    //MemDC.TextOut(m_TimeRect.left, m_TimeRect.top,m_sTimeValue);
    SetBkMode(MemDC.m_hDC, TRANSPARENT);
    DrawText(MemDC.m_hDC, m_StrPercentage, -1, &m_rcWindow, DT_VCENTER);
    MemDC.SelectObject(pOldFont);
    MemDC.SelectObject(pOldPen);

    ///将内存中的图拷贝到屏幕上进行显示
    pDC->BitBlt(m_rcWindow.left, m_rcWindow.top, m_PercentRect.Width(), m_PercentRect.Height(), &MemDC, 0, 0, SRCCOPY);

    ///绘图完成后的清理
    MemBmp.DeleteObject();
    MemDC.DeleteDC();
    gdiplusdc.ReleaseHDC(pDC->m_hDC);

    ReleaseDC( pDC);
    pDC=NULL;
}

重载OnTimer

void CMyProgressCtrl2::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: Add your message handler code here and/or call default

    m_clrRect.right+=1;
    GetDlgItem(IDC_STATIC_Progress2)->MoveWindow(m_clrRect);

    m_clrRectPercent.right +=1;
    m_clrRectPercent.left+=1;

    m_StrPercentage.Format(_T("%d"), m_clrRect.right);
    GetDlgItem(IDC_STATIC_Percentage)->SetWindowText(m_StrPercentage);
    GetDlgItem(IDC_STATIC_Percentage)->MoveWindow(m_clrRectPercent);

    m_SweepAngle +=0.45;

    m_ArcPoint[0].x+=1;
    m_ArcPoint[1].x+=1;
    m_ArcPoint[2].x+=1;

    Invalidate( FALSE);
    //InvalidateRect(m_clrRect, FALSE);
    UpdateWindow();
    if (m_clrRect.right >= 800)
    {
        m_clrRectPercent.right = 800;
        m_clrRectPercent.left =750;
        m_StrPercentage=(_T("完成"));
        GetDlgItem(IDC_STATIC_Percentage)->SetWindowText(m_StrPercentage);
        GetDlgItem(IDC_STATIC_Percentage)->MoveWindow(m_clrRectPercent);
        KillTimer(1);
    }

    CDialog::OnTimer(nIDEvent);
}

一个初始化函数

void CMyProgressCtrl2::SetBackground()
{
    m_clrRect.top=30;
    m_clrRect.left=0;
    m_clrRect.bottom=50;
    m_clrRect.right=0;

    m_clrRectPercent.top=0;
    m_clrRectPercent.left=m_clrRect.right-15;
    m_clrRectPercent.bottom=20;
    m_clrRectPercent.right=m_clrRect.right+15;


    m_ArcPoint[0]=CPoint(-3, 20);
    m_ArcPoint[1]=CPoint(m_clrRect.right, m_clrRect.top);
    m_ArcPoint[2]=CPoint(3, 20);

    m_SweepAngle = 0.0f;
    Invalidate(FALSE);
    UpdateWindow();

    SetTimer(1, 10, NULL);
}

接下来和窗口透明功能相加就会产生比较好的效果。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值