// ************************************************************************** // * This file is part of the FreeFileSync project. It is distributed under * // * GNU General Public License: http://www.gnu.org/licenses/gpl.html * // * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * // ************************************************************************** // #include "taskbar.h" #define WIN32_LEAN_AND_MEAN #include "windows.h" #include #include #include #include namespace { void writeString(const std::wstring& input, wchar_t* output, size_t outputBufferLen) { const size_t newSize = min(input.length() + 1, outputBufferLen); //including null-termination memcpy(output, input.c_str(), newSize * sizeof(wchar_t)); output[newSize-1] = 0; //if output buffer is too small... } std::wstring numberToHexString(const long number) { wchar_t result[100]; swprintf(result, 100, L"0x%08x", number); return std::wstring(result); } std::wstring writeErrorMsg(const wchar_t* input, HRESULT hr) { std::wstring output(input); output += L" ("; output += numberToHexString(hr); output += L": "; output += _com_error(hr).ErrorMessage(); output += L")"; return output; } using TaskbarSeven::TBHandle; typedef std::map TaskBarHandleMap; TaskbarSeven::TBHandle generateHandle() { static TBHandle handle = 0; return ++handle; //don't return 0! 0 is reserved for indicating failure } TaskBarHandleMap taskBarHandles; std::wstring lastErrorMessage; } //################################################################################################## TaskbarSeven::TBHandle TaskbarSeven::init() //call on app initializaiton; returns handle { ITaskbarList3* pto = NULL; HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pto)); if (FAILED(hr)) { lastErrorMessage = writeErrorMsg(L"Error calling \"CoCreateInstance\".", hr); return 0; } TBHandle newHandle = ::generateHandle(); taskBarHandles[newHandle] = pto; return newHandle; } void TaskbarSeven::release(TBHandle handle) //release handle on app exit { TaskBarHandleMap::const_iterator iter = taskBarHandles.find(handle); if (iter != taskBarHandles.end()) { if (iter->second != NULL) iter->second->Release(); taskBarHandles.erase(iter); } } bool TaskbarSeven::setStatus(TBHandle handle, void* hwnd, //HWND: window assciated to the taskbar icon TaskBarStatus status) { TBPFLAG flag = TBPF_NORMAL; switch (status) { case STATUS_NOPROGRESS: flag = TBPF_NOPROGRESS; break; case STATUS_INDETERMINATE: flag = TBPF_INDETERMINATE; break; case STATUS_NORMAL: flag = TBPF_NORMAL; break; case STATUS_ERROR: flag = TBPF_ERROR; break; case STATUS_PAUSED: flag = TBPF_PAUSED; break; } ITaskbarList3* pto = taskBarHandles[handle]; if (pto) { HRESULT hr = pto->SetProgressState(static_cast(hwnd), //[in] HWND hwnd, flag); //[in] TBPFLAG tbpFlags if (FAILED(hr)) { lastErrorMessage = writeErrorMsg(L"Error calling \"SetProgressState\".", hr); return false; } } return true; } bool TaskbarSeven::setProgress(TBHandle handle, void* hwnd, //HWND: window assciated to the taskbar icon size_t current, size_t total) { ITaskbarList3* pto = taskBarHandles[handle]; if (pto) { HRESULT hr = pto->SetProgressValue( static_cast(hwnd), //[in] HWND hwnd, current, //[in] ULONGLONG ullCompleted, total); //[in] ULONGLONG ullTotal if (FAILED(hr)) { lastErrorMessage = writeErrorMsg(L"Error calling \"SetProgressValue\".", hr); return false; } } return true; } void TaskbarSeven::getLastError(wchar_t* errorMessage, size_t errorBufferLen) { writeString(lastErrorMessage, errorMessage, errorBufferLen); }