[REGEDIT]
[reactos.git] / reactos / base / applications / 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19
20 #include <regedit.h>
21
22 static TCHAR s_szFindWhat[256];
23 static const TCHAR s_szFindFlags[] = _T("FindFlags");
24 static const TCHAR s_szFindFlagsR[] = _T("FindFlagsReactOS");
25 static HWND s_hwndAbortDialog;
26 static BOOL s_bAbort;
27
28 static DWORD s_dwFlags;
29 static TCHAR s_szName[MAX_PATH];
30 static DWORD s_cbName;
31 static const TCHAR s_empty[] = {0};
32 static const TCHAR s_backslash[] = {'\\', 0};
33
34 extern VOID SetValueName(HWND hwndLV, LPCTSTR pszValueName);
35
36 BOOL DoEvents(VOID)
37 {
38 MSG msg;
39 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
40 {
41 if (msg.message == WM_QUIT)
42 s_bAbort = TRUE;
43 if (!IsDialogMessage(s_hwndAbortDialog, &msg))
44 {
45 TranslateMessage(&msg);
46 DispatchMessage(&msg);
47 }
48 }
49 return s_bAbort;
50 }
51
52 static LPTSTR lstrstri(LPCTSTR psz1, LPCTSTR psz2)
53 {
54 INT i, cch1, cch2;
55
56 cch1 = lstrlen(psz1);
57 cch2 = lstrlen(psz2);
58 for(i = 0; i <= cch1 - cch2; i++)
59 {
60 if (CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
61 psz1 + i, cch2, psz2, cch2) == 2)
62 return (LPTSTR) (psz1 + i);
63 }
64 return NULL;
65 }
66
67 static BOOL CompareName(LPCTSTR pszName1, LPCTSTR pszName2)
68 {
69 if (s_dwFlags & RSF_WHOLESTRING)
70 {
71 if (s_dwFlags & RSF_MATCHCASE)
72 return lstrcmp(pszName1, pszName2) == 0;
73 else
74 return lstrcmpi(pszName1, pszName2) == 0;
75 }
76 else
77 {
78 if (s_dwFlags & RSF_MATCHCASE)
79 return _tcsstr(pszName1, pszName2) != NULL;
80 else
81 return lstrstri(pszName1, pszName2) != NULL;
82 }
83 }
84
85 static BOOL
86 CompareData(
87 DWORD dwType,
88 LPCTSTR psz1,
89 LPCTSTR psz2)
90 {
91 INT i, cch1 = lstrlen(psz1), cch2 = lstrlen(psz2);
92 if (dwType == REG_SZ || dwType == REG_EXPAND_SZ)
93 {
94 if (s_dwFlags & RSF_WHOLESTRING)
95 {
96 if (s_dwFlags & RSF_MATCHCASE)
97 return 2 == CompareString(LOCALE_SYSTEM_DEFAULT, 0,
98 psz1, cch1, psz2, cch2);
99 else
100 return 2 == CompareString(LOCALE_SYSTEM_DEFAULT,
101 NORM_IGNORECASE, psz1, cch1, psz2, cch2);
102 }
103
104 for(i = 0; i <= cch1 - cch2; i++)
105 {
106 if (s_dwFlags & RSF_MATCHCASE)
107 {
108 if (2 == CompareString(LOCALE_SYSTEM_DEFAULT, 0,
109 psz1 + i, cch2, psz2, cch2))
110 return TRUE;
111 }
112 else
113 {
114 if (2 == CompareString(LOCALE_SYSTEM_DEFAULT,
115 NORM_IGNORECASE, psz1 + i, cch2, psz2, cch2))
116 return TRUE;
117 }
118 }
119 }
120 return FALSE;
121 }
122
123 int compare(const void *x, const void *y)
124 {
125 const LPCTSTR *a = (const LPCTSTR *)x;
126 const LPCTSTR *b = (const LPCTSTR *)y;
127 return lstrcmpi(*a, *b);
128 }
129
130 BOOL RegFindRecurse(
131 HKEY hKey,
132 LPCTSTR pszSubKey,
133 LPCTSTR pszValueName,
134 LPTSTR *ppszFoundSubKey,
135 LPTSTR *ppszFoundValueName)
136 {
137 HKEY hSubKey;
138 LONG lResult;
139 TCHAR szSubKey[MAX_PATH];
140 DWORD i, c, cb, type;
141 BOOL fPast = FALSE;
142 LPTSTR *ppszNames = NULL;
143 LPBYTE pb = NULL;
144
145 if (DoEvents())
146 return FALSE;
147
148 lstrcpy(szSubKey, pszSubKey);
149 hSubKey = NULL;
150
151 lResult = RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
152 if (lResult != ERROR_SUCCESS)
153 return FALSE;
154
155 if (pszValueName == NULL)
156 pszValueName = s_empty;
157
158 lResult = RegQueryInfoKey(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL,
159 &c, NULL, NULL, NULL, NULL);
160 if (lResult != ERROR_SUCCESS)
161 goto err;
162 ppszNames = (LPTSTR *) malloc(c * sizeof(LPTSTR));
163 if (ppszNames == NULL)
164 goto err;
165 ZeroMemory(ppszNames, c * sizeof(LPTSTR));
166
167 for(i = 0; i < c; i++)
168 {
169 if (DoEvents())
170 goto err;
171
172 s_cbName = MAX_PATH * sizeof(TCHAR);
173 lResult = RegEnumValue(hSubKey, i, s_szName, &s_cbName, NULL, NULL,
174 NULL, &cb);
175 if (lResult == ERROR_NO_MORE_ITEMS)
176 {
177 c = i;
178 break;
179 }
180 if (lResult != ERROR_SUCCESS)
181 goto err;
182 if (s_cbName >= MAX_PATH * sizeof(TCHAR))
183 continue;
184
185 ppszNames[i] = _tcsdup(s_szName);
186 }
187
188 qsort(ppszNames, c, sizeof(LPTSTR), compare);
189
190 for(i = 0; i < c; i++)
191 {
192 if (DoEvents())
193 goto err;
194
195 if (!fPast && lstrcmpi(ppszNames[i], pszValueName) == 0)
196 {
197 fPast = TRUE;
198 continue;
199 }
200 if (!fPast)
201 continue;
202
203 if ((s_dwFlags & RSF_LOOKATVALUES) &&
204 CompareName(ppszNames[i], s_szFindWhat))
205 {
206 *ppszFoundSubKey = _tcsdup(szSubKey);
207 if (ppszNames[i][0] == 0)
208 *ppszFoundValueName = NULL;
209 else
210 *ppszFoundValueName = _tcsdup(ppszNames[i]);
211 goto success;
212 }
213
214 lResult = RegQueryValueEx(hSubKey, ppszNames[i], NULL, &type,
215 NULL, &cb);
216 if (lResult != ERROR_SUCCESS)
217 goto err;
218 pb = malloc(cb);
219 if (pb == NULL)
220 goto err;
221 lResult = RegQueryValueEx(hSubKey, ppszNames[i], NULL, &type,
222 pb, &cb);
223 if (lResult != ERROR_SUCCESS)
224 goto err;
225
226 if ((s_dwFlags & RSF_LOOKATDATA) &&
227 CompareData(type, (LPTSTR) pb, s_szFindWhat))
228 {
229 *ppszFoundSubKey = _tcsdup(szSubKey);
230 if (ppszNames[i][0] == 0)
231 *ppszFoundValueName = NULL;
232 else
233 *ppszFoundValueName = _tcsdup(ppszNames[i]);
234 goto success;
235 }
236 free(pb);
237 pb = NULL;
238 }
239
240 if (ppszNames != NULL)
241 {
242 for(i = 0; i < c; i++)
243 free(ppszNames[i]);
244 free(ppszNames);
245 }
246 ppszNames = NULL;
247
248 lResult = RegQueryInfoKey(hSubKey, NULL, NULL, NULL, &c, NULL, NULL,
249 NULL, NULL, NULL, NULL, NULL);
250 if (lResult != ERROR_SUCCESS)
251 goto err;
252 ppszNames = (LPTSTR *) malloc(c * sizeof(LPTSTR));
253 if (ppszNames == NULL)
254 goto err;
255 ZeroMemory(ppszNames, c * sizeof(LPTSTR));
256
257 for(i = 0; i < c; i++)
258 {
259 if (DoEvents())
260 goto err;
261
262 s_cbName = MAX_PATH * sizeof(TCHAR);
263 lResult = RegEnumKeyEx(hSubKey, i, s_szName, &s_cbName, NULL, NULL,
264 NULL, NULL);
265 if (lResult == ERROR_NO_MORE_ITEMS)
266 {
267 c = i;
268 break;
269 }
270 if (lResult != ERROR_SUCCESS)
271 goto err;
272 if (s_cbName >= MAX_PATH * sizeof(TCHAR))
273 continue;
274
275 ppszNames[i] = _tcsdup(s_szName);
276 }
277
278 qsort(ppszNames, c, sizeof(LPTSTR), compare);
279
280 for(i = 0; i < c; i++)
281 {
282 if (DoEvents())
283 goto err;
284
285 if ((s_dwFlags & RSF_LOOKATKEYS) &&
286 CompareName(ppszNames[i], s_szFindWhat))
287 {
288 *ppszFoundSubKey = malloc(
289 (lstrlen(szSubKey) + lstrlen(ppszNames[i]) + 2) *
290 sizeof(TCHAR));
291 if (*ppszFoundSubKey == NULL)
292 goto err;
293 if (szSubKey[0])
294 {
295 lstrcpy(*ppszFoundSubKey, szSubKey);
296 lstrcatW(*ppszFoundSubKey, s_backslash);
297 }
298 else
299 **ppszFoundSubKey = 0;
300 lstrcatW(*ppszFoundSubKey, ppszNames[i]);
301 *ppszFoundValueName = NULL;
302 goto success;
303 }
304
305 if (RegFindRecurse(hSubKey, ppszNames[i], NULL, ppszFoundSubKey,
306 ppszFoundValueName))
307 {
308 LPTSTR psz = *ppszFoundSubKey;
309 *ppszFoundSubKey = malloc(
310 (lstrlen(szSubKey) + lstrlen(psz) + 2) * sizeof(TCHAR));
311 if (*ppszFoundSubKey == NULL)
312 goto err;
313 if (szSubKey[0])
314 {
315 lstrcpy(*ppszFoundSubKey, szSubKey);
316 lstrcatW(*ppszFoundSubKey, s_backslash);
317 }
318 else
319 **ppszFoundSubKey = 0;
320 lstrcatW(*ppszFoundSubKey, psz);
321 free(psz);
322 goto success;
323 }
324 }
325
326 err:
327 if (ppszNames != NULL)
328 {
329 for(i = 0; i < c; i++)
330 free(ppszNames[i]);
331 free(ppszNames);
332 }
333 free(pb);
334 RegCloseKey(hSubKey);
335 return FALSE;
336
337 success:
338 if (ppszNames != NULL)
339 {
340 for(i = 0; i < c; i++)
341 free(ppszNames[i]);
342 free(ppszNames);
343 }
344 RegCloseKey(hSubKey);
345 return TRUE;
346 }
347
348 BOOL RegFindWalk(
349 HKEY * phKey,
350 LPCTSTR pszSubKey,
351 LPCTSTR pszValueName,
352 LPTSTR *ppszFoundSubKey,
353 LPTSTR *ppszFoundValueName)
354 {
355 LONG lResult;
356 DWORD i, c;
357 HKEY hBaseKey, hSubKey;
358 TCHAR szKeyName[MAX_PATH];
359 TCHAR szSubKey[MAX_PATH];
360 LPTSTR pch;
361 BOOL fPast;
362 LPTSTR *ppszNames = NULL;
363
364 hBaseKey = *phKey;
365 if (RegFindRecurse(hBaseKey, pszSubKey, pszValueName, ppszFoundSubKey,
366 ppszFoundValueName))
367 return TRUE;
368
369 if (lstrlen(pszSubKey) >= MAX_PATH)
370 return FALSE;
371
372 lstrcpy(szSubKey, pszSubKey);
373 while(szSubKey[0] != 0)
374 {
375 if (DoEvents())
376 return FALSE;
377
378 pch = _tcsrchr(szSubKey, _T('\\'));
379 if (pch == NULL)
380 {
381 lstrcpy(szKeyName, szSubKey);
382 szSubKey[0] = 0;
383 hSubKey = hBaseKey;
384 }
385 else
386 {
387 lstrcpyn(szKeyName, pch + 1, MAX_PATH);
388 *pch = 0;
389 lResult = RegOpenKeyEx(hBaseKey, szSubKey, 0, KEY_ALL_ACCESS,
390 &hSubKey);
391 if (lResult != ERROR_SUCCESS)
392 return FALSE;
393 }
394
395 lResult = RegQueryInfoKey(hSubKey, NULL, NULL, NULL, &c, NULL, NULL,
396 NULL, NULL, NULL, NULL, NULL);
397 if (lResult != ERROR_SUCCESS)
398 goto err;
399
400 ppszNames = (LPTSTR *) malloc(c * sizeof(LPTSTR));
401 if (ppszNames == NULL)
402 goto err;
403 ZeroMemory(ppszNames, c * sizeof(LPTSTR));
404
405 for(i = 0; i < c; i++)
406 {
407 if (DoEvents())
408 goto err;
409
410 s_cbName = MAX_PATH * sizeof(TCHAR);
411 lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cbName,
412 NULL, NULL, NULL, NULL);
413 if (lResult == ERROR_NO_MORE_ITEMS)
414 {
415 c = i;
416 break;
417 }
418 if (lResult != ERROR_SUCCESS)
419 break;
420 ppszNames[i] = _tcsdup(s_szName);
421 }
422
423 qsort(ppszNames, c, sizeof(LPTSTR), compare);
424
425 fPast = FALSE;
426 for(i = 0; i < c; i++)
427 {
428 if (DoEvents())
429 goto err;
430
431 if (!fPast && lstrcmpi(ppszNames[i], szKeyName) == 0)
432 {
433 fPast = TRUE;
434 continue;
435 }
436 if (!fPast)
437 continue;
438
439 if ((s_dwFlags & RSF_LOOKATKEYS) &&
440 CompareName(ppszNames[i], s_szFindWhat))
441 {
442 *ppszFoundSubKey = malloc(
443 (lstrlen(szSubKey) + lstrlen(ppszNames[i]) + 2) *
444 sizeof(TCHAR));
445 if (*ppszFoundSubKey == NULL)
446 goto err;
447 if (szSubKey[0])
448 {
449 lstrcpy(*ppszFoundSubKey, szSubKey);
450 lstrcatW(*ppszFoundSubKey, s_backslash);
451 }
452 else
453 **ppszFoundSubKey = 0;
454 lstrcatW(*ppszFoundSubKey, ppszNames[i]);
455 *ppszFoundValueName = NULL;
456 goto success;
457 }
458
459 if (RegFindRecurse(hSubKey, ppszNames[i], NULL,
460 ppszFoundSubKey, ppszFoundValueName))
461 {
462 LPTSTR psz = *ppszFoundSubKey;
463 *ppszFoundSubKey = malloc(
464 (lstrlen(szSubKey) + lstrlen(psz) + 2) *
465 sizeof(TCHAR));
466 if (*ppszFoundSubKey == NULL)
467 goto err;
468 if (szSubKey[0])
469 {
470 lstrcpy(*ppszFoundSubKey, szSubKey);
471 lstrcatW(*ppszFoundSubKey, s_backslash);
472 }
473 else
474 **ppszFoundSubKey = 0;
475 lstrcatW(*ppszFoundSubKey, psz);
476 free(psz);
477 goto success;
478 }
479 }
480 if (ppszNames != NULL)
481 {
482 for(i = 0; i < c; i++)
483 free(ppszNames[i]);
484 free(ppszNames);
485 }
486 ppszNames = NULL;
487
488 if (hBaseKey != hSubKey)
489 RegCloseKey(hSubKey);
490 }
491
492 if (*phKey == HKEY_CLASSES_ROOT)
493 {
494 *phKey = HKEY_CURRENT_USER;
495 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
496 ppszFoundValueName))
497 return TRUE;
498 }
499
500 if (*phKey == HKEY_CURRENT_USER)
501 {
502 *phKey = HKEY_LOCAL_MACHINE;
503 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
504 ppszFoundValueName))
505 goto success;
506 }
507
508 if (*phKey == HKEY_LOCAL_MACHINE)
509 {
510 *phKey = HKEY_USERS;
511 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
512 ppszFoundValueName))
513 goto success;
514 }
515
516 if (*phKey == HKEY_USERS)
517 {
518 *phKey = HKEY_CURRENT_CONFIG;
519 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
520 ppszFoundValueName))
521 goto success;
522 }
523
524 err:
525 if (ppszNames != NULL)
526 {
527 for(i = 0; i < c; i++)
528 free(ppszNames[i]);
529 free(ppszNames);
530 }
531 if (hBaseKey != hSubKey)
532 RegCloseKey(hSubKey);
533 return FALSE;
534
535 success:
536 if (ppszNames != NULL)
537 {
538 for(i = 0; i < c; i++)
539 free(ppszNames[i]);
540 free(ppszNames);
541 }
542 if (hBaseKey != hSubKey)
543 RegCloseKey(hSubKey);
544 return TRUE;
545 }
546
547
548 static DWORD GetFindFlags(void)
549 {
550 HKEY hKey;
551 DWORD dwType, dwValue, cbData;
552 DWORD dwFlags = RSF_LOOKATKEYS | RSF_LOOKATVALUES | RSF_LOOKATDATA;
553
554 if (RegOpenKey(HKEY_CURRENT_USER, g_szGeneralRegKey, &hKey) == ERROR_SUCCESS)
555 {
556 /* Retrieve flags from registry key */
557 cbData = sizeof(dwValue);
558 if (RegQueryValueEx(hKey, s_szFindFlags, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS)
559 {
560 if (dwType == REG_DWORD)
561 dwFlags = (dwFlags & ~0x0000FFFF) | ((dwValue & 0x0000FFFF) << 0);
562 }
563
564 /* Retrieve ReactOS Regedit specific flags from registry key */
565 cbData = sizeof(dwValue);
566 if (RegQueryValueEx(hKey, s_szFindFlagsR, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS)
567 {
568 if (dwType == REG_DWORD)
569 dwFlags = (dwFlags & ~0xFFFF0000) | ((dwValue & 0x0000FFFF) << 16);
570 }
571
572 RegCloseKey(hKey);
573 }
574 return dwFlags;
575 }
576
577 static void SetFindFlags(DWORD dwFlags)
578 {
579 HKEY hKey;
580 DWORD dwDisposition;
581 DWORD dwData;
582
583 if (RegCreateKeyEx(HKEY_CURRENT_USER, g_szGeneralRegKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS)
584 {
585 dwData = (dwFlags >> 0) & 0x0000FFFF;
586 RegSetValueEx(hKey, s_szFindFlags, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData));
587
588 dwData = (dwFlags >> 16) & 0x0000FFFF;
589 RegSetValueEx(hKey, s_szFindFlagsR, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData));
590
591 RegCloseKey(hKey);
592 }
593 }
594
595 static INT_PTR CALLBACK AbortFindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
596 {
597 UNREFERENCED_PARAMETER(lParam);
598 UNREFERENCED_PARAMETER(hDlg);
599
600 switch(uMsg)
601 {
602 case WM_CLOSE:
603 s_bAbort = TRUE;
604 break;
605
606 case WM_COMMAND:
607 switch(HIWORD(wParam))
608 {
609 case BN_CLICKED:
610 switch(LOWORD(wParam))
611 {
612 case IDCANCEL:
613 s_bAbort = TRUE;
614 break;
615 }
616 break;
617 }
618 break;
619 }
620 return 0;
621 }
622
623 BOOL FindNext(HWND hWnd)
624 {
625 HKEY hKeyRoot;
626 LPCTSTR pszKeyPath;
627 BOOL fSuccess;
628 TCHAR szFullKey[512];
629 LPCTSTR pszValueName;
630 LPTSTR pszFoundSubKey, pszFoundValueName;
631
632 if (_tcslen(s_szFindWhat) == 0)
633 {
634 FindDialog(hWnd);
635 return TRUE;
636 }
637
638 s_dwFlags = GetFindFlags();
639
640 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
641 if (pszKeyPath == NULL)
642 {
643 hKeyRoot = HKEY_CLASSES_ROOT;
644 pszKeyPath = s_empty;
645 }
646
647 /* Create abort find dialog */
648 s_hwndAbortDialog = CreateDialog(GetModuleHandle(NULL),
649 MAKEINTRESOURCE(IDD_FINDING), hWnd, AbortFindDialogProc);
650 if (s_hwndAbortDialog)
651 {
652 ShowWindow(s_hwndAbortDialog, SW_SHOW);
653 UpdateWindow(s_hwndAbortDialog);
654 }
655 s_bAbort = FALSE;
656
657 pszValueName = GetValueName(g_pChildWnd->hListWnd, -1);
658
659 EnableWindow(hFrameWnd, FALSE);
660 EnableWindow(g_pChildWnd->hTreeWnd, FALSE);
661 EnableWindow(g_pChildWnd->hListWnd, FALSE);
662 EnableWindow(g_pChildWnd->hAddressBarWnd, FALSE);
663
664 fSuccess = RegFindWalk(&hKeyRoot, pszKeyPath, pszValueName,
665 &pszFoundSubKey, &pszFoundValueName);
666
667 EnableWindow(hFrameWnd, TRUE);
668 EnableWindow(g_pChildWnd->hTreeWnd, TRUE);
669 EnableWindow(g_pChildWnd->hListWnd, TRUE);
670 EnableWindow(g_pChildWnd->hAddressBarWnd, TRUE);
671
672 if (s_hwndAbortDialog)
673 {
674 DestroyWindow(s_hwndAbortDialog);
675 s_hwndAbortDialog = NULL;
676 }
677
678 if (fSuccess)
679 {
680 RegKeyGetName(szFullKey, COUNT_OF(szFullKey), hKeyRoot, pszFoundSubKey);
681 SelectNode(g_pChildWnd->hTreeWnd, szFullKey);
682 SetValueName(g_pChildWnd->hListWnd, pszFoundValueName);
683 free(pszFoundSubKey);
684 free(pszFoundValueName);
685 SetFocus(g_pChildWnd->hListWnd);
686 }
687 return fSuccess || s_bAbort;
688 }
689
690 static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
691 {
692 INT_PTR iResult = 0;
693 HWND hControl;
694 LONG lStyle;
695 DWORD dwFlags;
696 static TCHAR s_szSavedFindValue[256];
697
698 switch(uMsg)
699 {
700 case WM_INITDIALOG:
701 dwFlags = GetFindFlags();
702
703 hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS);
704 if (hControl)
705 SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATKEYS) ? TRUE : FALSE, 0);
706
707 hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES);
708 if (hControl)
709 SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATVALUES) ? TRUE : FALSE, 0);
710
711 hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA);
712 if (hControl)
713 SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATDATA) ? TRUE : FALSE, 0);
714
715 /* Match whole string */
716 hControl = GetDlgItem(hDlg, IDC_MATCHSTRING);
717 if (hControl)
718 SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_WHOLESTRING) ? TRUE : FALSE, 0);
719
720 /* Case sensitivity */
721 hControl = GetDlgItem(hDlg, IDC_MATCHCASE);
722 if (hControl)
723 SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_MATCHCASE) ? TRUE : FALSE, 0);
724
725 hControl = GetDlgItem(hDlg, IDC_FINDWHAT);
726 if (hControl)
727 {
728 SetWindowText(hControl, s_szSavedFindValue);
729 SetFocus(hControl);
730 SendMessage(hControl, EM_SETSEL, 0, -1);
731 }
732 break;
733
734 case WM_CLOSE:
735 EndDialog(hDlg, 0);
736 break;
737
738 case WM_COMMAND:
739 switch(HIWORD(wParam))
740 {
741 case BN_CLICKED:
742 switch(LOWORD(wParam))
743 {
744 case IDOK:
745 dwFlags = 0;
746
747 hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS);
748 if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
749 dwFlags |= RSF_LOOKATKEYS;
750
751 hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES);
752 if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
753 dwFlags |= RSF_LOOKATVALUES;
754
755 hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA);
756 if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
757 dwFlags |= RSF_LOOKATDATA;
758
759 hControl = GetDlgItem(hDlg, IDC_MATCHSTRING);
760 if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
761 dwFlags |= RSF_WHOLESTRING;
762
763 hControl = GetDlgItem(hDlg, IDC_MATCHCASE);
764 if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
765 dwFlags |= RSF_MATCHCASE;
766
767 SetFindFlags(dwFlags);
768
769 hControl = GetDlgItem(hDlg, IDC_FINDWHAT);
770 if (hControl)
771 GetWindowText(hControl, s_szFindWhat, sizeof(s_szFindWhat) / sizeof(s_szFindWhat[0]));
772 EndDialog(hDlg, 1);
773 break;
774
775 case IDCANCEL:
776 EndDialog(hDlg, 0);
777 break;
778 }
779 break;
780
781 case EN_CHANGE:
782 switch(LOWORD(wParam))
783 {
784 case IDC_FINDWHAT:
785 GetWindowText((HWND) lParam, s_szSavedFindValue, sizeof(s_szSavedFindValue) / sizeof(s_szSavedFindValue[0]));
786 hControl = GetDlgItem(hDlg, IDOK);
787 if (hControl)
788 {
789 lStyle = GetWindowLongPtr(hControl, GWL_STYLE);
790 if (s_szSavedFindValue[0])
791 lStyle &= ~WS_DISABLED;
792 else
793 lStyle |= WS_DISABLED;
794 SetWindowLongPtr(hControl, GWL_STYLE, lStyle);
795 RedrawWindow(hControl, NULL, NULL, RDW_INVALIDATE);
796 }
797 break;
798 }
799 }
800 break;
801 }
802 return iResult;
803 }
804
805 void FindDialog(HWND hWnd)
806 {
807 if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_FIND),
808 hWnd, FindDialogProc, 0) != 0)
809 {
810 if (!FindNext(hWnd))
811 {
812 TCHAR msg[128], caption[128];
813
814 LoadString(hInst, IDS_FINISHEDFIND, msg, sizeof(msg)/sizeof(TCHAR));
815 LoadString(hInst, IDS_APP_TITLE, caption, sizeof(caption)/sizeof(TCHAR));
816 MessageBox(0, msg, caption, MB_ICONINFORMATION);
817 }
818 }
819 }
820