diff options
| author | Littleboy | 2011-03-31 04:46:36 -0400 | 
|---|---|---|
| committer | Julien | 2011-06-16 10:30:06 -0400 | 
| commit | c0ec09ac66162d253ab16e1fb9b3a85dfdd176d7 (patch) | |
| tree | e11799a41edd53f5317f01c35a2cc81542f6b8c2 | |
| parent | f67975a487704828a2005a26ed6725b01c2554db (diff) | |
| download | scummvm-rg350-c0ec09ac66162d253ab16e1fb9b3a85dfdd176d7.tar.gz scummvm-rg350-c0ec09ac66162d253ab16e1fb9b3a85dfdd176d7.tar.bz2 scummvm-rg350-c0ec09ac66162d253ab16e1fb9b3a85dfdd176d7.zip  | |
BACKENDS: Implement Win32 taskbar progress state and recent list
| -rw-r--r-- | backends/platform/sdl/win32/win32.cpp | 1 | ||||
| -rw-r--r-- | backends/taskbar/win32/win32-taskbar.cpp | 144 | ||||
| -rw-r--r-- | backends/taskbar/win32/win32-taskbar.h | 19 | ||||
| -rw-r--r-- | common/taskbar.h | 16 | 
4 files changed, 164 insertions, 16 deletions
diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp index 0fd2fbbd1d..bb254786d5 100644 --- a/backends/platform/sdl/win32/win32.cpp +++ b/backends/platform/sdl/win32/win32.cpp @@ -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(); diff --git a/backends/taskbar/win32/win32-taskbar.cpp b/backends/taskbar/win32/win32-taskbar.cpp index 7f76791dfa..1ddbde10bc 100644 --- a/backends/taskbar/win32/win32-taskbar.cpp +++ b/backends/taskbar/win32/win32-taskbar.cpp @@ -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"); -}
\ No newline at end of file +	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 diff --git a/backends/taskbar/win32/win32-taskbar.h b/backends/taskbar/win32/win32-taskbar.h index 20c1a8d383..d0871d36d2 100644 --- a/backends/taskbar/win32/win32-taskbar.h +++ b/backends/taskbar/win32/win32-taskbar.h @@ -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 diff --git a/common/taskbar.h b/common/taskbar.h index e29fcdcb36..ea1d218724 100644 --- a/common/taskbar.h +++ b/common/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  | 
