4 * @brief Implementation file for JumpList helper functions.
9 #pragma warning (push) // prevent "warning C4091: 'typedef ': ignored on left of 'tagGPFIDL_FLAGS' when no variable is declared"
10 #pragma warning (disable:4091) // VC bug when using XP enabled toolsets.
13 #include <propvarutil.h>
21 wchar_t g_exe_path[260];
23 IShellLinkW *CreateShellLink(const std::wstring& app_path, const std::wstring& params, const std::wstring& title, const std::wstring& desc, int icon_index)
25 IShellLinkW *pShellLink = nullptr;
26 if (FAILED(CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
27 IID_IShellLinkW, (void **)&pShellLink)))
30 std::wstring app_path2(app_path);
33 if (g_exe_path[0] == '\0')
34 GetModuleFileNameW(nullptr, g_exe_path, sizeof(g_exe_path)/sizeof(g_exe_path[0]));
35 app_path2 = g_exe_path;
37 pShellLink->SetPath(app_path2.c_str());
38 pShellLink->SetIconLocation(app_path2.c_str(), icon_index);
39 pShellLink->SetArguments(params.c_str());
40 pShellLink->SetDescription(desc.c_str());
42 IPropertyStore *pPS = nullptr;
43 if (SUCCEEDED(pShellLink->QueryInterface(IID_IPropertyStore, (void **)&pPS)))
46 if (SUCCEEDED(InitPropVariantFromString(title.c_str(), &pv)))
48 pPS->SetValue(PKEY_Title, pv);
49 PropVariantClear(&pv);
63 bool SetCurrentProcessExplicitAppUserModelID(const std::wstring& appid)
66 HMODULE hLibrary = GetModuleHandle(_T("shell32.dll"));
67 if (hLibrary == nullptr)
69 HRESULT (__stdcall *pfnSetCurrentProcessExplicitAppUserModelID)(PCWSTR AppID) =
70 (HRESULT (__stdcall *)(PCWSTR))GetProcAddress(hLibrary, "SetCurrentProcessExplicitAppUserModelID");
71 if (pfnSetCurrentProcessExplicitAppUserModelID == nullptr)
73 return pfnSetCurrentProcessExplicitAppUserModelID(appid.c_str()) == S_OK;
76 bool AddToRecentDocs(const String& app_path, const String& params, const String& title, const String& desc, int icon_index)
78 SHARDAPPIDINFOLINK saiil;
79 saiil.pszAppID = g_appid.c_str();
81 saiil.psl = CreateShellLink(app_path, params, title, desc, icon_index);
83 saiil.psl = (IShellLink *)CreateShellLink(ucr::toUTF16(app_path), ucr::toUTF16(params), ucr::toUTF16(title), ucr::toUTF16(desc), icon_index);
85 if (saiil.psl == nullptr)
87 SHAddToRecentDocs(SHARD_APPIDINFOLINK, &saiil);
92 std::vector<Item> GetRecentDocs(size_t nMaxItems)
94 std::vector<Item> list;
95 IApplicationDocumentLists *pDocumentLists = nullptr;
96 if (FAILED(CoCreateInstance(CLSID_ApplicationDocumentLists, nullptr, CLSCTX_INPROC_SERVER,
97 IID_IApplicationDocumentLists, (void **)&pDocumentLists)))
99 pDocumentLists->SetAppID(g_appid.c_str());
101 IObjectArray *pObjectArray;
102 if (SUCCEEDED(pDocumentLists->GetList(ADLT_RECENT, static_cast<UINT>(nMaxItems), IID_IObjectArray, (void **)&pObjectArray)))
105 if (SUCCEEDED(pObjectArray->GetCount(&nObjects)))
107 for (UINT i = 0; i < nObjects; ++i)
109 IShellLinkW *pShellLink;
110 if (SUCCEEDED(pObjectArray->GetAt(i, IID_IShellLinkW, (void **)&pShellLink)))
112 wchar_t szPath[MAX_PATH];
113 wchar_t szDescription[MAX_PATH];
114 wchar_t szArguments[MAX_PATH * 6];
115 pShellLink->GetPath(szPath, sizeof(szPath) / sizeof(szPath[0]), nullptr, SLGP_RAWPATH);
116 pShellLink->GetDescription(szDescription, sizeof(szDescription) / sizeof(szDescription[0]));
117 pShellLink->GetArguments(szArguments, sizeof(szArguments) / sizeof(szArguments[0]));
118 IPropertyStore *pPS = nullptr;
119 if (SUCCEEDED(pShellLink->QueryInterface(IID_IPropertyStore, (void **)&pPS)))
122 if (SUCCEEDED(pPS->GetValue(PKEY_Title, &pv)))
124 list.push_back(Item(ucr::toTString(szPath), ucr::toTString(szArguments), ucr::toTString(pv.bstrVal), ucr::toTString(szDescription)));
125 PropVariantClear(&pv);
129 pShellLink->Release();
133 pObjectArray->Release();
135 pDocumentLists->Release();