From: sdottaka Date: Sun, 26 Apr 2015 12:53:39 +0000 (+0900) Subject: PropShell.*: Add Register/Unregister shell extension buttons on Shell Options dialog X-Git-Tag: 2.16.5~1459^2~2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=389ef200a7334245cd092f8bb39c2a98a3c5512f;p=winmerge-jp%2Fwinmerge-jp.git PropShell.*: Add Register/Unregister shell extension buttons on Shell Options dialog --HG-- branch : stable --- diff --git a/Src/Merge.rc b/Src/Merge.rc index 814bd0f0a..f9cb5c324 100644 --- a/Src/Merge.rc +++ b/Src/Merge.rc @@ -1836,13 +1836,15 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION CAPTION "Shell Integration" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - GROUPBOX "Explorer",IDC_STATIC,7,7,218,46 + GROUPBOX "Explorer",IDC_STATIC,7,7,218,80 CONTROL "E&nable advanced menu",IDC_EXPLORER_ADVANCED,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,27,28,190,10 CONTROL "In&clude subfolders by default",IDC_EXPLORER_SUBFOLDERS, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,38,190,10 CONTROL "&Add to context menu",IDC_EXPLORER_CONTEXT,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,17,18,200,10 + PUSHBUTTON "&Register shell extension",IDC_REGISTER_SHELLEXTENSION,17,48,200,14 + PUSHBUTTON "&Unregister shell extension",IDC_UNREGISTER_SHELLEXTENSION,17,64,200,14 END IDD_PROPPAGE_COMPARE_FOLDER DIALOGEX 0, 0, 235, 205 diff --git a/Src/PropShell.cpp b/Src/PropShell.cpp index 1b144b295..0d2deac53 100644 --- a/Src/PropShell.cpp +++ b/Src/PropShell.cpp @@ -12,6 +12,8 @@ #include "OptionsDef.h" #include "OptionsMgr.h" #include "OptionsPanel.h" +#include "Environment.h" +#include "paths.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -31,6 +33,49 @@ static LPCTSTR f_RegDir = _T("Software\\Thingamahoochie\\WinMerge"); static LPCTSTR f_RegValueEnabled = _T("ContextMenuEnabled"); static LPCTSTR f_RegValuePath = _T("Executable"); +static bool IsShellExtensionRegistered() +{ + HKEY hKey; + if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID\\{4E716236-AA30-4C65-B225-D68BBA81E9C2}"), 0, KEY_QUERY_VALUE, &hKey)) { + RegCloseKey(hKey); + return true; + } + return false; +} + +static bool RegisterShellExtension(bool unregister) +{ + TCHAR szSystem32[260] = { 0 }; + TCHAR szSysWow64[260] = { 0 }; + GetSystemDirectory(szSystem32, sizeof(szSystem32) / sizeof(szSystem32[0])); + GetSystemWow64Directory(szSysWow64, sizeof(szSysWow64) / sizeof(szSysWow64[0])); + + String progpath = env_GetProgPath(); + String regsvr32 = paths_ConcatPath(szSystem32, _T("regsvr32.exe")); + String args; + SHELLEXECUTEINFO sei = { sizeof(sei) }; + sei.lpVerb = _T("runas"); + if (szSysWow64[0]) + { + args = (unregister ? _T("/s /u \"") : _T("/s \"")) + paths_ConcatPath(progpath, _T("ShellExtensionX64.dll")) + _T("\""); + sei.lpFile = regsvr32.c_str(); + sei.lpParameters = args.c_str(); + ShellExecuteEx(&sei); + + regsvr32 = paths_ConcatPath(szSysWow64, _T("regsvr32.exe")); + args = (unregister ? _T("/s /u \"") : _T("/s \"")) + paths_ConcatPath(progpath, _T("ShellExtensionU.dll")) + _T("\""); + sei.lpFile = regsvr32.c_str(); + sei.lpParameters = args.c_str(); + return !!ShellExecuteEx(&sei); + } + else + { + args = (unregister ? _T("/s /u \"") : _T("/s \"")) + paths_ConcatPath(progpath, _T("ShellExtensionU.dll")) + _T("\""); + sei.lpFile = regsvr32.c_str(); + sei.lpParameters = args.c_str(); + return !!ShellExecuteEx(&sei); + } +} PropShell::PropShell(COptionsMgr *optionsMgr) : OptionsPanel(optionsMgr, PropShell::IDD) @@ -45,12 +90,22 @@ BOOL PropShell::OnInitDialog() theApp.TranslateDialog(m_hWnd); CPropertyPage::OnInitDialog(); +#ifndef BCM_SETSHIELD +#define BCM_SETSHIELD (0x1600/*BCM_FIRST*/ + 0x000C) +#endif + + ::SendMessage(GetDlgItem(IDC_REGISTER_SHELLEXTENSION)->m_hWnd, BCM_SETSHIELD, 0, TRUE); + ::SendMessage(GetDlgItem(IDC_UNREGISTER_SHELLEXTENSION)->m_hWnd, BCM_SETSHIELD, 0, TRUE); + // Update shell extension checkboxes + UpdateButtons(); GetContextRegValues(); AdvancedContextMenuCheck(); SubfolderOptionCheck(); UpdateData(FALSE); + SetTimer(0, 1000, NULL); + return TRUE; // return TRUE unless you set the focus to a control } @@ -67,6 +122,9 @@ void PropShell::DoDataExchange(CDataExchange* pDX) BEGIN_MESSAGE_MAP(PropShell, CPropertyPage) //{{AFX_MSG_MAP(PropShell) ON_BN_CLICKED(IDC_EXPLORER_CONTEXT, OnAddToExplorer) + ON_BN_CLICKED(IDC_REGISTER_SHELLEXTENSION, OnRegisterShellExtension) + ON_BN_CLICKED(IDC_UNREGISTER_SHELLEXTENSION, OnUnregisterShellExtension) + ON_WM_TIMER() //}}AFX_MSG_MAP END_MESSAGE_MAP() @@ -118,6 +176,7 @@ void PropShell::OnAddToExplorer() { AdvancedContextMenuCheck(); SubfolderOptionCheck(); + UpdateButtons(); } /// Saves given path to registry for ShellExtension, and Context Menu settings @@ -175,11 +234,8 @@ void PropShell::SaveMergePath() /// Enable/Disable "Advanced menu" checkbox. void PropShell::AdvancedContextMenuCheck() { - if (IsDlgButtonChecked(IDC_EXPLORER_CONTEXT)) - GetDlgItem(IDC_EXPLORER_ADVANCED)->EnableWindow(TRUE); - else + if (!IsDlgButtonChecked(IDC_EXPLORER_CONTEXT)) { - GetDlgItem(IDC_EXPLORER_ADVANCED)->EnableWindow(FALSE); CheckDlgButton(IDC_EXPLORER_ADVANCED, FALSE); m_bContextAdvanced = FALSE; } @@ -188,12 +244,36 @@ void PropShell::AdvancedContextMenuCheck() /// Enable/Disable "Include subfolders by default" checkbox. void PropShell::SubfolderOptionCheck() { - if (IsDlgButtonChecked(IDC_EXPLORER_CONTEXT)) - GetDlgItem(IDC_EXPLORER_SUBFOLDERS)->EnableWindow(TRUE); - else + if (!IsDlgButtonChecked(IDC_EXPLORER_CONTEXT)) { - GetDlgItem(IDC_EXPLORER_SUBFOLDERS)->EnableWindow(FALSE); CheckDlgButton(IDC_EXPLORER_SUBFOLDERS, FALSE); m_bContextSubfolders = FALSE; } } + +void PropShell::UpdateButtons() +{ + bool registered = IsShellExtensionRegistered(); + GetDlgItem(IDC_EXPLORER_CONTEXT)->EnableWindow(registered); + GetDlgItem(IDC_REGISTER_SHELLEXTENSION)->EnableWindow(!registered); + GetDlgItem(IDC_UNREGISTER_SHELLEXTENSION)->EnableWindow(registered); + GetDlgItem(IDC_EXPLORER_ADVANCED)->EnableWindow( + GetDlgItem(IDC_EXPLORER_CONTEXT)->IsWindowEnabled() && IsDlgButtonChecked(IDC_EXPLORER_CONTEXT)); + GetDlgItem(IDC_EXPLORER_SUBFOLDERS)->EnableWindow( + GetDlgItem(IDC_EXPLORER_CONTEXT)->IsWindowEnabled() && IsDlgButtonChecked(IDC_EXPLORER_CONTEXT)); +} + +void PropShell::OnRegisterShellExtension() +{ + RegisterShellExtension(false); +} + +void PropShell::OnUnregisterShellExtension() +{ + RegisterShellExtension(true); +} + +void PropShell::OnTimer(UINT_PTR nIDEvent) +{ + UpdateButtons(); +} diff --git a/Src/PropShell.h b/Src/PropShell.h index d189d337b..45c10b50b 100644 --- a/Src/PropShell.h +++ b/Src/PropShell.h @@ -34,10 +34,14 @@ public: protected: virtual BOOL OnInitDialog(); afx_msg void OnAddToExplorer(); + afx_msg void OnRegisterShellExtension(); + afx_msg void OnUnregisterShellExtension(); + afx_msg void OnTimer(UINT_PTR nIDEvent); void GetContextRegValues(); void AdvancedContextMenuCheck(); void SubfolderOptionCheck(); + void UpdateButtons(); DECLARE_MESSAGE_MAP() diff --git a/Src/resource.h b/Src/resource.h index d6ead2f51..fa359ae48 100644 --- a/Src/resource.h +++ b/Src/resource.h @@ -469,6 +469,8 @@ #define IDC_COLORSCHEME_GITHUBBITBUCKET 1355 #define IDC_FINDDLG_DONTCLOSE 1356 #define IDC_PATH_COMPARING 1357 +#define IDC_REGISTER_SHELLEXTENSION 1358 +#define IDC_UNREGISTER_SHELLEXTENSION 1359 #define IDC_EDIT_WHOLE_WORD 8603 #define IDC_EDIT_MATCH_CASE 8604 #define IDC_EDIT_FINDTEXT 8605 @@ -1171,7 +1173,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 242 #define _APS_NEXT_COMMAND_VALUE 33273 -#define _APS_NEXT_CONTROL_VALUE 1359 +#define _APS_NEXT_CONTROL_VALUE 1361 #define _APS_NEXT_SYMED_VALUE 115 #endif #endif