Каким будет самый короткий код для установки состояния кнопки панели задач Windows 7 для известного дескриптора окна?
Цель состоит в том, чтобы написать консольную утилиту, которая изменяет ход и состояние (цвет) элемента панели задач окна консоли из пакетного сценария. В то время как скрипт выполняет разные задачи, элемент панели задач его окна консоли должен представлять текущее состояние.
Я получаю дескриптор окна с помощью функции GetConsoleWindow (), но затем мне кажется, что для этого требуются такие вещи, как COM и Shell API, которые я не понимаю. Один пример, который я нашел, использует целое приложение с графическим интерфейсом пользователя с MFC для демонстрации API, но большинство из них слишком сложны для моего маленького инструмента, и я не понимаю его достаточно хорошо, чтобы удалить ненужные вещи.
Инструмент должен компилироваться в Windows 7 с VS2010 (C ++), но также работать и в более ранних версиях Windows (ничего не делать, если функция недоступна).
Я создал класс, чтобы установить прогресс в панели задач 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;
}
Обратите внимание, вам все еще нужно позвонить RegisterWindowMessage("TaskbarButtonCreated")
а также ChangeWindowMessageFilterEx()
настроить фильтр сообщений перед SetProgressValue()
может работать.
Согласно документам MSDN, вы должны воссоздавать свой объект каждый раз, когда получаете созданное сообщение, но я обнаружил, что мне просто нужно сделать ChangeWindowMessageFilterEx()
и это нормально работает для нормальных обстоятельств.