Unbreak support Windows XP
[TortoiseGit.git] / src / TortoiseProc / Settings / SetOverlayHandlers.cpp
blobdced1d6021fd2ca81d7474a796a99d7d69d957b4
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2010, 2012, 2014 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "stdafx.h"
20 #include "TortoiseProc.h"
21 #include "SetOverlayHandlers.h"
24 IMPLEMENT_DYNAMIC(CSetOverlayHandlers, ISettingsPropPage)
25 CSetOverlayHandlers::CSetOverlayHandlers()
26 : ISettingsPropPage(CSetOverlayHandlers::IDD)
27 , m_bShowIgnoredOverlay(TRUE)
28 , m_bShowUnversionedOverlay(TRUE)
29 , m_bShowAddedOverlay(TRUE)
30 , m_bShowLockedOverlay(TRUE)
31 , m_bShowReadonlyOverlay(TRUE)
32 , m_bShowDeletedOverlay(TRUE)
34 m_regShowIgnoredOverlay = CRegDWORD(_T("Software\\TortoiseOverlays\\ShowIgnoredOverlay"), TRUE);
35 m_regShowUnversionedOverlay = CRegDWORD(_T("Software\\TortoiseOverlays\\ShowUnversionedOverlay"), TRUE);
36 m_regShowAddedOverlay = CRegDWORD(_T("Software\\TortoiseOverlays\\ShowAddedOverlay"), TRUE);
37 m_regShowLockedOverlay = CRegDWORD(_T("Software\\TortoiseOverlays\\ShowLockedOverlay"), TRUE);
38 m_regShowReadonlyOverlay = CRegDWORD(_T("Software\\TortoiseOverlays\\ShowReadonlyOverlay"), TRUE);
39 m_regShowDeletedOverlay = CRegDWORD(_T("Software\\TortoiseOverlays\\ShowDeletedOverlay"), TRUE);
41 m_bShowIgnoredOverlay = m_regShowIgnoredOverlay;
42 m_bShowUnversionedOverlay = m_regShowUnversionedOverlay;
43 m_bShowAddedOverlay = m_regShowAddedOverlay;
44 m_bShowLockedOverlay = m_regShowLockedOverlay;
45 m_bShowReadonlyOverlay = m_regShowReadonlyOverlay;
46 m_bShowDeletedOverlay = m_regShowDeletedOverlay;
49 CSetOverlayHandlers::~CSetOverlayHandlers()
53 void CSetOverlayHandlers::DoDataExchange(CDataExchange* pDX)
55 ISettingsPropPage::DoDataExchange(pDX);
56 DDX_Check(pDX, IDC_SHOWIGNOREDOVERLAY, m_bShowIgnoredOverlay);
57 DDX_Check(pDX, IDC_SHOWUNVERSIONEDOVERLAY, m_bShowUnversionedOverlay);
58 DDX_Check(pDX, IDC_SHOWADDEDOVERLAY, m_bShowAddedOverlay);
59 DDX_Check(pDX, IDC_SHOWLOCKEDOVERLAY, m_bShowLockedOverlay);
60 DDX_Check(pDX, IDC_SHOWREADONLYOVERLAY, m_bShowReadonlyOverlay);
61 DDX_Check(pDX, IDC_SHOWDELETEDOVERLAY, m_bShowDeletedOverlay);
64 BEGIN_MESSAGE_MAP(CSetOverlayHandlers, ISettingsPropPage)
65 ON_BN_CLICKED(IDC_SHOWIGNOREDOVERLAY, &CSetOverlayHandlers::OnChange)
66 ON_BN_CLICKED(IDC_SHOWUNVERSIONEDOVERLAY, &CSetOverlayHandlers::OnChange)
67 ON_BN_CLICKED(IDC_SHOWADDEDOVERLAY, &CSetOverlayHandlers::OnChange)
68 ON_BN_CLICKED(IDC_SHOWLOCKEDOVERLAY, &CSetOverlayHandlers::OnChange)
69 ON_BN_CLICKED(IDC_SHOWREADONLYOVERLAY, &CSetOverlayHandlers::OnChange)
70 ON_BN_CLICKED(IDC_SHOWDELETEDOVERLAY, &CSetOverlayHandlers::OnChange)
71 ON_BN_CLICKED(IDC_REGEDT, &CSetOverlayHandlers::OnBnClickedRegedt)
72 END_MESSAGE_MAP()
74 BOOL CSetOverlayHandlers::OnInitDialog()
76 ISettingsPropPage::OnInitDialog();
78 UpdateInfoLabel();
80 UpdateData(FALSE);
82 return TRUE;
85 void CSetOverlayHandlers::OnChange()
87 UpdateInfoLabel();
88 SetModified();
91 BOOL CSetOverlayHandlers::OnApply()
93 UpdateData();
95 if (DWORD(m_regShowIgnoredOverlay) != DWORD(m_bShowIgnoredOverlay))
96 m_restart = Restart_System;
97 Store (m_bShowIgnoredOverlay, m_regShowIgnoredOverlay);
99 if (DWORD(m_regShowUnversionedOverlay) != DWORD(m_bShowUnversionedOverlay))
100 m_restart = Restart_System;
101 Store (m_bShowUnversionedOverlay, m_regShowUnversionedOverlay);
103 if (DWORD(m_regShowAddedOverlay) != DWORD(m_bShowAddedOverlay))
104 m_restart = Restart_System;
105 Store (m_bShowAddedOverlay, m_regShowAddedOverlay);
107 if (DWORD(m_regShowLockedOverlay) != DWORD(m_bShowLockedOverlay))
108 m_restart = Restart_System;
109 Store (m_bShowLockedOverlay, m_regShowLockedOverlay);
111 if (DWORD(m_regShowReadonlyOverlay) != DWORD(m_bShowReadonlyOverlay))
112 m_restart = Restart_System;
113 Store (m_bShowReadonlyOverlay, m_regShowReadonlyOverlay);
115 if (DWORD(m_regShowDeletedOverlay) != DWORD(m_bShowDeletedOverlay))
116 m_restart = Restart_System;
117 Store (m_bShowDeletedOverlay, m_regShowDeletedOverlay);
120 SetModified(FALSE);
121 return ISettingsPropPage::OnApply();
124 int CSetOverlayHandlers::GetInstalledOverlays()
126 // if there are more than 12 overlay handlers installed, then that means not all
127 // of the overlay handlers can be shown. Windows chooses the ones first
128 // returned by RegEnumKeyEx() and just drops the ones that come last in
129 // that enumeration.
130 int nInstalledOverlayhandlers = 0;
131 // scan the registry for installed overlay handlers
132 HKEY hKey;
133 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
134 _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers"),
135 0, KEY_ENUMERATE_SUB_KEYS, &hKey)==ERROR_SUCCESS)
137 TCHAR value[2048] = { 0 };
138 TCHAR keystring[2048] = { 0 };
139 for (int i = 0, rc = ERROR_SUCCESS; rc == ERROR_SUCCESS; i++)
141 DWORD size = _countof(value);
142 FILETIME last_write_time;
143 rc = RegEnumKeyEx(hKey, i, value, &size, NULL, NULL, NULL, &last_write_time);
144 if (rc == ERROR_SUCCESS)
146 if (_tcsnicmp(&value[1], L"tortoise", 8) != 0)
148 // check if there's a 'default' entry with a guid
149 _tcscpy_s(keystring, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers\\"));
150 _tcscat_s(keystring, value);
151 DWORD dwType = 0;
152 DWORD dwSize = _countof(value); // the API docs only specify "The size of the destination data buffer",
153 // but better be safe than sorry using _countof instead of sizeof
154 if (SHGetValue(HKEY_LOCAL_MACHINE,
155 keystring,
156 NULL,
157 &dwType, value, &dwSize) == ERROR_SUCCESS)
159 if ((dwSize > 10)&&(value[0] == '{'))
160 nInstalledOverlayhandlers++;
165 RegCloseKey(hKey);
167 return nInstalledOverlayhandlers;
170 void CSetOverlayHandlers::UpdateInfoLabel()
172 CString sUnversioned, sNeedslock, sIgnored, sLocked;
173 GetDlgItemText(IDC_SHOWUNVERSIONEDOVERLAY, sUnversioned);
174 GetDlgItemText(IDC_SHOWREADONLYOVERLAY, sNeedslock);
175 GetDlgItemText(IDC_SHOWIGNOREDOVERLAY, sIgnored);
176 GetDlgItemText(IDC_SHOWLOCKEDOVERLAY, sLocked);
178 int nInstalledOverlays = GetInstalledOverlays();
179 CString sInfo;
180 sInfo.Format(IDS_SETTINGS_OVERLAYINFO, nInstalledOverlays);
182 const int nOverlayLimit = 3;
183 // max registered: drop the locked overlay
184 // max + 1 registered: drop the locked and the ignored overlay
185 // max + 2 registered: drop the locked, ignored and readonly overlay
186 // max + 3 or more registered: drop the locked, ignored, readonly and unversioned overlay
187 CString sInfo2;
188 if (nInstalledOverlays > nOverlayLimit+3)
189 sInfo2 += L", " + sUnversioned;
190 if (nInstalledOverlays > nOverlayLimit+2)
191 sInfo2 += L", " + sNeedslock;
192 if (nInstalledOverlays > nOverlayLimit+1)
193 sInfo2 += L", " + sIgnored;
194 if (nInstalledOverlays > nOverlayLimit)
195 sInfo2 += L", " + sLocked;
196 sInfo2.Trim(L" ,");
198 if (!sInfo2.IsEmpty())
200 CString sTemp;
201 sTemp.Format(IDS_SETTINGS_OVERLAYINFO2, (LPCWSTR)sInfo2);
202 sInfo += L"\n" + sTemp;
204 SetDlgItemText(IDC_HANDLERHINT, sInfo);
207 void CSetOverlayHandlers::OnBnClickedRegedt()
209 TCHAR szPath[MAX_PATH] = { 0 };
210 if (SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_WINDOWS | CSIDL_FLAG_CREATE, nullptr, SHGFP_TYPE_CURRENT, szPath)))
212 CString path = szPath;
213 path += L"\\regedit.exe";
215 // regedit stores the key it showed last in
216 // HKEY_Current_User\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\LastKey
217 // we set that here to
218 // HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers
219 // so when we start regedit, it will show that key on start
220 CRegString regLastKey(L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\LastKey");
221 regLastKey = L"Computer\\HKEY_Local_Machine\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers";
223 SHELLEXECUTEINFO si = { sizeof(SHELLEXECUTEINFO) };
224 si.hwnd = GetSafeHwnd();
225 si.lpVerb = L"open";
226 si.lpFile = path;
227 si.nShow = SW_SHOW;
228 ShellExecuteEx(&si);