New Features for the Statusbar in MFC

Expanding existing objects with new and better features is a way of imitating evolution in the living world. Still, the result is just as good as in nature. Gradually we create tools for our work that make life much easier. A similar process can be observed in the Statusbar of the Windows operating system. Let us see what improvements we have at hand with the appearance of the newest generation of tools. This is the second part of an eight-part series.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 3
October 08, 2009
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Previously I showed you how to handle the classic Statusbar. As with everything around us, this has also improved in the last few years. This will be a great opportunity for those who want to see and learn about the new features available. If for some reason you are not familiar with how the classic Statusbar worked I strongly advise you to read my previous article titled Status Bar in MFC.

I already mentioned that with the MFC Feature Pack launched along with Service Pack One of Visual Studio 2008, the Statusbar was improved with the addition of the following features: the capability to post images, animations, and progress bars in the Statusbar. We can also make it respond to mouse double-clicks performed within the surface of the Statusbar.

For a quick review, let me recall the example project I created last time. I added an extra pane to the Statusbar in which I displayed the current day and the clock of the local system. Today I am going to expand on this by adding an image of a clock near it.

First, we need to add a bitmap image to the resource. Go to the resource view and import the following picture into it:

Change its name in the properties section to ID_STATUS_CLOCK_ICON. Now add the following lines to the end of the OnCreate section:

CBitmap m_StatusBarClockIcon;

 

m_StatusBarClockIcon.LoadBitmap (ID_STATUS_CLOCK_ICON);

 

m_wndStatusBar.SetPaneIcon(m_wndStatusBar.CommandToIndex( ID_STATUS_TEXT), m_StatusBarClockIcon,TRUE);

For starters, we loaded the image, and then set it to the corresponding pane. The icon is appended to the left side of the pane and has no influence on the size of the text. The pane's size is extended to fit in the icon near the text's side. Once compiled and run, you can see the effect:

 

Adding small tooltip texts that pop up once you hover over a pane is just as easy with the SetTipText function:

m_wndStatusBar.SetTipText(

m_wndStatusBar.CommandToIndex(ID_STATUS_TEXT),

_T(" The current time"));

 

Animation

Animations are in fact just a list of pictures that are periodically changed to create an impression of movement. You may want to use one when you want to simulate, for example, that the application is working/processing some information. To set an animation into the Statusbar we need a list of images, a pane, and we may want to specify the speed with which the images change.

The list of images we need to pass down for the in-built set function via a HIMAGELIST type. I am going to use the CImageList class, as this has a default operator that transforms the variable to this structure. We will load the image in one chunk and split it up later. I decided to add a simple animation of an analog clock made out of four pictures. I created them and added them in a row, one after another, as follows:

Add it via the resource view and assign it to the resource identifier IDB_ANIM_CLOCK. Now we will load and create the list with the following lines added at the end of the OnCreate function:

CBitmap bitMap;

CImageList ImageList;

 

bitMap.LoadBitmap(IDB_ANIM_CLOCK);

 

//specify size of an image, style configurations

// number of initial images present and to what it can grow

m_ImageList.Create(23, 24, ILC_COLOR32 | ILC_MASK, 4, 0);

 

// decompose the image by using the mask

m_ImageList.Add(&bitMap, RGB(255,0,255));

Meanwhile, create a new pane inside the Statusbar as you learned how to do  in my previous article with the ID_CLOCK_ICON ID (add to the indicators list, etc). Because (at least in my case) I could not create a pane that had no default text attached to it, and adding a default text made some unneeded space, I have resized the text space to zero and also reset an empty text.

int ind = m_wndStatusBar.CommandToIndex(ID_CLOCK_ICON);

 

m_wndStatusBar.SetPaneText(ind,_T(""));

m_wndStatusBar.SetPaneWidth(ind, 0);

m_wndStatusBar.SetPaneAnimation(ind, m_ImageList) ;

For the SetPaneAnimation, a third parameter specifies the speed. By default this is 500 ms. We will mess with this later. For now, notice that the pane occupies just the space required for it and nothing more.

Progress bar

It is always a good idea to remind the user of the status of the data procession, if possible. Adding a little progress bar inside the Statusbar is one of the best solutions.

A progress bar requires its own pane. Create one with the ID of ID_PROG_BAR. Add any default text, as the size it does not matter. We will change it.

int id = m_wndStatusBar.CommandToIndex(ID_PROG_BAR;

 

m_wndStatusBar.SetPaneWidth(id, 100);

m_wndStatusBar.EnablePaneProgressBar (id, 100);

 

The short code snippet above is all you need to get it up and working. To simulate it I decided to increase the progress by one at every OnTimer call (so every single second). I set 100 pixels as the length of the progress bar and set the maximum value of the progress bar to one hundred with the second function (besides enabling it). You can use the following method to ensure a nice demo (add it at the end of OnTimer function):

if(m_alfa == 100)

m_alfa = 0;

 

m_wndStatusBar.SetPaneProgress( m_wndStatusBar.CommandToIndex(ID_PROG_BAR), ++m_alfa);

 

Most of the time you may want to modify this from other classes. If this is the case, you need to create a method for accessing the Statusbar. The most advisable is to implement a member function of the mainframe that returns a reference or pointer. You can ask for the mainframe's pointer from any class via the following line:

 

((CMainFrame*) AfxGetMainWnd ())->GetStatusBar().SetPaneText(…);

 

if the GetStatusbar is defined as:

 

CMFCStatusBar& CMainFrame::GetStatusBar()

{

return m_wndStatusBar;

} 

Double click response

 

The last and most promising of the new features is the possibility to catch double clicks made upon a pane. You can initialize this by calling the following function:

 

m_wndStatusBar.EnablePaneDoubleClick(TRUE);

 

Put it inside the OnCreate method of the mainframe, and after every double click on a pane, the WM_COMMAND message will be sent along with the ID of the pane. To demonstrate it, add the OnCommand function via the rout Class View -> MainFram -> Properties -> Overrides.

The wParam parameter will carry the code of the pane. I have implemented a couple of behaviors for every control I presented here. The progress bar's counter will increase by ten, the speed of the animation will double and the current clock will be shown inside a message window for the icon/clock. The code snippet for all of this is below, and is quite easy to understand if you have followed me up to this point:

BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)

{

 

if( wParam == ID_PROG_BAR)

{

m_alfa = m_alfa +10;

 

if(m_alfa == 100) //when full, start over

m_alfa = 0;

m_wndStatusBar.SetPaneProgress(

m_wndStatusBar.CommandToIndex(ID_PROG_BAR), ++m_alfa);

}

else

 

if( wParam == ID_STATUS_TEXT)

this->MessageBox(_T("Current time is: n") + time);

else

 

if (wParam == ID_CLOCK_ICON)

{

m_speed /= 2;

if(!m_speed) // no zero speed allowed, reset

m_speed = 500;

m_wndStatusBar.SetPaneAnimation( m_wndStatusBar.CommandToIndex(ID_CLOCK_ICON),

m_ImageList, m_speed) ;

}

 

return CMDIFrameWndEx::OnCommand(wParam, lParam);

}

 

Moreover, as a little extra artistic touch, at the end I changed the background of the clock pane and the color of the text. Use the SetPaneBackgroundColor and SetPaneTextColor functions along with a RGB color. The OnCreate method is once again the correct choice to specify this.

int id = m_wndStatusBar.CommandToIndex(ID_STATUS_TEXT);

 

m_wndStatusBar.SetPaneBackgroundColor(id, RGB( 0 ,255,0));

m_wndStatusBar.SetPaneTextColor (id, RGB( 255,0 ,0));

 

Here I also attach the final state of the project if you want to try it out and see it for yourself. I used Microsoft Visual Studio 2008 with the Service Pack installed so prepare to use something similar at least.

 

Thank you for your interest and reading my article. It would be an extraordinary help if you would take the time to rate my article and to give your feedback in the blog commenting tool you can find below the article. Any constructive criticism is welcome. If you have other questions that are not related to this article, join our friendly forum at DevHardware or at our sister forum Dev Shed, and put up your questions for our experts. Until next time, Live With Passion!

blog comments powered by Disqus
.NET ARTICLES

- .Net 4.5 Brings Changes
- Understanding Events in VB.NET
- Objects, Properties, Events and Methods in V...
- Install Visual Web Developer Express 2010
- Microsoft Gadgeteer an Open Source Alternati...
- Best DotNetNuke Modules
- Facebook Image Viewer in Visual Basic
- Murach`s ADO.NET 4 Database Programming with...
- 5 Must Have Visual Studio 2010 Extensions
- Dynamic Web Applications with ASP.NET Mono u...
- PDFSharp: HTML to PDF in ASP.NET 3.5 using V...
- Using the PDFSharp Library in ASP.NET 3.5 wi...
- Sending Email in ASP.NET 3.5 using VB.NET wi...
- ASP.NET 3.5 Role Based Security and User Aut...
- Creating ASP.NET Login Web Pages and Basic C...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 11 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials