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 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 lResult = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL, 164 &c, NULL, NULL, NULL, NULL); 165 if (lResult != ERROR_SUCCESS) 166 goto err; 167 ppszNames = (LPWSTR *) malloc(c * sizeof(LPWSTR)); 168 if (ppszNames == NULL) 169 goto err; 170 ZeroMemory(ppszNames, c * sizeof(LPWSTR)); 171 172 for(i = 0; i < c; i++) 173 { 174 if (DoEvents()) 175 goto err; 176 177 s_cchName = _countof(s_szName); 178 lResult = RegEnumValueW(hSubKey, i, s_szName, &s_cchName, NULL, NULL, 179 NULL, &cb); 180 if (lResult == ERROR_NO_MORE_ITEMS) 181 { 182 c = i; 183 break; 184 } 185 if (lResult != ERROR_SUCCESS) 186 goto err; 187 if (s_cchName >= _countof(s_szName)) 188 continue; 189 190 ppszNames[i] = _wcsdup(s_szName); 191 } 192 193 qsort(ppszNames, c, sizeof(LPWSTR), compare); 194 195 if (pszValueName == NULL) 196 pszValueName = ppszNames[0]; 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_cchName = _countof(s_szName); 271 lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cchName, 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_cchName >= _countof(s_szName)) 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 374 if (wcslen(pszSubKey) >= _countof(szSubKey)) 375 return FALSE; 376 377 if (RegFindRecurse(hBaseKey, pszSubKey, pszValueName, ppszFoundSubKey, 378 ppszFoundValueName)) 379 return TRUE; 380 381 wcscpy(szSubKey, pszSubKey); 382 while(szSubKey[0] != 0) 383 { 384 if (DoEvents()) 385 return FALSE; 386 387 pch = wcsrchr(szSubKey, L'\\'); 388 if (pch == NULL) 389 { 390 wcscpy(szKeyName, szSubKey); 391 szSubKey[0] = 0; 392 hSubKey = hBaseKey; 393 } 394 else 395 { 396 lstrcpynW(szKeyName, pch + 1, MAX_PATH); 397 *pch = 0; 398 lResult = RegOpenKeyExW(hBaseKey, szSubKey, 0, KEY_ALL_ACCESS, 399 &hSubKey); 400 if (lResult != ERROR_SUCCESS) 401 return FALSE; 402 } 403 404 lResult = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &c, NULL, NULL, 405 NULL, NULL, NULL, NULL, NULL); 406 if (lResult != ERROR_SUCCESS) 407 goto err; 408 409 ppszNames = (LPWSTR *) malloc(c * sizeof(LPWSTR)); 410 if (ppszNames == NULL) 411 goto err; 412 ZeroMemory(ppszNames, c * sizeof(LPWSTR)); 413 414 for(i = 0; i < c; i++) 415 { 416 if (DoEvents()) 417 goto err; 418 419 s_cchName = _countof(s_szName); 420 lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cchName, 421 NULL, NULL, NULL, NULL); 422 if (lResult == ERROR_NO_MORE_ITEMS) 423 { 424 c = i; 425 break; 426 } 427 if (lResult != ERROR_SUCCESS) 428 break; 429 ppszNames[i] = _wcsdup(s_szName); 430 } 431 432 qsort(ppszNames, c, sizeof(LPWSTR), compare); 433 434 fPast = FALSE; 435 for(i = 0; i < c; i++) 436 { 437 if (DoEvents()) 438 goto err; 439 440 if (!fPast && _wcsicmp(ppszNames[i], szKeyName) == 0) 441 { 442 fPast = TRUE; 443 continue; 444 } 445 if (!fPast) 446 continue; 447 448 if ((s_dwFlags & RSF_LOOKATKEYS) && 449 CompareName(ppszNames[i], s_szFindWhat)) 450 { 451 *ppszFoundSubKey = malloc( 452 (wcslen(szSubKey) + wcslen(ppszNames[i]) + 2) * 453 sizeof(WCHAR)); 454 if (*ppszFoundSubKey == NULL) 455 goto err; 456 if (szSubKey[0]) 457 { 458 wcscpy(*ppszFoundSubKey, szSubKey); 459 wcscat(*ppszFoundSubKey, s_backslash); 460 } 461 else 462 **ppszFoundSubKey = 0; 463 wcscat(*ppszFoundSubKey, ppszNames[i]); 464 *ppszFoundValueName = NULL; 465 goto success; 466 } 467 468 if (RegFindRecurse(hSubKey, ppszNames[i], NULL, 469 ppszFoundSubKey, ppszFoundValueName)) 470 { 471 LPWSTR psz = *ppszFoundSubKey; 472 *ppszFoundSubKey = malloc( 473 (wcslen(szSubKey) + wcslen(psz) + 2) * 474 sizeof(WCHAR)); 475 if (*ppszFoundSubKey == NULL) 476 goto err; 477 if (szSubKey[0]) 478 { 479 wcscpy(*ppszFoundSubKey, szSubKey); 480 wcscat(*ppszFoundSubKey, s_backslash); 481 } 482 else 483 **ppszFoundSubKey = 0; 484 wcscat(*ppszFoundSubKey, psz); 485 free(psz); 486 goto success; 487 } 488 } 489 if (ppszNames != NULL) 490 { 491 for(i = 0; i < c; i++) 492 free(ppszNames[i]); 493 free(ppszNames); 494 } 495 ppszNames = NULL; 496 497 if (hBaseKey != hSubKey) 498 RegCloseKey(hSubKey); 499 } 500 501 if (*phKey == HKEY_CLASSES_ROOT) 502 { 503 *phKey = HKEY_CURRENT_USER; 504 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey, 505 ppszFoundValueName)) 506 return TRUE; 507 } 508 509 if (*phKey == HKEY_CURRENT_USER) 510 { 511 *phKey = HKEY_LOCAL_MACHINE; 512 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey, 513 ppszFoundValueName)) 514 goto success; 515 } 516 517 if (*phKey == HKEY_LOCAL_MACHINE) 518 { 519 *phKey = HKEY_USERS; 520 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey, 521 ppszFoundValueName)) 522 goto success; 523 } 524 525 if (*phKey == HKEY_USERS) 526 { 527 *phKey = HKEY_CURRENT_CONFIG; 528 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey, 529 ppszFoundValueName)) 530 goto success; 531 } 532 533 err: 534 if (ppszNames != NULL) 535 { 536 for(i = 0; i < c; i++) 537 free(ppszNames[i]); 538 free(ppszNames); 539 } 540 if (hBaseKey != hSubKey) 541 RegCloseKey(hSubKey); 542 return FALSE; 543 544 success: 545 if (ppszNames != NULL) 546 { 547 for(i = 0; i < c; i++) 548 free(ppszNames[i]); 549 free(ppszNames); 550 } 551 if (hBaseKey != hSubKey) 552 RegCloseKey(hSubKey); 553 return TRUE; 554 } 555 556 557 static DWORD GetFindFlags(void) 558 { 559 HKEY hKey; 560 DWORD dwType, dwValue, cbData; 561 DWORD dwFlags = RSF_LOOKATKEYS | RSF_LOOKATVALUES | RSF_LOOKATDATA; 562 563 if (RegOpenKeyW(HKEY_CURRENT_USER, g_szGeneralRegKey, &hKey) == ERROR_SUCCESS) 564 { 565 /* Retrieve flags from registry key */ 566 cbData = sizeof(dwValue); 567 if (RegQueryValueExW(hKey, s_szFindFlags, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS) 568 { 569 if (dwType == REG_DWORD) 570 dwFlags = (dwFlags & ~0x0000FFFF) | ((dwValue & 0x0000FFFF) << 0); 571 } 572 573 /* Retrieve ReactOS Regedit specific flags from registry key */ 574 cbData = sizeof(dwValue); 575 if (RegQueryValueExW(hKey, s_szFindFlagsR, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS) 576 { 577 if (dwType == REG_DWORD) 578 dwFlags = (dwFlags & ~0xFFFF0000) | ((dwValue & 0x0000FFFF) << 16); 579 } 580 581 RegCloseKey(hKey); 582 } 583 return dwFlags; 584 } 585 586 static void SetFindFlags(DWORD dwFlags) 587 { 588 HKEY hKey; 589 DWORD dwDisposition; 590 DWORD dwData; 591 592 if (RegCreateKeyExW(HKEY_CURRENT_USER, g_szGeneralRegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS) 593 { 594 dwData = (dwFlags >> 0) & 0x0000FFFF; 595 RegSetValueExW(hKey, s_szFindFlags, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData)); 596 597 dwData = (dwFlags >> 16) & 0x0000FFFF; 598 RegSetValueExW(hKey, s_szFindFlagsR, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData)); 599 600 RegCloseKey(hKey); 601 } 602 } 603 604 static INT_PTR CALLBACK AbortFindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 605 { 606 UNREFERENCED_PARAMETER(lParam); 607 UNREFERENCED_PARAMETER(hDlg); 608 609 switch(uMsg) 610 { 611 case WM_CLOSE: 612 s_bAbort = TRUE; 613 break; 614 615 case WM_COMMAND: 616 switch(HIWORD(wParam)) 617 { 618 case BN_CLICKED: 619 switch(LOWORD(wParam)) 620 { 621 case IDCANCEL: 622 s_bAbort = TRUE; 623 break; 624 } 625 break; 626 } 627 break; 628 } 629 return 0; 630 } 631 632 BOOL FindNext(HWND hWnd) 633 { 634 HKEY hKeyRoot; 635 LPCWSTR pszKeyPath; 636 BOOL fSuccess; 637 WCHAR szFullKey[512]; 638 LPCWSTR pszValueName; 639 LPWSTR pszFoundSubKey, pszFoundValueName; 640 641 if (wcslen(s_szFindWhat) == 0) 642 { 643 FindDialog(hWnd); 644 return TRUE; 645 } 646 647 s_dwFlags = GetFindFlags(); 648 649 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); 650 if (pszKeyPath == NULL) 651 { 652 hKeyRoot = HKEY_CLASSES_ROOT; 653 pszKeyPath = s_empty; 654 } 655 656 /* Create abort find dialog */ 657 s_hwndAbortDialog = CreateDialogW(GetModuleHandle(NULL), 658 MAKEINTRESOURCEW(IDD_FINDING), hWnd, AbortFindDialogProc); 659 if (s_hwndAbortDialog) 660 { 661 ShowWindow(s_hwndAbortDialog, SW_SHOW); 662 UpdateWindow(s_hwndAbortDialog); 663 } 664 s_bAbort = FALSE; 665 666 pszValueName = GetValueName(g_pChildWnd->hListWnd, -1); 667 668 EnableWindow(hFrameWnd, FALSE); 669 EnableWindow(g_pChildWnd->hTreeWnd, FALSE); 670 EnableWindow(g_pChildWnd->hListWnd, FALSE); 671 EnableWindow(g_pChildWnd->hAddressBarWnd, FALSE); 672 673 fSuccess = RegFindWalk(&hKeyRoot, pszKeyPath, pszValueName, 674 &pszFoundSubKey, &pszFoundValueName); 675 676 EnableWindow(hFrameWnd, TRUE); 677 EnableWindow(g_pChildWnd->hTreeWnd, TRUE); 678 EnableWindow(g_pChildWnd->hListWnd, TRUE); 679 EnableWindow(g_pChildWnd->hAddressBarWnd, TRUE); 680 681 if (s_hwndAbortDialog) 682 { 683 DestroyWindow(s_hwndAbortDialog); 684 s_hwndAbortDialog = NULL; 685 } 686 687 if (fSuccess) 688 { 689 GetKeyName(szFullKey, ARRAY_SIZE(szFullKey), hKeyRoot, pszFoundSubKey); 690 SelectNode(g_pChildWnd->hTreeWnd, szFullKey); 691 free(pszFoundSubKey); 692 693 if (pszFoundValueName != NULL) 694 { 695 SetValueName(g_pChildWnd->hListWnd, pszFoundValueName); 696 free(pszFoundValueName); 697 SetFocus(g_pChildWnd->hListWnd); 698 } 699 else 700 { 701 SetFocus(g_pChildWnd->hTreeWnd); 702 } 703 } 704 return fSuccess || s_bAbort; 705 } 706 707 static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 708 { 709 INT_PTR iResult = 0; 710 HWND hControl; 711 LONG lStyle; 712 DWORD dwFlags; 713 static WCHAR s_szSavedFindValue[256]; 714 715 switch(uMsg) 716 { 717 case WM_INITDIALOG: 718 dwFlags = GetFindFlags(); 719 720 hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS); 721 if (hControl) 722 SendMessageW(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATKEYS) ? TRUE : FALSE, 0); 723 724 hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES); 725 if (hControl) 726 SendMessageW(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATVALUES) ? TRUE : FALSE, 0); 727 728 hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA); 729 if (hControl) 730 SendMessageW(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATDATA) ? TRUE : FALSE, 0); 731 732 /* Match whole string */ 733 hControl = GetDlgItem(hDlg, IDC_MATCHSTRING); 734 if (hControl) 735 SendMessageW(hControl, BM_SETCHECK, (dwFlags & RSF_WHOLESTRING) ? TRUE : FALSE, 0); 736 737 /* Case sensitivity */ 738 hControl = GetDlgItem(hDlg, IDC_MATCHCASE); 739 if (hControl) 740 SendMessageW(hControl, BM_SETCHECK, (dwFlags & RSF_MATCHCASE) ? TRUE : FALSE, 0); 741 742 hControl = GetDlgItem(hDlg, IDC_FINDWHAT); 743 if (hControl) 744 { 745 SetWindowTextW(hControl, s_szSavedFindValue); 746 SetFocus(hControl); 747 SendMessageW(hControl, EM_SETSEL, 0, -1); 748 } 749 break; 750 751 case WM_CLOSE: 752 EndDialog(hDlg, 0); 753 break; 754 755 case WM_COMMAND: 756 switch(HIWORD(wParam)) 757 { 758 case BN_CLICKED: 759 switch(LOWORD(wParam)) 760 { 761 case IDOK: 762 dwFlags = 0; 763 764 hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS); 765 if (hControl && (SendMessageW(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED)) 766 dwFlags |= RSF_LOOKATKEYS; 767 768 hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES); 769 if (hControl && (SendMessageW(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED)) 770 dwFlags |= RSF_LOOKATVALUES; 771 772 hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA); 773 if (hControl && (SendMessageW(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED)) 774 dwFlags |= RSF_LOOKATDATA; 775 776 hControl = GetDlgItem(hDlg, IDC_MATCHSTRING); 777 if (hControl && (SendMessageW(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED)) 778 dwFlags |= RSF_WHOLESTRING; 779 780 hControl = GetDlgItem(hDlg, IDC_MATCHCASE); 781 if (hControl && (SendMessageW(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED)) 782 dwFlags |= RSF_MATCHCASE; 783 784 SetFindFlags(dwFlags); 785 786 hControl = GetDlgItem(hDlg, IDC_FINDWHAT); 787 if (hControl) 788 GetWindowTextW(hControl, s_szFindWhat, ARRAY_SIZE(s_szFindWhat)); 789 EndDialog(hDlg, 1); 790 break; 791 792 case IDCANCEL: 793 EndDialog(hDlg, 0); 794 break; 795 } 796 break; 797 798 case EN_CHANGE: 799 switch(LOWORD(wParam)) 800 { 801 case IDC_FINDWHAT: 802 GetWindowTextW((HWND) lParam, s_szSavedFindValue, ARRAY_SIZE(s_szSavedFindValue)); 803 hControl = GetDlgItem(hDlg, IDOK); 804 if (hControl) 805 { 806 lStyle = GetWindowLongPtr(hControl, GWL_STYLE); 807 if (s_szSavedFindValue[0]) 808 lStyle &= ~WS_DISABLED; 809 else 810 lStyle |= WS_DISABLED; 811 SetWindowLongPtr(hControl, GWL_STYLE, lStyle); 812 RedrawWindow(hControl, NULL, NULL, RDW_INVALIDATE); 813 } 814 break; 815 } 816 } 817 break; 818 } 819 return iResult; 820 } 821 822 void FindNextMessageBox(HWND hWnd) 823 { 824 if (!FindNext(hWnd)) 825 { 826 WCHAR msg[128], caption[128]; 827 828 LoadStringW(hInst, IDS_FINISHEDFIND, msg, ARRAY_SIZE(msg)); 829 LoadStringW(hInst, IDS_APP_TITLE, caption, ARRAY_SIZE(caption)); 830 MessageBoxW(hWnd, msg, caption, MB_ICONINFORMATION); 831 } 832 } 833 834 void FindDialog(HWND hWnd) 835 { 836 if (DialogBoxParamW(GetModuleHandle(NULL), MAKEINTRESOURCEW(IDD_FIND), 837 hWnd, FindDialogProc, 0) != 0) 838 { 839 FindNextMessageBox(hWnd); 840 } 841 } 842