Ticket #9267: jump_list.patch

File jump_list.patch, 4.2 KB (added by SF/sven3000, 13 years ago)

Proof of concept jump list support patch.

  • backends/platform/sdl/win32/win32.cpp

     
    2626// Disable symbol overrides so that we can use system headers.
    2727#define FORBIDDEN_SYMBOL_ALLOW_ALL
    2828
    29 #include "common/scummsys.h"
    30 
    3129#ifdef WIN32
    3230
    3331#define WIN32_LEAN_AND_MEAN
     32#include <SDKDDKVer.h>
    3433#include <windows.h>
     34#include <shlobj.h>
    3535#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one...
    3636
     37
     38#include "common/scummsys.h"
     39#include "common/config-manager.h"
     40
     41
    3742#include "backends/platform/sdl/win32/win32.h"
    3843#include "backends/fs/windows/windows-fs-factory.h"
    3944
     
    6267
    6368#endif
    6469
     70namespace // Internal linkage
     71{
     72
     73// System.Title property key, values taken from http://msdn.microsoft.com/en-us/library/bb787584.aspx
     74const PROPERTYKEY PKEY_Title = { /* fmtid = */ { 0xF29F85E0, 0x4FF9, 0x1068, { 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 } }, /* propID = */ 2 };
     75
     76// Helper function to convert from ANSI to unicode strings. Caller must delete[] return value.
     77LPWSTR ansiToUnicode(const char *s)
     78{
     79        DWORD size = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, 0);
     80        if( size > 0 )
     81        {
     82                LPWSTR result = new WCHAR[size];
     83                if( MultiByteToWideChar(CP_ACP, 0, s, -1, result, size) != 0 )
     84                        return result;
     85        }
     86        return NULL;
     87}
     88
     89bool isWin7OrLater()
     90{
     91   OSVERSIONINFOEX versionInfo;
     92   DWORDLONG conditionMask = 0;
     93
     94   ZeroMemory(&versionInfo, sizeof(OSVERSIONINFOEX));
     95   versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
     96   versionInfo.dwMajorVersion = 6;
     97   versionInfo.dwMinorVersion = 1;
     98
     99   VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
     100   VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
     101
     102   return VerifyVersionInfo(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask);
     103}
     104
     105}
     106
    65107void OSystem_Win32::init() {
    66108#ifdef HIDE_CONSOLE
    67109        // console hiding for win32
     
    168210        }
    169211}
    170212
     213void OSystem_Win32::engineInit()
     214{
     215        OSystem_SDL::engineInit();
     216       
     217        // Calling SHAddToRecentDocs with an IShellLink is only supported for jump list purposes in Windows 7,
     218        // so we don't call it in older versions of Windows.
     219        if (isWin7OrLater()) {
     220                // ANSI version doesn't seem to work correctly with Win7 jump lists, so explicitly use Unicode interface.
     221                IShellLinkW *link;
     222
     223                // Get the ScummVM executable path.
     224                WCHAR path[MAX_PATH];
     225                GetModuleFileNameW(NULL, path, MAX_PATH);
     226
     227                // Create a shell link.
     228                if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&link)))) {
     229                        // Convert game name and description to Unicode.
     230                        LPWSTR game = ansiToUnicode(ConfMan.getActiveDomainName().c_str());
     231                        LPWSTR description = ansiToUnicode(ConfMan.get("description").c_str());
     232
     233                        // Set link properties.
     234                        link->SetPath(path);
     235                        link->SetArguments(game);
     236                        link->SetIconLocation(path, 0); // There's no way to get a game-specific icon, is there?
     237
     238                        // The link's display name must be set via property store.
     239                        IPropertyStore* propStore;
     240                        HRESULT hr = link->QueryInterface(&propStore);
     241                        if (SUCCEEDED(hr)) {
     242                                PROPVARIANT pv;
     243                                pv.vt = VT_LPWSTR;   
     244                                pv.pwszVal = description;
     245
     246                                hr = propStore->SetValue(PKEY_Title, pv);
     247
     248                                propStore->Commit();   
     249                                propStore->Release();
     250                        }
     251
     252                        // SHAddToRecentDocs will cause the games to be added to the Recent list, allowing the
     253                        // user to pin them.
     254                        SHAddToRecentDocs(SHARD_LINK, link);
     255                        link->Release();
     256                        delete[] game;
     257                        delete[] description;
     258                }
     259        }
     260}
     261
    171262#endif
  • backends/platform/sdl/win32/win32.h

     
    3131class OSystem_Win32 : public OSystem_SDL {
    3232public:
    3333        virtual void init();
     34        virtual void engineInit();
    3435
    3536protected:
    3637        virtual Common::String getDefaultConfigFileName();