13

为已知窗口句柄设置 Windows 7 任务栏按钮状态的最短代码是什么?

目标是编写一个控制台实用程序,从批处理脚本更改控制台窗口任务栏项目的进度和状态(颜色)。当脚本执行不同的任务时,其控制台窗口的任务栏项目应该代表当前状态。

我使用 GetConsoleWindow() 函数获得了窗口句柄,但它似乎需要加载我不理解的 COM 和 Shell API 内容。我发现的一个示例使用带有 MFC 的整个 GUI 应用程序来演示 API,但其中大部分对于我的小工具来说太复杂了,而且我对它的理解还不够好,无法删除我不需要的东西。

该工具应该在带有 VS2010 (C++) 的 Windows 7 上编译,但也可以在早期的 Windows 版本上运行(如果某个功能不可用,则不执行任何操作)。

4

2 回答 2

15

我创建了一个类来一次设置项目在 Win7 任务栏中的进度。ITaskBarList3它是 Windows Shell 提供的接口的包装器。它是专门用ITaskBarList3.SetProgressStateITaskBarList3.SetProgressValue函数完成的。

这是我挖出来的代码:

#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;
}
于 2013-02-21T13:04:46.463 回答
0

请注意,您仍然需要调用RegisterWindowMessage("TaskbarButtonCreated")ChangeWindowMessageFilterEx()设置消息过滤器SetProgressValue()才能工作。

根据 MSDN 文档,您应该在每次收到创建的消息时重新创建对象,但我发现我只需要这样做ChangeWindowMessageFilterEx(),它在正常情况下工作正常。

于 2015-03-05T14:27:25.480 回答