OSDN Git Service

Merge with stable
[winmerge-jp/winmerge-jp.git] / Src / PropShell.cpp
1 /** 
2  * @file  PropShell.h
3  *
4  * @brief Implementation file for Shell Options dialog.
5  *
6  */
7 // ID line follows -- this is updated by SVN
8 // $Id: PropShell.cpp 6725 2009-05-09 14:31:24Z kimmov $
9
10 #include "stdafx.h"
11 #include "PropShell.h"
12 #include "Merge.h"
13 #include "RegKey.h"
14 #include "OptionsDef.h"
15 #include "OptionsMgr.h"
16 #include "OptionsPanel.h"
17 #include "DDXHelper.h"
18 #include "Constants.h"
19
20 #ifdef _DEBUG
21 #define new DEBUG_NEW
22 #undef THIS_FILE
23 static char THIS_FILE[] = __FILE__;
24 #endif
25
26 /// Flags for enabling and mode of extension
27 #define CONTEXT_F_ENABLED 0x01
28 #define CONTEXT_F_ADVANCED 0x02
29 #define CONTEXT_F_SUBFOLDERS 0x04
30
31 // registry values
32 static LPCTSTR f_RegValueEnabled = _T("ContextMenuEnabled");
33 static LPCTSTR f_RegValuePath = _T("Executable");
34
35
36 PropShell::PropShell(COptionsMgr *optionsMgr) 
37 : OptionsPanel(optionsMgr, PropShell::IDD)
38 , m_bEnableShellContextMenu(false)
39 , m_bContextAdded(false)
40 , m_bContextAdvanced(false)
41 , m_bContextSubfolders(false)
42 {
43 }
44
45 BOOL PropShell::OnInitDialog()
46 {
47         theApp.TranslateDialog(m_hWnd);
48         CPropertyPage::OnInitDialog();
49
50         // Update shell extension checkboxes
51         GetContextRegValues();
52         AdvancedContextMenuCheck();
53         SubfolderOptionCheck();
54         UpdateData(FALSE);
55
56         return TRUE;  // return TRUE  unless you set the focus to a control
57 }
58
59 void PropShell::DoDataExchange(CDataExchange* pDX)
60 {
61         CPropertyPage::DoDataExchange(pDX);
62         //{{AFX_DATA_MAP(PropShell)
63         DDX_Check(pDX, IDC_ENABLE_SHELL_CONTEXT_MENU, m_bEnableShellContextMenu);
64         DDX_Check(pDX, IDC_EXPLORER_CONTEXT, m_bContextAdded);
65         DDX_Check(pDX, IDC_EXPLORER_ADVANCED, m_bContextAdvanced);
66         DDX_Check(pDX, IDC_EXPLORER_SUBFOLDERS, m_bContextSubfolders);
67         //}}AFX_DATA_MAP
68 }
69
70 BEGIN_MESSAGE_MAP(PropShell, CPropertyPage)
71         //{{AFX_MSG_MAP(PropShell)
72         ON_BN_CLICKED(IDC_EXPLORER_CONTEXT, OnAddToExplorer)
73         //}}AFX_MSG_MAP
74 END_MESSAGE_MAP()
75
76 /** 
77  * @brief Reads options values from storage to UI.
78  */
79 void PropShell::ReadOptions()
80 {
81         GetContextRegValues();
82         m_bEnableShellContextMenu = GetOptionsMgr()->GetBool(OPT_DIRVIEW_ENABLE_SHELL_CONTEXT_MENU);
83 }
84
85 /** 
86  * @brief Writes options values from UI to storage.
87  */
88 void PropShell::WriteOptions()
89 {
90         GetOptionsMgr()->SaveOption(OPT_DIRVIEW_ENABLE_SHELL_CONTEXT_MENU, m_bEnableShellContextMenu);
91         SaveMergePath(); // saves context menu settings as well
92 }
93
94 /// Get registry values for ShellExtension
95 void PropShell::GetContextRegValues()
96 {
97         CRegKeyEx reg;
98         LONG retVal = 0;
99         retVal = reg.Open(HKEY_CURRENT_USER, RegDir);
100         if (retVal != ERROR_SUCCESS)
101         {
102                 String msg = string_format(_T("Failed to open registry key HKCU/%s:\n\t%d : %s"),
103                         RegDir, retVal, GetSysError(retVal).c_str());
104                 LogErrorString(msg);
105                 return;
106         }
107
108         // Read bitmask for shell extension settings
109         DWORD dwContextEnabled = reg.ReadDword(f_RegValueEnabled, 0);
110
111         if (dwContextEnabled & CONTEXT_F_ENABLED)
112                 m_bContextAdded = true;
113
114         if (dwContextEnabled & CONTEXT_F_ADVANCED)
115                 m_bContextAdvanced = true;
116
117         if (dwContextEnabled & CONTEXT_F_SUBFOLDERS)
118                 m_bContextSubfolders = true;
119 }
120
121 /// Set registry values for ShellExtension
122 void PropShell::OnAddToExplorer()
123 {
124         AdvancedContextMenuCheck();
125         SubfolderOptionCheck();
126 }
127
128 /// Saves given path to registry for ShellExtension, and Context Menu settings
129 void PropShell::SaveMergePath()
130 {
131         TCHAR temp[MAX_PATH] = {0};
132         LONG retVal = 0;
133         GetModuleFileName(AfxGetInstanceHandle(), temp, MAX_PATH);
134
135         CRegKeyEx reg;
136         retVal = reg.Open(HKEY_CURRENT_USER, RegDir);
137         if (retVal != ERROR_SUCCESS)
138         {
139                 String msg = string_format(_T("Failed to open registry key HKCU/%s:\n\t%d : %s"),
140                         RegDir, retVal, GetSysError(retVal).c_str());
141                 LogErrorString(msg);
142                 return;
143         }
144
145         // Save path to WinMerge(U).exe
146         retVal = reg.WriteString(f_RegValuePath, temp);
147         if (retVal != ERROR_SUCCESS)
148         {
149                 String msg = string_format(_T("Failed to set registry value %s:\n\t%d : %s"),
150                         f_RegValuePath, retVal, GetSysError(retVal).c_str());
151                 LogErrorString(msg);
152         }
153
154         // Determine bitmask for shell extension
155         DWORD dwContextEnabled = reg.ReadDword(f_RegValueEnabled, 0);
156         if (m_bContextAdded)
157                 dwContextEnabled |= CONTEXT_F_ENABLED;
158         else
159                 dwContextEnabled &= ~CONTEXT_F_ENABLED;
160
161         if (m_bContextAdvanced)
162                 dwContextEnabled |= CONTEXT_F_ADVANCED;
163         else
164                 dwContextEnabled &= ~CONTEXT_F_ADVANCED;
165
166         if (m_bContextSubfolders)
167                 dwContextEnabled |= CONTEXT_F_SUBFOLDERS;
168         else
169                 dwContextEnabled &= ~CONTEXT_F_SUBFOLDERS;
170
171         retVal = reg.WriteDword(f_RegValueEnabled, dwContextEnabled);
172         if (retVal != ERROR_SUCCESS)
173         {
174                 String msg = string_format(_T("Failed to set registry value %s to %d:\n\t%d : %s"),
175                         f_RegValueEnabled, dwContextEnabled, retVal, GetSysError(retVal).c_str());
176                 LogErrorString(msg);
177         }
178 }
179
180 /// Enable/Disable "Advanced menu" checkbox.
181 void PropShell::AdvancedContextMenuCheck()
182 {
183         if (IsDlgButtonChecked(IDC_EXPLORER_CONTEXT))
184                 GetDlgItem(IDC_EXPLORER_ADVANCED)->EnableWindow(TRUE);
185         else
186         {
187                 GetDlgItem(IDC_EXPLORER_ADVANCED)->EnableWindow(FALSE);
188                 CheckDlgButton(IDC_EXPLORER_ADVANCED, FALSE);
189                 m_bContextAdvanced = false;
190         }
191 }
192
193 /// Enable/Disable "Include subfolders by default" checkbox.
194 void PropShell::SubfolderOptionCheck()
195 {
196         if (IsDlgButtonChecked(IDC_EXPLORER_CONTEXT))
197                 GetDlgItem(IDC_EXPLORER_SUBFOLDERS)->EnableWindow(TRUE);
198         else
199         {
200                 GetDlgItem(IDC_EXPLORER_SUBFOLDERS)->EnableWindow(FALSE);
201                 CheckDlgButton(IDC_EXPLORER_SUBFOLDERS, FALSE);
202                 m_bContextSubfolders = false;
203         }
204 }