BACKENDS: Implement Win32 taskbar progress state and recent list

This commit is contained in:
Littleboy 2011-03-31 04:46:36 -04:00 committed by Julien
parent f67975a487
commit c0ec09ac66
4 changed files with 164 additions and 16 deletions

View file

@ -87,6 +87,7 @@ void OSystem_Win32::init() {
// Initialize task bar manager
_taskbarManager = new Win32TaskbarManager();
((Win32TaskbarManager *)_taskbarManager)->init();
// Invoke parent implementation of this method
OSystem_SDL::init();

View file

@ -25,30 +25,160 @@
* https://code.google.com/p/dukto/
*/
#include "common/scummsys.h"
#ifdef WIN32
#include "common/textconsole.h"
// Needed for taskbar functions
#include <SDKDDKVer.h>
#include <shlobj.h>
#include "backends/taskbar/win32/win32-taskbar.h"
#include "common/config-manager.h"
#include "common/textconsole.h"
#include <SDL_syswm.h>
// System.Title property key, values taken from http://msdn.microsoft.com/en-us/library/bb787584.aspx
const PROPERTYKEY PKEY_Title = { /* fmtid = */ { 0xF29F85E0, 0x4FF9, 0x1068, { 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 } }, /* propID = */ 2 };
Win32TaskbarManager::Win32TaskbarManager() {
_taskbar = NULL;
}
Win32TaskbarManager::~Win32TaskbarManager() {
if (_taskbar)
_taskbar->Release();
_taskbar = NULL;
CoUninitialize();
}
void Win32TaskbarManager::init() {
// Do nothing if not running on Windows 7 of later
if (!isWin7OrLater())
return;
CoInitialize(NULL);
// Try creating instance (on fail, _taskbar will contain NULL)
HRESULT hr = CoCreateInstance(CLSID_TaskbarList,
0,
CLSCTX_INPROC_SERVER,
IID_ITaskbarList3,
reinterpret_cast<void**> (&(_taskbar)));
if (SUCCEEDED(hr)) {
// Initialize taskbar object
if (FAILED(_taskbar->HrInit())) {
_taskbar->Release();
_taskbar = NULL;
}
} else {
warning("[Win32TaskbarManager::init] Cannot create taskbar instance");
}
}
void Win32TaskbarManager::setOverlayIcon(const Common::String &name, const Common::String &description) {
if (_taskbar == NULL)
return;
warning("[Win32TaskbarManager::setOverlayIcon] Not implemented");
}
void Win32TaskbarManager::setProgressValue(int val, int max) {
warning("[Win32TaskbarManager::setProgressValue] Not implemented");
void Win32TaskbarManager::setProgressValue(int completed, int total) {
if (_taskbar == NULL)
return;
_taskbar->SetProgressValue(getHwnd(), completed, total);
}
void Win32TaskbarManager::setProgressState(TaskbarProgressState state) {
warning("[Win32TaskbarManager::setProgressState] Not implemented");
if (_taskbar == NULL)
return;
_taskbar->SetProgressState(getHwnd(), (TBPFLAG)state);
}
void Win32TaskbarManager::addRecent(const Common::String &name, const Common::String &description) {
warning("[Win32TaskbarManager::addRecent] Not implemented");
}
if (_taskbar == NULL)
return;
// ANSI version doesn't seem to work correctly with Win7 jump lists, so explicitly use Unicode interface.
IShellLinkW *link;
// Get the ScummVM executable path.
WCHAR path[MAX_PATH];
GetModuleFileNameW(NULL, path, MAX_PATH);
// Create a shell link.
if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&link)))) {
// Convert game name and description to Unicode.
LPWSTR game = ansiToUnicode(name.c_str());
LPWSTR desc = ansiToUnicode(description.c_str());
// Set link properties.
link->SetPath(path);
link->SetArguments(game);
link->SetIconLocation(path, 0); // There's no way to get a game-specific icon, is there?
// The link's display name must be set via property store.
IPropertyStore* propStore;
HRESULT hr = link->QueryInterface(&propStore);
if (SUCCEEDED(hr)) {
PROPVARIANT pv;
pv.vt = VT_LPWSTR;
pv.pwszVal = desc;
hr = propStore->SetValue(PKEY_Title, pv);
propStore->Commit();
propStore->Release();
}
// SHAddToRecentDocs will cause the games to be added to the Recent list, allowing the
// user to pin them.
SHAddToRecentDocs(SHARD_LINK, link);
link->Release();
delete[] game;
delete[] desc;
}
}
bool Win32TaskbarManager::isWin7OrLater() {
OSVERSIONINFOEX versionInfo;
DWORDLONG conditionMask = 0;
ZeroMemory(&versionInfo, sizeof(OSVERSIONINFOEX));
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
versionInfo.dwMajorVersion = 6;
versionInfo.dwMinorVersion = 1;
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
return VerifyVersionInfo(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask);
}
LPWSTR Win32TaskbarManager::ansiToUnicode(const char *s) {
DWORD size = MultiByteToWideChar(0, 0, s, -1, NULL, 0);
if (size > 0) {
LPWSTR result = new WCHAR[size];
if (MultiByteToWideChar(0, 0, s, -1, result, size) != 0)
return result;
}
return NULL;
}
HWND Win32TaskbarManager::getHwnd() {
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
if(!SDL_GetWMInfo(&wmi))
return NULL;
return wmi.window;
}
#endif

View file

@ -28,18 +28,35 @@
#ifndef BACKEND_WIN32_TASKBAR_H
#define BACKEND_WIN32_TASKBAR_H
#ifdef WIN32
#include "common/str.h"
#include "common/taskbar.h"
struct ITaskbarList3;
class Win32TaskbarManager : public Common::TaskbarManager {
public:
Win32TaskbarManager();
virtual ~Win32TaskbarManager();
void init();
virtual void setOverlayIcon(const Common::String &name, const Common::String &description);
virtual void setProgressValue(int val, int max);
virtual void setProgressValue(int completed, int total);
virtual void setProgressState(TaskbarProgressState state);
virtual void addRecent(const Common::String &name, const Common::String &description);
private:
HWND _hwnd;
ITaskbarList3 *_taskbar;
// Helper functions
bool isWin7OrLater();
LPWSTR ansiToUnicode(const char *s);
HWND getHwnd();
};
#endif
#endif // BACKEND_WIN32_TASKBAR_H

View file

@ -35,11 +35,11 @@ public:
* Values representing the taskbar progress state
*/
enum TaskbarProgressState {
NoProgress = 0,
Indeterminate = 1,
Normal = 2,
Error = 4,
Paused = 8
kTaskbarNoProgress = 0,
kTaskbarIndeterminate = 1,
kTaskbarNormal = 2,
kTaskbarError = 4,
kTaskbarPaused = 8
};
TaskbarManager() {}
@ -61,10 +61,10 @@ public:
/**
* Sets a progress value on the taskbar icon
*
* @param val The current progress value
* @param max The maximum progress value
* @param completed The current progress value.
* @param total The maximum progress value.
*/
virtual void setProgressValue(int val, int max) {}
virtual void setProgressValue(int completed, int total) {}
/**
* Sets the progress state on the taskbar icon