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.
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
)
74 BOOL
CSetOverlayHandlers::OnInitDialog()
76 ISettingsPropPage::OnInitDialog();
85 void CSetOverlayHandlers::OnChange()
91 BOOL
CSetOverlayHandlers::OnApply()
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
);
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
130 int nInstalledOverlayhandlers
= 0;
131 // scan the registry for installed overlay handlers
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
);
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
,
157 &dwType
, value
, &dwSize
) == ERROR_SUCCESS
)
159 if ((dwSize
> 10)&&(value
[0] == '{'))
160 nInstalledOverlayhandlers
++;
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();
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
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
;
198 if (!sInfo2
.IsEmpty())
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();