OSDN Git Service

Add support for Windows 7 jump list
authorsdottaka <none@none>
Mon, 15 Apr 2013 10:22:16 +0000 (19:22 +0900)
committersdottaka <none@none>
Mon, 15 Apr 2013 10:22:16 +0000 (19:22 +0900)
Src/JumpList.cpp [new file with mode: 0644]
Src/JumpList.h [new file with mode: 0644]
Src/MainFrm.cpp
Src/Merge.cpp
Src/Merge.vcproj
Src/Merge.vcxproj
Src/Merge.vcxproj.filters

diff --git a/Src/JumpList.cpp b/Src/JumpList.cpp
new file mode 100644 (file)
index 0000000..90f24a8
--- /dev/null
@@ -0,0 +1,94 @@
+/** 
+ * @file  JumpList.cpp
+ *
+ * @brief Implementation file for JumpList helper functions.
+ *
+ */
+#include "JumpList.h"
+#include <ObjBase.h>
+#include <ShlObj.h>
+#if _MSC_VER >= 1600
+#include <propvarutil.h>
+#include <propkey.h>
+#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 (file)
index 0000000..124258f
--- /dev/null
@@ -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
index 9ec8c1d..c0f0afa 100644 (file)
@@ -79,6 +79,7 @@
 #include "MergeCmdLineInfo.h"
 #include "SyntaxColorsUtil.h"
 #include "TFile.h"
+#include "JumpList.h"
 #include <Poco/Exception.h>
 
 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;
 }
 
index fbd38a2..0308c7b 100644 (file)
@@ -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
 
index b2098be..ee17556 100644 (file)
                                        RelativePath=".\HexMergeView.cpp">\r
                                </File>\r
                                <File\r
+                                       RelativePath=".\JumpList.cpp">\r
+                                       <FileConfiguration\r
+                                               Name="UnicodeRelease|Win32">\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"/>\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="UnicodeDebug|Win32">\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"/>\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32">\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"/>\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32">\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"/>\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
                                        RelativePath="Common\LanguageSelect.cpp">\r
                                        <FileConfiguration\r
                                                Name="UnicodeRelease|Win32">\r
                                        RelativePath="IOptionsPanel.h">\r
                                </File>\r
                                <File\r
+                                       RelativePath=".\JumpList.h">\r
+                               </File>\r
+                               <File\r
                                        RelativePath="Common\LanguageSelect.h">\r
                                </File>\r
                                <File\r
index ea19cf7..30acf28 100644 (file)
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='X64 Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='X64 Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
     </ClCompile>\r
+    <ClCompile Include="JumpList.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='UnicodeDebug|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='UnicodeRelease|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='UnicodeDebug|x64'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='UnicodeRelease|x64'">NotUsing</PrecompiledHeader>\r
+    </ClCompile>\r
     <ClCompile Include="LineFiltersDlg.cpp" />\r
     <ClCompile Include="LineFiltersList.cpp">\r
       <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>\r
     <ClInclude Include="IntToIntMap.h" />\r
     <ClInclude Include="IOptionsPanel.h" />\r
     <ClInclude Include="Common\LanguageSelect.h" />\r
+    <ClInclude Include="JumpList.h" />\r
     <ClInclude Include="LineFiltersDlg.h" />\r
     <ClInclude Include="LineFiltersList.h" />\r
     <ClInclude Include="LoadSaveCodepageDlg.h" />\r
index c28d749..12008c8 100644 (file)
     <ClCompile Include="DirCompProgressBar.cpp">\r
       <Filter>GUI\Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="JumpList.cpp">\r
+      <Filter>GUI\Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="charsets.h">\r
     <ClInclude Include="DirCompProgressBar.h">\r
       <Filter>GUI\Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="JumpList.h">\r
+      <Filter>GUI\Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="res\binarydiff.ico">\r