BACKENDS: Implement Win32 taskbar progress state and recent list
This commit is contained in:
parent
f67975a487
commit
c0ec09ac66
4 changed files with 164 additions and 16 deletions
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue