Search code examples
c++windows-7console-applicationtaskbar

Windows 7 taskbar state with minimal code


What would be the shortest code to set the state of a Windows 7 taskbar button for a known window handle?

The goal is to write a console utility that changes the progress and state (colour) of the console window taskbar item from a batch script. While the script performs different tasks, the taskbar item of its console window should represent the current state.

I get the window handle with the GetConsoleWindow() function, but then it seems to require loads of COM and Shell API stuff that I don't understand. One example I've found uses a whole GUI application with MFC to demonstrate the API, but most of it is way too complicated for my little tool and I don't understand it well enough to remove the stuff I don't need.

The tool should compile on Windows 7 with VS2010 (C++) but also run on earlier Windows versions (doing nothing if a feature is not available).


Solution

  • I created a class to set the progress in the Win7 taskbar for a project at one time. It's a wrapper for the ITaskBarList3 interface available from the Windows Shell. It's specifically done with ITaskBarList3.SetProgressState and ITaskBarList3.SetProgressValue functions.

    This is the code I dug up:

    #include <shobjidl.h>
    #include <windows.h>
    #pragma comment(lib, "Shell32.lib")
    #pragma comment(lib, "Ole32.lib")
    
    class Win7TaskbarProgress  
    {
    public:
        Win7TaskbarProgress();
        virtual ~Win7TaskbarProgress();
    
        void SetProgressState(HWND hwnd, TBPFLAG flag);
        void SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal);
    
    private:
        bool Init();
        ITaskbarList3* m_pITaskBarList3;
        bool m_bFailed;
    };
    
    Win7TaskbarProgress::Win7TaskbarProgress()
    {
        m_pITaskBarList3 = NULL;
        m_bFailed = false;
    }
    
    Win7TaskbarProgress::~Win7TaskbarProgress()
    {
        if (m_pITaskBarList3)   
        {
            m_pITaskBarList3->Release();
            CoUninitialize();
        }
    }
    
    void Win7TaskbarProgress::SetProgressState( HWND hwnd, TBPFLAG flag )
    {
        if (Init())
            m_pITaskBarList3->SetProgressState(hwnd, flag);
    }
    
    void Win7TaskbarProgress::SetProgressValue( HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal )
    {
        if (Init())
            m_pITaskBarList3->SetProgressValue(hwnd, ullCompleted, ullTotal);
    }
    
    bool Win7TaskbarProgress::Init()
    {
        if (m_pITaskBarList3)
            return true;
    
        if (m_bFailed)
            return 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;
    }