Windows 7 taskbar state with minimal code

拜拜、爱过 提交于 2019-12-03 06:59:44

问题


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).


回答1:


I created a class to set the progress in the Win7 taskbar for a project at one time. 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;
}



回答2:


Note you still need to call RegisterWindowMessage("TaskbarButtonCreated") and ChangeWindowMessageFilterEx() to setup an message filter before SetProgressValue() can work.

According to the MSDN docs you are supposed to recreate your object each time you get the created message but I found I just had to do the ChangeWindowMessageFilterEx() and it works fine for normal circumstances.



来源:https://stackoverflow.com/questions/15001638/windows-7-taskbar-state-with-minimal-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!