OSDN Git Service

Fix adding garbage item into Win7 jump list on WinMerge ANSI build
[winmerge-jp/winmerge-jp.git] / Src / JumpList.cpp
1 /** 
2  * @file  JumpList.cpp
3  *
4  * @brief Implementation file for JumpList helper functions.
5  *
6  */
7 #include "JumpList.h"
8 #include <ObjBase.h>
9 #include <ShlObj.h>
10 #if _MSC_VER >= 1600
11 #include <propvarutil.h>
12 #include <propkey.h>
13 #endif
14 #include "unicoder.h"
15
16 namespace
17 {
18
19 std::wstring g_appid;
20 wchar_t g_exe_path[260];
21
22 IShellLinkW *CreateShellLink(const std::wstring& app_path, const std::wstring& params, const std::wstring& title, const std::wstring& desc, int icon_index)
23 {
24 #if _MSC_VER >= 1600
25         IShellLinkW *pShellLink = NULL;
26         if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
27                                     IID_IShellLinkW, (void **)&pShellLink)))
28                 return NULL;
29
30         std::wstring app_path2(app_path);
31         if (app_path.empty())
32         {
33                 if (g_exe_path[0] == '\0')
34                         GetModuleFileNameW(NULL, g_exe_path, sizeof(g_exe_path));
35                 app_path2 = g_exe_path;
36         }
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());
41
42         IPropertyStore *pPS = NULL;
43         if (SUCCEEDED(pShellLink->QueryInterface(IID_IPropertyStore, (void **)&pPS)))
44         {
45                 PROPVARIANT pv;
46                 InitPropVariantFromString(title.c_str(), &pv);
47                 pPS->SetValue(PKEY_Title, pv);
48                 PropVariantClear(&pv);
49                 pPS->Commit();
50                 pPS->Release();
51         }
52
53         return pShellLink;
54 #else
55         return NULL;
56 #endif
57 }
58
59 }
60
61 namespace JumpList
62 {
63
64 bool SetCurrentProcessExplicitAppUserModelID(const std::wstring& appid)
65 {
66         g_appid = appid;
67         HMODULE hLibrary = GetModuleHandle(_T("shell32.dll"));
68         if (!hLibrary)
69                 return false;
70         HRESULT (__stdcall *pfnSetCurrentProcessExplicitAppUserModelID)(PCWSTR AppID) = 
71                 (HRESULT (__stdcall *)(PCWSTR))GetProcAddress(hLibrary, "SetCurrentProcessExplicitAppUserModelID");
72         if (!pfnSetCurrentProcessExplicitAppUserModelID)
73                 return false;
74         return pfnSetCurrentProcessExplicitAppUserModelID(appid.c_str()) == S_OK;
75 }
76
77 bool AddToRecentDocs(const String& app_path, const String& params, const String& title, const String& desc, int icon_index)
78 {
79 #if _MSC_VER >= 1600
80         SHARDAPPIDINFOLINK saiil;
81         saiil.pszAppID = g_appid.c_str();
82 #ifdef _UNICODE
83         saiil.psl = CreateShellLink(app_path, params, title, desc, icon_index);
84 #else
85         saiil.psl = (IShellLink *)CreateShellLink(ucr::toUTF16(app_path), ucr::toUTF16(params), ucr::toUTF16(title), ucr::toUTF16(desc), icon_index);
86 #endif
87         if (!saiil.psl)
88                 return false;
89         SHAddToRecentDocs(SHARD_APPIDINFOLINK, &saiil);
90         saiil.psl->Release();
91         return true;
92 #else
93         return false;
94 #endif
95 }
96
97 }