finally i've structured it in the following way:
Code:
// Include Vista-specific defines unless on GCC3
#if !defined(__GNUC__) || __GNUC__>=4
#include <ShObjIdl.h>
#define FREEARC_WIN_VISTA
#endif
...............
/******************************************************************************
** Windows7+ taskbar progress indication *****************************************
******************************************************************************/
#ifdef FREEARC_WIN_VISTA
class Win7TaskbarProgress
{
private:
ITaskbarList3* m_pITaskBarList3;
bool m_bFailed, local;
HWND hWnd;
bool Init()
{
if (m_pITaskBarList3)
return true;
if (m_bFailed)
return false;
hWnd = GetConsoleWindow();
local = false;
// Initialize COM for this thread...
CoInitialize(NULL);
CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&m_pITaskBarList3);
if (m_pITaskBarList3)
return true;
m_bFailed = true;
CoUninitialize();
return false;
}
public:
Win7TaskbarProgress()
{
m_pITaskBarList3 = NULL;
m_bFailed = false;
}
virtual ~Win7TaskbarProgress()
{
if (local)
SetProgressState(TBPF_NOPROGRESS);
if (m_pITaskBarList3)
{
m_pITaskBarList3->Release();
CoUninitialize();
}
}
void SetProgressState(TBPFLAG flag)
{
SetProgressState(hWnd, flag);
}
void SetProgressState(HWND hwnd, TBPFLAG flag)
{
if (Init())
m_pITaskBarList3->SetProgressState(hwnd, flag);
}
void SetProgressValue(ULONGLONG ullCompleted, ULONGLONG ullTotal)
{
local = true;
SetProgressValue(hWnd, ullCompleted, ullTotal);
}
void SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal)
{
if (Init())
m_pITaskBarList3->SetProgressValue(hwnd, ullCompleted, ullTotal);
}
};
#else
struct Win7TaskbarProgress
{
void SetProgressValue (uint64 ullCompleted, uint64 ullTotal) {}
};
#endif
usage example for console program (indicator automatically removed by the Win7TaskbarProgress destructor):
Code:
Win7TaskbarProgress win7taskbar;
for (int i=0; i<100; i++)
win7taskbar.SetProgressValue (i, 100);
in the GUI program, you shoul additionally pass handle of GUI window and manually remove the indicator:
Code:
Win7TaskbarProgress win7taskbar;
for (int i=0; i<100; i++)
win7taskbar.SetProgressValue (hWnd, i, 100);
SetProgressState(hWnd, TBPF_NOPROGRESS);