Regedit: Partially implemented Find/Find Next
[reactos.git] / reactos / subsys / system / regedit / find.c
1 /*
2 * Regedit find dialog
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19
20 #include <windows.h>
21 #include <tchar.h>
22 #include <commctrl.h>
23 #include <commdlg.h>
24 #include <cderr.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <shellapi.h>
28 #include <objsel.h>
29 #include <objbase.h>
30 #include <ole2.h>
31
32 #include "main.h"
33 #include "regproc.h"
34
35 static TCHAR s_szFindWhat[256];
36 static const TCHAR s_szFindFlags[] = _T("FindFlags");
37 static const TCHAR s_szFindFlagsR[] = _T("FindFlagsReactOS");
38 static HWND s_hwndAbortDialog;
39 static BOOL s_bAbort;
40
41
42
43 static DWORD GetFindFlags(void)
44 {
45 HKEY hKey;
46 DWORD dwFlags = RSF_LOOKATKEYS;
47 DWORD dwType, dwValue, cbData;
48
49 if (RegOpenKey(HKEY_CURRENT_USER, g_szGeneralRegKey, &hKey) == ERROR_SUCCESS)
50 {
51 /* Retrieve flags from registry key */
52 cbData = sizeof(dwValue);
53 if (RegQueryValueEx(hKey, s_szFindFlags, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS)
54 {
55 if (dwType == REG_DWORD)
56 dwFlags = (dwFlags & ~0x0000FFFF) | ((dwValue & 0x0000FFFF) << 0);
57 }
58
59 /* Retrieve ReactOS Regedit specific flags from registry key */
60 cbData = sizeof(dwValue);
61 if (RegQueryValueEx(hKey, s_szFindFlagsR, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS)
62 {
63 if (dwType == REG_DWORD)
64 dwFlags = (dwFlags & ~0xFFFF0000) | ((dwValue & 0x0000FFFF) << 16);
65 }
66
67 RegCloseKey(hKey);
68 }
69 return dwFlags;
70 }
71
72 static void SetFindFlags(DWORD dwFlags)
73 {
74 HKEY hKey;
75 DWORD dwDisposition;
76 DWORD dwData;
77
78 if (RegCreateKeyEx(HKEY_CURRENT_USER, g_szGeneralRegKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS)
79 {
80 dwData = (dwFlags >> 0) & 0x0000FFFF;
81 RegSetValueEx(hKey, s_szFindFlags, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData));
82
83 dwData = (dwFlags >> 16) & 0x0000FFFF;
84 RegSetValueEx(hKey, s_szFindFlagsR, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData));
85
86 RegCloseKey(hKey);
87 }
88 }
89
90 static INT_PTR CALLBACK AbortFindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
91 {
92 switch(uMsg)
93 {
94 case WM_CLOSE:
95 s_bAbort = TRUE;
96 break;
97
98 case WM_COMMAND:
99 switch(HIWORD(wParam))
100 {
101 case BN_CLICKED:
102 switch(LOWORD(wParam))
103 {
104 case IDCANCEL:
105 s_bAbort = TRUE;
106 break;
107 }
108 break;
109 }
110 break;
111 }
112 return 0;
113 }
114
115 static BOOL RegSearchProc(LPVOID lpParam)
116 {
117 MSG msg;
118
119 if (s_hwndAbortDialog && PeekMessage(&msg, s_hwndAbortDialog, 0, 0, PM_REMOVE))
120 {
121 TranslateMessage(&msg);
122 DispatchMessage(&msg);
123 }
124 return s_bAbort;
125 }
126
127 BOOL FindNext(HWND hWnd)
128 {
129 HKEY hKeyRoot;
130 LPCTSTR pszFindWhat;
131 LPCTSTR pszKeyPath;
132 DWORD dwFlags;
133 LONG lResult;
134 TCHAR szSubKey[512];
135 TCHAR szError[512];
136 TCHAR szTitle[64];
137 TCHAR szFullKey[512];
138
139 pszFindWhat = s_szFindWhat;
140 dwFlags = GetFindFlags() & ~(RSF_LOOKATVALUES | RSF_LOOKATDATA);
141
142 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
143 lstrcpyn(szSubKey, pszKeyPath, sizeof(szSubKey) / sizeof(szSubKey[0]));
144
145 /* Create abort find dialog */
146 s_hwndAbortDialog = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_FINDING), hWnd, AbortFindDialogProc);
147 if (s_hwndAbortDialog)
148 ShowWindow(s_hwndAbortDialog, SW_SHOW);
149 s_bAbort = FALSE;
150
151 lResult = RegSearch(hKeyRoot, szSubKey, sizeof(szSubKey) / sizeof(szSubKey[0]),
152 pszFindWhat, 0, dwFlags, RegSearchProc, NULL);
153
154 if (s_hwndAbortDialog)
155 {
156 DestroyWindow(s_hwndAbortDialog);
157 s_hwndAbortDialog = NULL;
158 }
159
160 /* Did the user click "Cancel"? If so, exit without displaying an error message */
161 if (lResult == ERROR_OPERATION_ABORTED)
162 return FALSE;
163
164 if (lResult != ERROR_SUCCESS)
165 {
166 LoadString(NULL, IDS_APP_TITLE, szTitle, sizeof(szTitle) / sizeof(szTitle[0]));
167
168 if ((lResult != ERROR_NO_MORE_ITEMS) || !LoadString(NULL, IDS_FINISHEDFIND, szError, sizeof(szError) / sizeof(szError[0])))
169 {
170 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lResult, 0,
171 szError, sizeof(szError) / sizeof(szError[0]), NULL);
172 }
173 MessageBox(hWnd, szError, szTitle, MB_OK);
174 return FALSE;
175 }
176
177 RegKeyGetName(szFullKey, sizeof(szFullKey) / sizeof(szFullKey[0]), hKeyRoot, szSubKey);
178 SelectNode(g_pChildWnd->hTreeWnd, szFullKey);
179 return TRUE;
180 }
181
182 static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
183 {
184 INT_PTR iResult = 0;
185 HWND hControl;
186 LONG lStyle;
187 DWORD dwFlags;
188 static TCHAR s_szSavedFindValue[256];
189
190 switch(uMsg)
191 {
192 case WM_INITDIALOG:
193 dwFlags = GetFindFlags();
194
195 /* Looking at values is not yet implemented */
196 hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS);
197 if (hControl)
198 SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATKEYS) ? TRUE : FALSE, 0);
199
200 /* Looking at values is not yet implemented */
201 hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES);
202 if (hControl)
203 {
204 lStyle = GetWindowLong(hControl, GWL_STYLE);
205 SetWindowLong(hControl, GWL_STYLE, lStyle | WS_DISABLED);
206 }
207
208 /* Looking at data is not yet implemented */
209 hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA);
210 if (hControl)
211 {
212 lStyle = GetWindowLong(hControl, GWL_STYLE);
213 SetWindowLong(hControl, GWL_STYLE, lStyle | WS_DISABLED);
214 }
215
216 /* Match whole string */
217 hControl = GetDlgItem(hDlg, IDC_MATCHSTRING);
218 if (hControl)
219 SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_WHOLESTRING) ? TRUE : FALSE, 0);
220
221 /* Case sensitivity */
222 hControl = GetDlgItem(hDlg, IDC_MATCHCASE);
223 if (hControl)
224 SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_MATCHCASE) ? TRUE : FALSE, 0);
225
226 hControl = GetDlgItem(hDlg, IDC_FINDWHAT);
227 if (hControl)
228 {
229 SetWindowText(hControl, s_szSavedFindValue);
230 SetFocus(hControl);
231 SendMessage(hControl, EM_SETSEL, 0, -1);
232 }
233 break;
234
235 case WM_CLOSE:
236 EndDialog(hDlg, 0);
237 break;
238
239 case WM_COMMAND:
240 switch(HIWORD(wParam))
241 {
242 case BN_CLICKED:
243 switch(LOWORD(wParam))
244 {
245 case IDOK:
246 dwFlags = 0;
247
248 hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS);
249 if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
250 dwFlags |= RSF_LOOKATKEYS;
251
252 hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES);
253 if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
254 dwFlags |= RSF_LOOKATVALUES;
255
256 hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA);
257 if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
258 dwFlags |= RSF_LOOKATDATA;
259
260 hControl = GetDlgItem(hDlg, IDC_MATCHSTRING);
261 if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
262 dwFlags |= RSF_WHOLESTRING;
263
264 hControl = GetDlgItem(hDlg, IDC_MATCHCASE);
265 if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
266 dwFlags |= RSF_MATCHCASE;
267
268 SetFindFlags(dwFlags);
269
270 hControl = GetDlgItem(hDlg, IDC_FINDWHAT);
271 if (hControl)
272 GetWindowText(hControl, s_szFindWhat, sizeof(s_szFindWhat) / sizeof(s_szFindWhat[0]));
273 EndDialog(hDlg, 1);
274 break;
275
276 case IDCANCEL:
277 EndDialog(hDlg, 0);
278 break;
279 }
280 break;
281
282 case EN_CHANGE:
283 switch(LOWORD(wParam))
284 {
285 case IDC_FINDWHAT:
286 GetWindowText((HWND) lParam, s_szSavedFindValue, sizeof(s_szSavedFindValue) / sizeof(s_szSavedFindValue[0]));
287 hControl = GetDlgItem(hDlg, IDOK);
288 if (hControl)
289 {
290 lStyle = GetWindowLong(hControl, GWL_STYLE);
291 if (s_szSavedFindValue[0])
292 lStyle &= ~WS_DISABLED;
293 else
294 lStyle |= WS_DISABLED;
295 SetWindowLong(hControl, GWL_STYLE, lStyle);
296 RedrawWindow(hControl, NULL, NULL, RDW_INVALIDATE);
297 }
298 break;
299 }
300 }
301 break;
302 }
303 return iResult;
304 }
305
306 void FindDialog(HWND hWnd)
307 {
308 if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_FIND),
309 hWnd, FindDialogProc, 0) != 0)
310 {
311 FindNext(hWnd);
312 }
313 }
314