Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / MFC

Windows 7: How to display progress bar on taskbar icon?

4.80/5 (8 votes)
12 May 2010CPOL3 min read 60K  
Simple method to display progressbar over taskbar button

The best thing you may notice in Windows 7 may be its taskbar. It's totally revamped and gives us a fresh look, more usable with progress bar overlays, jump lists to easily open the last opened documents, and improved and interactive thumbnail previews applications etc. You can see more details in Windows 7 website.

In this post, I am covering progress bar to display as taskbar button overlay. In Windows 7, you might have noticed the progress bar on taskbar button in many applications like Windows Explorer shows progress of file copy, Internet Explorer or Safari displays progress of downloads, etc.

We can program this for our application as well. It can be easily accomplished using the ITaskList3 COM Interface. This Interface not only for progress bars. It can be used for:

  • When working with a TDI (Tabbed Document Interface) application (such as Internet Explorer) or a MDI application (such as Microsoft Excel) that is displaying its windows as a group on the taskbar:
    • Provide the taskbar with a thumbnail that represents the view of an individual tab or document. (You can see this in action with Safari Or Internet Explorer Browser)
    • Remove the thumbnail of an individual tab or document from the group.
    • Change the order of thumbnails in the group.
    • Set a tab thumbnail as the selected item when the thumbnails are shown.
  • When applying an overlay to a taskbar icon, such as a notification.
    • When showing the progress of an operation, such as copying or installing an item.
    • When adding a toolbar to a thumbnail. (like iTunes of Windows Media Player)

Now let’s see how we can do this. I've prepared a simple dialog based application which shows a progressbar as below. You can also see the progressbar over the Icon of application displayed in the thumbnail area.

image

image

The code is self explanatory. See the code snippet and comments. Don't forget to release the ITaskListInterface after usage. You should call m_pTaskList>Release(); to release the interface.

Step #1

Declare the pointer to access ITaskbarList3 interface. You can make this as a member of the dialog class.

C++
ITaskbarList3* m_pTaskBarlist;
CoCreateInstance(
            CLSID_TaskbarList, NULL, CLSCTX_ALL,
            IID_ITaskbarList3, (void**)&m_pTaskBarlist);

Step #2

Initialize the progressbar state to enable the progressbar overlay:

C++
m_pTaskBarlist->SetProgressState( m_hWnd, TBPF_INDETERMINATE );

The parameters are relatively simple. Windows handle must be passed along with the type of progressbar that needs to be displayed. If you check the definition, you can see the following types can be passed to the function. These states are exactly similar state of a normal progressbar.

TBPF_NOPROGRESSThis flag disables the progressbar overlay and displays normal taskbar button
TBPF_INDETERMINATEInstead of displaying the constant progress, it displays horizontal marquee
TBPF_NORMALNormal progressbar
TBPF_ERRORProgressbar with an red colored overlay (based on the theme)
TBPF_PAUSEDPaused state. In this state, you can see a flashing horizontal on progressbars

Step #3 Progress

Simply call SetProgressValue() as given below. The current value and maximum value should be given.

C++
m_pTaskBarlist->SetProgressValue( m_hWnd, nPos, nMax );

Once you finish the task, you've to disable the progress state. I hope you know how to do it :)

See the full scoop here.

To compile this code, either use Visual Studio 2010 or download the Windows 7 SDK from MSDN website.

C++
// Declare this as member of the class or global (not recommended)
ITaskbarList3* m_pTaskBarlist;
void CTaskBarSampleDlg::OnBnClickedButtonStart()
{
	m_Progress.SetRange( 0, 10 ); // set the range for the control
	m_Progress.SetPos( 0 ); // Set initial position
	// Initialize the pointer. You can also do this in the constructor.
	// Remember to release after use
	if( NULL == m_pTaskBarlist )
	{
		CoCreateInstance(
			CLSID_TaskbarList, NULL, CLSCTX_ALL,
			IID_ITaskbarList3, (void**)&m_pTaskBarlist);
	}
	m_pTaskBarlist->SetProgressState( m_hWnd, TBPF_INDETERMINATE );
	SetTimer( 0, 500, 0 );
}
// Timer to update the progress
void CTaskBarSampleDlg::OnTimer(UINT_PTR nIDEvent)
{
	int nPos = m_Progress.GetPos();
	int nMin, nMax;
	m_Progress.GetRange( nMin, nMax );
	nPos++;
	// if finished, kill timer and return
	if( nPos > nMax )
	{
		// reset the progress state
		m_pTaskBarlist->SetProgressState( m_hWnd, TBPF_NOPROGRESS );
		// just flash the window to notify user
		FlashWindow( true );
		// Stop the timer
		KillTimer( 0 );
		// You can release the pointer if necessary here. 
                  // But not a good practice
		return;
	}
	// set progress to taskbar overlay
	m_pTaskBarlist->SetProgressValue( m_hWnd, nPos, nMax );
	// set the control's progress state
	m_Progress.SetPos( nPos );
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)