EZSnakeCtrl-Indefinite Cyclic Progress control


Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame

Environment: Visual C++ 6 (SP2), Windows 98

I got the hunch from Netscape's progress control in the status bar. Since most of the complexity is hidden in the implementation, using this is as easy as using a normal progress bar. This control is not derived from CProgressBarctrl but from CStatic to ensure simplicity and efficiency. An imitation of Netscape status bar as well as a dialog based demo like that of CGradientProgress is included in the sample zip file. If this control is used in a dialog box, simply put a CStatic Place holder in the dialog and subclass it to CEZSnakeCtrl. Now you can customize the look & feel of the control. Various options available are:

 //Get & Set The Maximum value of the progress control
 //0 is assumed as the minimum.
 int GetMax();
 void SetMax(int nMax); 

 //Get & Set the size of the snake      
 int GetSize();
 void SetSize(int nSize);

 //Get & Set the the Steps ->unit increment
 int GetStep();
 void SetStep(int nStep);

 //Get The Head Position
 int GetPos();

 //Get The tail position
 int GetTail();

 //Get the direction of the snake
 BOOL IsReverse();

 //Get & Set the Gradient begin & end colors
 COLORREF GetGradientEndColor();
 COLORREF GetGradientStartColor();
 void SetGradientFill(COLORREF clrStart,COLORREF clrEnd);

 //Get & Set Background color
 COLORREF GetBkColor();
 void SetBkColor(COLORREF clrFG);

 int StepIt();//Move the snake.
 void ResetProgress();//reset the snake

I think the demo project can do rest of the explaining.


Download demo project - 71 Kb
Download source - 3 Kb


  • The display is jerky.

    Posted by aglushen on 05/19/2005 03:12am

    I like the idea but don't really like the implementation. The prgress bar display is very jerky at times. Thanks, --Sasha

  • Thanks !

    Posted by Legacy on 09/26/2000 07:00am

    Originally posted by: Mountazar Abou Chrouche

    Hi, thanks for you Mr.Petr Novotny
    You saved me !

  • Netscape version & statusbar resizing

    Posted by Legacy on 12/06/1999 08:00am

    Originally posted by: rick shide

    The control does not adjust to statusbar resizing (via window resizing).

  • Thats nice!!!!!

    Posted by Legacy on 10/26/1999 07:00am

    Originally posted by: p.karthikeyan

    hai Mr.lakshmiNarasimhan!
    that was nice.

  • Got it to work - what had to be fixed

    Posted by Legacy on 09/23/1999 07:00am

    Originally posted by: Petr Novotny

    I have got the control to work. I needed to do a few fixes in it though.

    Fixes: (as suggested here, but I found the suggestions too late)
    A. OnPaint MUST use CPaintDC. There's no excuse for calling GetDC. This way, the control gets never validated! It's caught in an infinite loop, getting zillions of WM_PAINTs.
    B. If you fix A, StepIt() doesn't redraw the control. InvalidateRect(NULL) in StepIt() does the trick.

    What I did:

    1. I have created a new thread for the "progress dialog". I create the progress dialog in InitInstance().
    2. In progress dialog's OnInitDialog, I call SetTimer (and adjust the snake).
    3. In OnTimer handler, I do StepIt().
    4. In dialog's PostNcDestroy, I call PostQuitMessage to finish the thread.
    5. When I want to close the dialog, I call DestroyWindow() on it from the main thread.

    Works like charm.

  • Message Boxes don't work with this control!!!

    Posted by Legacy on 09/13/1999 07:00am

    Originally posted by: Navi Singh

    I tried to use the control in my app. I found that message boxes do not popup in front of the app after creating this control. A simple test of the fact is to create a message box immediately after the create call to the snake control.


  • RE:Message boxes don't work...

    Posted by Legacy on 09/13/1999 07:00am

    Originally posted by: Lakshmi Narasimhan V

    Hi all,
    Firstly, this is an Indefinite progress control. Any job thats indefinite has to be placed in a seperate thread(also read Johnny anonymous' comment). So Until I bring up a thread encapsulated(Like CAnimateCtrl's Play) version I advise the developers to put it in a seperate thread(I'm held up in other work currently).

    V.Lakshmi Narasimhan

  • Use CPaintDC...

    Posted by Legacy on 08/16/1999 07:00am

    Originally posted by: John Weeder

    Lots of problems happen if you use the control (as-is)  with status/toolbars. 

    Docking controls bars use the following code:

    // handle pending WM_PAINT messages
    MSG msg;
    while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
    if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))

    Unfortunately, this control doesn't use a CPaintDC so the paint message is never properly handled and an infinite loop results..

    I suggest using a
    CPaintDC dcPaint(this);

    in OnPaint(). You will need to clean up the old mem dc and release dc stuff... It is patently incorrect.

    I also suggest an InvalidateRect(0); in StepIt() to force a redraw.

  • It's not working correctly

    Posted by Legacy on 07/30/1999 07:00am

    Originally posted by: Mike

    If you compile and run the project you will find a bug when you try to open a modal dialogbox like the Aboutbox. The whole demo application hangs!

  • FIX: Mouse movement causes erratic painting

    Posted by Legacy on 07/30/1999 07:00am

    Originally posted by: Johnny Anonymous

    First, this is a really slick control.

    As has already been mentioned by the author in another
    comment, this control will work perfectly outside of
    the main thread. For single-threaded applications it
    can be made to work just as well.

    The main problem is the Sleep() call located in
    CMainFrame::OnStart(). This freezes all message
    processing for the application and then the
    abbrieviated message loop must process all the
    pending messages before the control is updated
    by the call the StepIt().

    To fix the problem in the demo, do the following:

    1) Remove the call to Sleep() in CMainFrame::OnStart()
    (in a real single-threaded application you would
    probably want to add some things to the event
    loop, etc...)

    2) Add timing code to the EZSnakeCtrl class.
    Since sleep was removed, the control will be
    drawing itself as fast as you machine will let
    it. An easy way to control the speed would be
    to use the timeGetTime() call to limit the
    stepping to once every 10 milliseconds or so.
    Here's one way to do that.

    In EZSnakeCtrl.h:

    Add the following member variable...

    DWORD m_dwResolution;

    In EZSnakeCtrl.cpp:

    Add the following in the constructor...

    m_dwResolution = 10; // note: you may want to add a member function to set this at run time...

    Add the following at the top of the CEZSnakeCtrl::StepIt()
    member function...

    static DWORD dwLastTime = 0;
    DWORD dwNow;

    dwNow = timeGetTime();

    if (dwNow - dwLastTime < m_dwResolution)
    return m_nPos;
    dwLastTime = dwNow;

    You'll probably want to add some code to exit the
    message loop if the WM_QUIT message as received or
    if a custom message you've defined is posted to the
    thread. The code above should take care of the
    problems people are having.

  • Loading, Please Wait ...

  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date