问题 Windows 7任务栏状态,代码最少


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

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

我使用GetConsoleWindow()函数获取窗口句柄,但是它似乎需要加载COM和Shell API的东西,我不明白。我发现的一个例子使用了一个带有MFC的整个GUI应用程序来演示API,但是大多数它对于我的小工具来说太复杂了,而且我不太了解它以便删除我不需要的东西。

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


6090
2018-02-21 11:55


起源

“任务栏状态”是什么意思?你的意思是只显示进度或其他什么? - sashoalm
是的,只是进度和状态(不确定,暂停,错误,即颜色为绿色,黄色和红色)。没有跳转列表,缩略图或动作按钮。 - ygoe


答案:


我创建了一个类来同时为项目设置Win7任务栏中的进度。这是我挖出的代码:

#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;
}

12
2018-02-21 13:04



我想我需要这个: #include <ShObjIdl.h> 但那是什么呢 VERIFY() 做? - ygoe
没什么重要的,我删除了编辑我的答案并将其删除。它就像一个ASSERT()但该语句仍然在Release版本中执行。看到 msdn.microsoft.com/en-us/library/fcatwy09(v=vs.80).aspx - sashoalm
我已经制作了一个方便的小工具,扩展了我之前的Flash专用功能。你可以在这里找到它: dev.unclassified.de/apps/flashconsolewindow - ygoe
它在多线程应用程序中不起作用。如果从工作线程调用方法SetProgressState,则它在Release()中崩溃。 - palota


请注意,您仍然需要打电话 RegisterWindowMessage("TaskbarButtonCreated") 和 ChangeWindowMessageFilterEx() 之前设置消息过滤器 SetProgressValue() 能行得通。

根据MSDN文档,您应该在每次获取创建的消息时重新创建对象,但我发现我只需要执行 ChangeWindowMessageFilterEx() 它适用于正常情况。


0
2018-03-05 14:27



我写了一个使用的应用程序 SetProgressValue 并且完美无缺 RegisterWindowMessage 也不 ChangeWindowMessageFilterEx。与往常一样,文档中缺少许多信息。 - v77