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_cchName; 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 /* Do not assume that pch1 is terminated with UNICODE_NULL */ 91 static BOOL MatchString(LPCWCH pch1, INT cch1, LPCWCH pch2, INT cch2) 92 { 93 INT i; 94 DWORD dwNorm = ((s_dwFlags & RSF_MATCHCASE) ? NORM_IGNORECASE : 0); 95 96 if (s_dwFlags & RSF_WHOLESTRING) 97 return 2 == CompareStringW(LOCALE_SYSTEM_DEFAULT, dwNorm, pch1, cch1, pch2, cch2); 98 99 if (cch1 < cch2) 100 return FALSE; 101 102 for (i = 0; i <= cch1 - cch2; i++) 103 { 104 if (2 == CompareStringW(LOCALE_SYSTEM_DEFAULT, dwNorm, pch1 + i, cch2, pch2, cch2)) 105 return TRUE; 106 } 107 108 return FALSE; 109 } 110 111 static BOOL MatchData(DWORD dwType, LPCVOID pv1, DWORD cb1) 112 { 113 if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ) 114 return MatchString(pv1, (INT)(cb1 / sizeof(WCHAR)), s_szFindWhat, lstrlenW(s_szFindWhat)); 115 116 return FALSE; 117 } 118 119 int compare(const void *x, const void *y) 120 { 121 const LPCWSTR *a = (const LPCWSTR *)x; 122 const LPCWSTR *b = (const LPCWSTR *)y; 123 return _wcsicmp(*a, *b); 124 } 125 126 BOOL RegFindRecurse( 127 HKEY hKey, 128 LPCWSTR pszSubKey, 129 LPCWSTR pszValueName, 130 LPWSTR *ppszFoundSubKey, 131 LPWSTR *ppszFoundValueName) 132 { 133 HKEY hSubKey; 134 LONG lResult; 135 WCHAR szSubKey[MAX_PATH]; 136 DWORD i, c, cb, type; 137 BOOL fPast; 138 LPWSTR *ppszNames = NULL; 139 LPBYTE pb = NULL; 140 141 if (DoEvents()) 142 return FALSE; 143 144 if(wcslen(pszSubKey) >= _countof(szSubKey)) 145 return FALSE; 146 147 wcscpy(szSubKey, pszSubKey); 148 hSubKey = NULL; 149 150 lResult = RegOpenKeyExW(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey); 151 if (lResult != ERROR_SUCCESS) 152 return FALSE; 153 154 lResult = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL, 155 &c, NULL, NULL, NULL, NULL); 156 if (lResult != ERROR_SUCCESS) 157 goto err; 158 ppszNames = (LPWSTR *) malloc(c * sizeof(LPWSTR)); 159 if (ppszNames == NULL) 160 goto err; 161 ZeroMemory(ppszNames, c * sizeof(LPWSTR)); 162 163 /* Retrieve the value names associated with the current key */ 164 for(i = 0; i < c; i++) 165 { 166 if (DoEvents()) 167 goto err; 168 169 s_cchName = _countof(s_szName); 170 lResult = RegEnumValueW(hSubKey, i, s_szName, &s_cchName, NULL, NULL, 171 NULL, &cb); 172 if (lResult == ERROR_NO_MORE_ITEMS) 173 { 174 c = i; 175 break; 176 } 177 if (lResult != ERROR_SUCCESS) 178 goto err; 179 if (s_cchName >= _countof(s_szName)) 180 continue; 181 182 ppszNames[i] = _wcsdup(s_szName); 183 } 184 185 qsort(ppszNames, c, sizeof(LPWSTR), compare); 186 187 /* If pszValueName is NULL, the function will search for all values within the key */ 188 fPast = (pszValueName == NULL); 189 190 /* Search within the values */ 191 for (i = 0; i < c; i++) 192 { 193 if (DoEvents()) 194 goto err; 195 196 if (!fPast && _wcsicmp(ppszNames[i], pszValueName) == 0) 197 { 198 fPast = TRUE; 199 continue; 200 } 201 if (!fPast) 202 continue; 203 204 if ((s_dwFlags & RSF_LOOKATVALUES) && 205 CompareName(ppszNames[i], s_szFindWhat)) 206 { 207 *ppszFoundSubKey = _wcsdup(szSubKey); 208 *ppszFoundValueName = _wcsdup(ppszNames[i]); 209 goto success; 210 } 211 212 lResult = RegQueryValueExW(hSubKey, ppszNames[i], NULL, &type, 213 NULL, &cb); 214 if (lResult != ERROR_SUCCESS) 215 goto err; 216 pb = malloc(cb); 217 if (pb == NULL) 218 goto err; 219 lResult = RegQueryValueExW(hSubKey, ppszNames[i], NULL, &type, 220 pb, &cb); 221 if (lResult != ERROR_SUCCESS) 222 goto err; 223 224 if ((s_dwFlags & RSF_LOOKATDATA) && MatchData(type, pb, cb)) 225 { 226 *ppszFoundSubKey = _wcsdup(szSubKey); 227 *ppszFoundValueName = _wcsdup(ppszNames[i]); 228 goto success; 229 } 230 free(pb); 231 pb = NULL; 232 } 233 234 if (ppszNames != NULL) 235 { 236 for(i = 0; i < c; i++) 237 free(ppszNames[i]); 238 free(ppszNames); 239 } 240 ppszNames = NULL; 241 242 /* Retrieve the number of sub-keys */ 243 lResult = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &c, NULL, NULL, 244 NULL, NULL, NULL, NULL, NULL); 245 if (lResult != ERROR_SUCCESS) 246 goto err; 247 ppszNames = (LPWSTR *) malloc(c * sizeof(LPWSTR)); 248 if (ppszNames == NULL) 249 goto err; 250 ZeroMemory(ppszNames, c * sizeof(LPWSTR)); 251 252 /* Retrieve the names of the sub-keys */ 253 for(i = 0; i < c; i++) 254 { 255 if (DoEvents()) 256 goto err; 257 258 s_cchName = _countof(s_szName); 259 lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cchName, NULL, NULL, 260 NULL, NULL); 261 if (lResult == ERROR_NO_MORE_ITEMS) 262 { 263 c = i; 264 break; 265 } 266 if (lResult != ERROR_SUCCESS) 267 goto err; 268 if (s_cchName >= _countof(s_szName)) 269 continue; 270 271 ppszNames[i] = _wcsdup(s_szName); 272 } 273 274 qsort(ppszNames, c, sizeof(LPWSTR), compare); 275 276 /* Search within the sub-keys */ 277 for(i = 0; i < c; i++) 278 { 279 if (DoEvents()) 280 goto err; 281 282 if ((s_dwFlags & RSF_LOOKATKEYS) && 283 CompareName(ppszNames[i], s_szFindWhat)) 284 { 285 *ppszFoundSubKey = malloc( 286 (wcslen(szSubKey) + wcslen(ppszNames[i]) + 2) * 287 sizeof(WCHAR)); 288 if (*ppszFoundSubKey == NULL) 289 goto err; 290 if (szSubKey[0]) 291 { 292 wcscpy(*ppszFoundSubKey, szSubKey); 293 wcscat(*ppszFoundSubKey, s_backslash); 294 } 295 else 296 **ppszFoundSubKey = 0; 297 wcscat(*ppszFoundSubKey, ppszNames[i]); 298 *ppszFoundValueName = NULL; 299 goto success; 300 } 301 302 /* Search within the value entries of the sub-key */ 303 if (RegFindRecurse(hSubKey, ppszNames[i], NULL, ppszFoundSubKey, 304 ppszFoundValueName)) 305 { 306 LPWSTR psz = *ppszFoundSubKey; 307 *ppszFoundSubKey = malloc( 308 (wcslen(szSubKey) + wcslen(psz) + 2) * sizeof(WCHAR)); 309 if (*ppszFoundSubKey == NULL) 310 goto err; 311 if (szSubKey[0]) 312 { 313 wcscpy(*ppszFoundSubKey, szSubKey); 314 wcscat(*ppszFoundSubKey, s_backslash); 315 } 316 else 317 **ppszFoundSubKey = 0; 318 wcscat(*ppszFoundSubKey, psz); 319 free(psz); 320 goto success; 321 } 322 } 323 324 err: 325 if (ppszNames != NULL) 326 { 327 for(i = 0; i < c; i++) 328 free(ppszNames[i]); 329 free(ppszNames); 330 } 331 free(pb); 332 RegCloseKey(hSubKey); 333 return FALSE; 334 335 success: 336 if (ppszNames != NULL) 337 { 338 for(i = 0; i < c; i++) 339 free(ppszNames[i]); 340 free(ppszNames); 341 } 342 RegCloseKey(hSubKey); 343 return TRUE; 344 } 345 346 BOOL RegFindWalk( 347 HKEY * phKey, 348 LPCWSTR pszSubKey, 349 LPCWSTR pszValueName, 350 LPWSTR *ppszFoundSubKey, 351 LPWSTR *ppszFoundValueName) 352 { 353 LONG lResult; 354 DWORD i, c; 355 HKEY hBaseKey, hSubKey; 356 WCHAR szKeyName[MAX_PATH]; 357 WCHAR szSubKey[MAX_PATH]; 358 LPWSTR pch; 359 BOOL fPast, fKeyMatched; 360 LPWSTR *ppszNames = NULL; 361 362 hBaseKey = *phKey; 363 364 if (wcslen(pszSubKey) >= _countof(szSubKey)) 365 return FALSE; 366 367 if (RegFindRecurse(hBaseKey, pszSubKey, pszValueName, ppszFoundSubKey, 368 ppszFoundValueName)) 369 return TRUE; 370 371 wcscpy(szSubKey, pszSubKey); 372 while(szSubKey[0] != 0) 373 { 374 if (DoEvents()) 375 return FALSE; 376 377 pch = wcsrchr(szSubKey, L'\\'); 378 if (pch == NULL) 379 { 380 wcscpy(szKeyName, szSubKey); 381 szSubKey[0] = 0; 382 hSubKey = hBaseKey; 383 } 384 else 385 { 386 lstrcpynW(szKeyName, pch + 1, MAX_PATH); 387 *pch = 0; 388 lResult = RegOpenKeyExW(hBaseKey, szSubKey, 0, KEY_ALL_ACCESS, 389 &hSubKey); 390 if (lResult != ERROR_SUCCESS) 391 return FALSE; 392 } 393 394 lResult = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &c, NULL, NULL, 395 NULL, NULL, NULL, NULL, NULL); 396 if (lResult != ERROR_SUCCESS) 397 goto err; 398 399 ppszNames = (LPWSTR *) malloc(c * sizeof(LPWSTR)); 400 if (ppszNames == NULL) 401 goto err; 402 ZeroMemory(ppszNames, c * sizeof(LPWSTR)); 403 404 for(i = 0; i < c; i++) 405 { 406 if (DoEvents()) 407 goto err; 408 409 s_cchName = _countof(s_szName); 410 lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cchName, 411 NULL, NULL, NULL, NULL); 412 if (lResult == ERROR_NO_MORE_ITEMS) 413 { 414 c = i; 415 break; 416 } 417 if (lResult != ERROR_SUCCESS) 418 break; 419 ppszNames[i] = _wcsdup(s_szName); 420 } 421 422 qsort(ppszNames, c, sizeof(LPWSTR), compare); 423 424 fPast = FALSE; 425 for(i = 0; i < c; i++) 426 { 427 if (DoEvents()) 428 goto err; 429 430 if (!fPast && _wcsicmp(ppszNames[i], szKeyName) == 0) 431 { 432 fPast = TRUE; 433 continue; 434 } 435 if (!fPast) 436 continue; 437 438 if ((s_dwFlags & RSF_LOOKATKEYS) && 439 CompareName(ppszNames[i], s_szFindWhat)) 440 { 441 *ppszFoundSubKey = malloc( 442 (wcslen(szSubKey) + wcslen(ppszNames[i]) + 2) * 443 sizeof(WCHAR)); 444 if (*ppszFoundSubKey == NULL) 445 goto err; 446 if (szSubKey[0]) 447 { 448 wcscpy(*ppszFoundSubKey, szSubKey); 449 wcscat(*ppszFoundSubKey, s_backslash); 450 } 451 else 452 **ppszFoundSubKey = 0; 453 wcscat(*ppszFoundSubKey, ppszNames[i]); 454 *ppszFoundValueName = NULL; 455 goto success; 456 } 457 458 fKeyMatched = (_wcsicmp(ppszNames[i], szKeyName) == 0); 459 if (RegFindRecurse(hSubKey, ppszNames[i], (fKeyMatched ? pszValueName : NULL), 460 ppszFoundSubKey, ppszFoundValueName)) 461 { 462 LPWSTR psz = *ppszFoundSubKey; 463 *ppszFoundSubKey = malloc( 464 (wcslen(szSubKey) + wcslen(psz) + 2) * 465 sizeof(WCHAR)); 466 if (*ppszFoundSubKey == NULL) 467 goto err; 468 if (szSubKey[0]) 469 { 470 wcscpy(*ppszFoundSubKey, szSubKey); 471 wcscat(*ppszFoundSubKey, s_backslash); 472 } 473 else 474 **ppszFoundSubKey = 0; 475 wcscat(*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 (RegOpenKeyW(HKEY_CURRENT_USER, g_szGeneralRegKey, &hKey) == ERROR_SUCCESS) 555 { 556 /* Retrieve flags from registry key */ 557 cbData = sizeof(dwValue); 558 if (RegQueryValueExW(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 (RegQueryValueExW(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 (RegCreateKeyExW(HKEY_CURRENT_USER, g_szGeneralRegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS) 584 { 585 dwData = (dwFlags >> 0) & 0x0000FFFF; 586 RegSetValueExW(hKey, s_szFindFlags, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData)); 587 588 dwData = (dwFlags >> 16) & 0x0000FFFF; 589 RegSetValueExW(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 LPCWSTR pszKeyPath; 627 BOOL fSuccess; 628 WCHAR szFullKey[512]; 629 LPCWSTR pszValueName; 630 LPWSTR pszFoundSubKey, pszFoundValueName; 631 632 if (wcslen(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 = CreateDialogW(GetModuleHandle(NULL), 649 MAKEINTRESOURCEW(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 GetKeyName(szFullKey, ARRAY_SIZE(szFullKey), hKeyRoot, pszFoundSubKey); 681 SelectNode(g_pChildWnd->hTreeWnd, szFullKey); 682 free(pszFoundSubKey); 683 684 if (pszFoundValueName != NULL) 685 { 686 SetValueName(g_pChildWnd->hListWnd, pszFoundValueName); 687 free(pszFoundValueName); 688 SetFocus(g_pChildWnd->hListWnd); 689 } 690 else 691 { 692 SetFocus(g_pChildWnd->hTreeWnd); 693 } 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, ARRAY_SIZE(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, ARRAY_SIZE(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 FindNextMessageBox(HWND hWnd) 814 { 815 if (!FindNext(hWnd)) 816 { 817 WCHAR msg[128], caption[128]; 818 819 LoadStringW(hInst, IDS_FINISHEDFIND, msg, ARRAY_SIZE(msg)); 820 LoadStringW(hInst, IDS_APP_TITLE, caption, ARRAY_SIZE(caption)); 821 MessageBoxW(hWnd, msg, caption, MB_ICONINFORMATION); 822 } 823 } 824 825 void FindDialog(HWND hWnd) 826 { 827 if (DialogBoxParamW(GetModuleHandle(NULL), MAKEINTRESOURCEW(IDD_FIND), 828 hWnd, FindDialogProc, 0) != 0) 829 { 830 FindNextMessageBox(hWnd); 831 } 832 } 833