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