Click here to Skip to main content
Click here to Skip to main content
Go to top

New Pie progress control with 3D look

, 26 Oct 2002
Rate this:
Please Sign up or sign in to vote.
Now you can have a pie control replacement for a progress bar, in 3D look.

Sample Image - 3D-Pie_progress_control.gif

Introduction

Hi all!! Well I have been looking for a pie control that would use the skin images instead of simple colors and just could not find that. And I struggled quit a lot to make it but ..Frown | :( anyway so found out another solution that is 3D pie control that could satisfy my needs. I got it developed with one of my bright colleagues, Amit Ganguly, who is a fresh engineer and strong with mathematics. So guys just download it, use it, and let me know your comments/

How to use it

This is very simple to use. Just add a button to your project and make member variables of the button. Include the following line at the top of the dialog box's header file (if you are making a dialog box based application as my demo project with the article).

#include <span class="code-string">"PieProgress.h"</span>

Now you have included the class CPieProgress. It's time to make an object of this class, change the following code in the header file.

CButton m_ctlPieProgress;

to

CPieProgress m_ctlPieProgress;

Of course if the member variable of the button earlier created by you, is named m_ctlPieProgress. All is done, all you have to do now is initialize the pie control. Add the following lines of code in your dialog box's implementation class in the function OnInitDialog().

BOOL CPieControlDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
    
    // TODO: Add extra initialization here

    m_ctlPieProgress.SetRange(0,100);
    m_ctlPieProgress.SetProgressColors(RGB(255,0,0),RGB(0,255,0));
    
    SetTimer(1978,500,NULL);
    return TRUE;  // return TRUE  unless you set the focus to a control
}

I have set a timer here to see the progress. So its all done and you have a 3D-pie control in your project. Enjoy.........

Behind the scenes

Nothing magical here. It's the magic of subclassing. I derived the pie control's class directly from CWnd and have the magical drawing function DrawPie() get called from OnPaint() after checking that the progress value lies in the range set as follows:

void CPieProgress::DrawPie(CZipDC * pDC,CPoint CntrPt,CRect Rect)
{
    CBrush  BkgndBrh;
    CBrush  FrgndBrh;
    
    BkgndBrh.CreateSolidBrush(clrComplete);
    FrgndBrh.CreateSolidBrush(clrIncomplete);

    iSemi_ht = 0.6 * Rect.Height() /2;
    iSemi_lt = Rect.Width()/2;

    PieRect.top = CntrPt.y - iSemi_ht;
    PieRect.bottom = CntrPt.y + iSemi_ht;
    PieRect.left = CntrPt.x - iSemi_lt;
    PieRect.right = CntrPt.x + iSemi_lt;
    

    StrtPt.x = CntrPt.x;
    StrtPt.y = CntrPt.y + iSemi_ht;

    EndPt = StrtPt;

    pDC->SelectObject(&BkgndBrh);
    pDC->Pie(PieRect.operator LPRECT(),StrtPt,EndPt);    

    iPer = ((nValue - nLow)* 100/(nHigh - nLow));
    
    EndPt = GetPerPoint(iPer,iSemi_lt,iSemi_ht,CntrPt);     
    
    pDC->SelectObject(&FrgndBrh);
    pDC->Pie(PieRect.operator LPRECT(),StrtPt,EndPt);

    Rect_1.bottom = CntrPt.y;
    Rect_1.right = CntrPt.x;
    Rect_1.top = CntrPt.y - 10;
    Rect_1.left = CntrPt.x - iSemi_lt;

    Rect_2.top = CntrPt.y - 10;
    Rect_2.left  =CntrPt.x;
    Rect_2.bottom = CntrPt.y;
    Rect_2.right = CntrPt.x + iSemi_lt;

    if(iPer >= 25)
    {
        pDC->FillRect(Rect_1.operator LPRECT(),&BkgndBrh);
        if(iPer >= 75)
        {
            pDC->FillRect(Rect_2.operator LPRECT(),&BkgndBrh);
        }
        else
        {
            pDC->FillRect(Rect_2.operator LPRECT(),&FrgndBrh);
        }
                
    }
    else
    {
        
        pDC->FillRect(Rect_1.operator LPRECT(),&FrgndBrh);
        pDC->FillRect(Rect_2.operator LPRECT(),&FrgndBrh);
    }


    if(iPer <= 50)
    {
        Rect_1.bottom = EndPt.y;
        switch(iPer)
        {

        case 0:
            Rect_1.right = EndPt.x ;
            break;
        
        case 1:
            Rect_1.right = EndPt.x + 2;
            break;
        
        case 2:
            Rect_1.right = EndPt.x + 4;
            break;
        case 3:
            Rect_1.right = EndPt.x + 6;
            break;
        
        case 4:
            Rect_1.right = EndPt.x + 8;
            break;
        
        default:
            Rect_1.right = EndPt.x + 10;    
            break;
        }
                
        Rect_1.top = EndPt.y - 10;
        Rect_1.left = EndPt.x;
        pDC->FillRect(Rect_1.operator LPRECT(),&BkgndBrh);    
    }
    else
    {
        Rect_1.bottom = EndPt.y;
        switch(iPer)
        {
        case 96:
             Rect_1.left = EndPt.x - 8;                
            break;
        
        case 97:
            Rect_1.left = EndPt.x - 6;            
            break;

        case 98:
            Rect_1.left = EndPt.x - 4;            
            break;
        
        case 99:
            Rect_1.left = EndPt.x - 2;            
            break;
        
        case 100:
            Rect_1.left = EndPt.x ;            
            break;
        

        default:
            Rect_1.left = EndPt.x - 10;            
            break;
        }
                
        Rect_1.top = EndPt.y - 10;
        Rect_1.right = EndPt.x;
        pDC->FillRect(Rect_1.operator LPRECT(),&FrgndBrh);
    }
    

    CntrPt.y = CntrPt.y - 10;
    
    PieRect.top = CntrPt.y - iSemi_ht;
    PieRect.bottom = CntrPt.y + iSemi_ht ;
    PieRect.left = CntrPt.x - iSemi_lt;
    PieRect.right = CntrPt.x + iSemi_lt;

    StrtPt.x = CntrPt.x;
    StrtPt.y = CntrPt.y + iSemi_ht;

    EndPt = StrtPt;

    pDC->SelectObject(&BkgndBrh);
    pDC->Pie(PieRect.operator LPRECT(),StrtPt,EndPt);    

        
    EndPt = GetPerPoint(iPer,iSemi_lt,iSemi_ht,CntrPt);     
    
    pDC->SelectObject(&FrgndBrh);
    pDC->Pie(PieRect.operator LPRECT(),StrtPt,EndPt);

    pDC->MoveTo(CntrPt.x - iSemi_lt,CntrPt.y);
    pDC->LineTo(CntrPt.x - iSemi_lt,CntrPt.y + 10); 
    
    pDC->MoveTo(CntrPt.x + iSemi_lt,CntrPt.y);
    pDC->LineTo(CntrPt.x + iSemi_lt,CntrPt.y + 10); 

}

Now you must be wondering why so much of code there. Well this is what shows Mr. Amit Ganguly's mathematical skills. I haven't really checked what all he has written there but I think, this must be the smallest code required to draw the pie (I guess it is called Keplar's law ).

Guys help me

Hey guys please let me know if someone has any idea about the skin based pie control...coool...so just live life Wink | ;)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Ashok Jaiswal
Web Developer
Hong Kong Hong Kong
innovating, managing and developing next generation media products and services

Comments and Discussions

 
GeneralThis pie chart seems to not show properly at 100% [modified] Pinmemberhyvee_doughboy25-Jul-07 5:10 
QuestionFlickering PinmemberLuPossj2-Jul-07 20:50 
Questionclear bkg? Pinmemberchris17514-Sep-06 9:14 
Generala drawing fix... PinmemberOrkblutt17-Aug-06 6:59 
GeneralRe: a drawing fix... PinmemberNynaeve10-May-07 10:11 
Questionhow to use non dialog box application Pinmembershaikesu9-Dec-05 0:36 
QuestionHit testing? PinsussTedL22-Jul-02 8:00 
Generalcode in the article PinmemberJason Henderson22-Jul-02 3:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 27 Oct 2002
Article Copyright 2002 by Ashok Jaiswal
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid