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 } 828