From c78cc88c273c0ad65a18ae2f272069c340790d25 Mon Sep 17 00:00:00 2001 From: sdottaka Date: Mon, 15 Apr 2013 19:22:16 +0900 Subject: [PATCH] Add support for Windows 7 jump list --- Src/JumpList.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++ Src/JumpList.h | 18 +++++++++ Src/MainFrm.cpp | 37 +++++++++++++++++++ Src/Merge.cpp | 3 ++ Src/Merge.vcproj | 30 +++++++++++++++ Src/Merge.vcxproj | 11 ++++++ Src/Merge.vcxproj.filters | 6 +++ 7 files changed, 199 insertions(+) create mode 100644 Src/JumpList.cpp create mode 100644 Src/JumpList.h diff --git a/Src/JumpList.cpp b/Src/JumpList.cpp new file mode 100644 index 000000000..90f24a889 --- /dev/null +++ b/Src/JumpList.cpp @@ -0,0 +1,94 @@ +/** + * @file JumpList.cpp + * + * @brief Implementation file for JumpList helper functions. + * + */ +#include "JumpList.h" +#include +#include +#if _MSC_VER >= 1600 +#include +#include +#endif +#include "unicoder.h" + +namespace +{ + +std::wstring g_appid; +TCHAR g_exe_path[260]; + +IShellLink *CreateShellLink(const String& app_path, const String& params, const String& title, const String& desc, int icon_index) +{ +#if _MSC_VER >= 1600 + IShellLink *pShellLink = NULL; + if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + IID_IShellLink, (void **)&pShellLink))) + return NULL; + + String app_path2(app_path); + if (app_path.empty()) + { + if (g_exe_path[0] == '\0') + GetModuleFileName(NULL, g_exe_path, sizeof(g_exe_path)); + app_path2 = g_exe_path; + } + pShellLink->SetPath(app_path2.c_str()); + pShellLink->SetIconLocation(app_path2.c_str(), icon_index); + pShellLink->SetArguments(params.c_str()); + pShellLink->SetDescription(desc.c_str()); + + IPropertyStore *pPS = NULL; + if (SUCCEEDED(pShellLink->QueryInterface(IID_IPropertyStore, (void **)&pPS))) + { + std::wstring title2 = ucr::toUTF16((title.empty()) ? params : title); + PROPVARIANT pv; + InitPropVariantFromString(title2.c_str(), &pv); + pPS->SetValue(PKEY_Title, pv); + PropVariantClear(&pv); + pPS->Commit(); + pPS->Release(); + } + + return pShellLink; +#else + return NULL; +#endif +} + +} + +namespace JumpList +{ + +bool SetCurrentProcessExplicitAppUserModelID(const std::wstring& appid) +{ + g_appid = appid; + HMODULE hLibrary = GetModuleHandle(_T("shell32.dll")); + if (!hLibrary) + return false; + HRESULT (__stdcall *pfnSetCurrentProcessExplicitAppUserModelID)(PCWSTR AppID) = + (HRESULT (__stdcall *)(PCWSTR))GetProcAddress(hLibrary, "SetCurrentProcessExplicitAppUserModelID"); + if (!pfnSetCurrentProcessExplicitAppUserModelID) + return false; + return pfnSetCurrentProcessExplicitAppUserModelID(appid.c_str()) == S_OK; +} + +bool AddToRecentDocs(const String& app_path, const String& params, const String& title, const String& desc, int icon_index) +{ +#if _MSC_VER >= 1600 + SHARDAPPIDINFOLINK saiil; + saiil.pszAppID = g_appid.c_str(); + saiil.psl = CreateShellLink(app_path, params, title, desc, icon_index); + if (!saiil.psl) + return false; + SHAddToRecentDocs(SHARD_APPIDINFOLINK, &saiil); + saiil.psl->Release(); + return true; +#else + return false; +#endif +} + +} diff --git a/Src/JumpList.h b/Src/JumpList.h new file mode 100644 index 000000000..124258f06 --- /dev/null +++ b/Src/JumpList.h @@ -0,0 +1,18 @@ +/** + * @file JumpList.h + * + * @brief Declaration file for JumpList helper functions. + * + */ +#ifndef _JUMPLIST_H_ +#define _JUMPLIST_H_ + +#include "UnicodeString.h" + +namespace JumpList +{ + bool SetCurrentProcessExplicitAppUserModelID(const std::wstring& appid); + bool AddToRecentDocs(const String& app_path = _T(""), const String& params = _T(""), const String& title = _T(""), const String& desc = _T(""), int icon_index = 0); +} + +#endif diff --git a/Src/MainFrm.cpp b/Src/MainFrm.cpp index 9ec8c1df4..c0f0afa6d 100644 --- a/Src/MainFrm.cpp +++ b/Src/MainFrm.cpp @@ -79,6 +79,7 @@ #include "MergeCmdLineInfo.h" #include "SyntaxColorsUtil.h" #include "TFile.h" +#include "JumpList.h" #include using std::vector; @@ -1083,6 +1084,35 @@ void CMainFrame::OnOptions() } } +static bool AddToRecentDocs(const PathContext& paths, const unsigned flags[], bool recurse, const String& filter) +{ + String params, title; + for (int nIndex = 0; nIndex < paths.GetSize(); ++nIndex) + { + if (flags[nIndex] & FFILEOPEN_READONLY) + { + switch (nIndex) + { + case 0: params += _T("/wl "); break; + case 1: params += paths.GetSize() == 2 ? _T("/wr ") : _T("/wm "); break; + case 2: params += _T("/wr "); break; + } + } + params += _T("\"") + paths[nIndex] + _T("\" "); + + String path = paths[nIndex]; + paths_normalize(path); + title += paths_FindFileName(path); + if (nIndex < paths.GetSize() - 1) + title += _T(" - "); + } + if (recurse) + params += _T("/r "); + if (!filter.empty()) + params += _T("/f \"") + filter + _T("\" "); + return JumpList::AddToRecentDocs(_T(""), params, title, params, 0); +} + /** * @brief Begin a diff: open dirdoc if it is directories, else open a mergedoc for editing. * @param [in] pszLeft Left-side path. @@ -1369,6 +1399,13 @@ BOOL CMainFrame::DoFileOpen(PathContext * pFiles /*=NULL*/, ShowMergeDoc(pDirDoc, files.GetSize(), fileloc, dwFlags, infoUnpacker); } + + if (!((dwFlags[0] & FFILEOPEN_NOMRU) && (dwFlags[0] & FFILEOPEN_CMDLINE))) + { + String filter = GetOptionsMgr()->GetString(OPT_FILEFILTER_CURRENT); + AddToRecentDocs(files, (unsigned *)dwFlags, bRecurse, filter); + } + return TRUE; } diff --git a/Src/Merge.cpp b/Src/Merge.cpp index fbd38a23a..0308c7b01 100644 --- a/Src/Merge.cpp +++ b/Src/Merge.cpp @@ -59,6 +59,7 @@ #include "MergeCmdLineInfo.h" #include "ConflictFileParser.h" #include "codepage.h" +#include "JumpList.h" // For shutdown cleanup #include "charsets.h" @@ -224,6 +225,8 @@ BOOL CMergeApp::InitInstance() if (pfnSetDllDirectoryA) pfnSetDllDirectoryA(""); + JumpList::SetCurrentProcessExplicitAppUserModelID(L"Thingamahoochie.WinMerge"); + InitCommonControls(); // initialize common control library CWinApp::InitInstance(); // call parent class method diff --git a/Src/Merge.vcproj b/Src/Merge.vcproj index b2098be3e..ee175566d 100644 --- a/Src/Merge.vcproj +++ b/Src/Merge.vcproj @@ -5488,6 +5488,33 @@ RelativePath=".\HexMergeView.cpp"> + + + + + + + + + + + + + + @@ -7569,6 +7596,9 @@ RelativePath="IOptionsPanel.h"> + + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + Disabled @@ -8689,6 +8699,7 @@ + diff --git a/Src/Merge.vcxproj.filters b/Src/Merge.vcxproj.filters index c28d7498c..12008c8f0 100644 --- a/Src/Merge.vcxproj.filters +++ b/Src/Merge.vcxproj.filters @@ -736,6 +736,9 @@ GUI\Source Files + + GUI\Source Files + @@ -1362,6 +1365,9 @@ GUI\Header Files + + GUI\Header Files + -- 2.11.0