reactos/reactos/base/applications/regedit/find.c
Aleksey Bragin ffe49df99a [REGEDIT]
- Adam Kachwalla: Fix inconsistent formatting.
- Me: to anyone who's gonna try syncing the code with Wine's regedit: Have fun!
See issue #5716 for more details.

svn path=/trunk/; revision=49980
2010-12-07 21:49:25 +00:00

827 lines
23 KiB
C

/*
* Regedit find dialog
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <regedit.h>
#define RSF_WHOLESTRING 0x00000001
#define RSF_LOOKATKEYS 0x00000002
#define RSF_LOOKATVALUES 0x00000004
#define RSF_LOOKATDATA 0x00000008
#define RSF_MATCHCASE 0x00010000
static TCHAR s_szFindWhat[256];
static const TCHAR s_szFindFlags[] = _T("FindFlags");
static const TCHAR s_szFindFlagsR[] = _T("FindFlagsReactOS");
static HWND s_hwndAbortDialog;
static BOOL s_bAbort;
static DWORD s_dwFlags;
static TCHAR s_szName[MAX_PATH];
static DWORD s_cbName;
static const TCHAR s_empty[] = {0};
static const TCHAR s_backslash[] = {'\\', 0};
extern VOID SetValueName(HWND hwndLV, LPCTSTR pszValueName);
BOOL DoEvents(VOID)
{
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
s_bAbort = TRUE;
if (!IsDialogMessage(s_hwndAbortDialog, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return s_bAbort;
}
static LPTSTR lstrstri(LPCTSTR psz1, LPCTSTR psz2)
{
INT i, cch1, cch2;
cch1 = lstrlen(psz1);
cch2 = lstrlen(psz2);
for(i = 0; i <= cch1 - cch2; i++)
{
if (CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
psz1 + i, cch2, psz2, cch2) == 2)
return (LPTSTR) (psz1 + i);
}
return NULL;
}
static BOOL CompareName(LPCTSTR pszName1, LPCTSTR pszName2)
{
if (s_dwFlags & RSF_WHOLESTRING)
{
if (s_dwFlags & RSF_MATCHCASE)
return lstrcmp(pszName1, pszName2) == 0;
else
return lstrcmpi(pszName1, pszName2) == 0;
}
else
{
if (s_dwFlags & RSF_MATCHCASE)
return _tcsstr(pszName1, pszName2) != NULL;
else
return lstrstri(pszName1, pszName2) != NULL;
}
}
static BOOL
CompareData(
DWORD dwType,
LPCTSTR psz1,
LPCTSTR psz2)
{
INT i, cch1 = lstrlen(psz1), cch2 = lstrlen(psz2);
if (dwType == REG_SZ || dwType == REG_EXPAND_SZ)
{
if (s_dwFlags & RSF_WHOLESTRING)
{
if (s_dwFlags & RSF_MATCHCASE)
return 2 == CompareString(LOCALE_SYSTEM_DEFAULT, 0,
psz1, cch1, psz2, cch2);
else
return 2 == CompareString(LOCALE_SYSTEM_DEFAULT,
NORM_IGNORECASE, psz1, cch1, psz2, cch2);
}
for(i = 0; i <= cch1 - cch2; i++)
{
if (s_dwFlags & RSF_MATCHCASE)
{
if (2 == CompareString(LOCALE_SYSTEM_DEFAULT, 0,
psz1 + i, cch2, psz2, cch2))
return TRUE;
}
else
{
if (2 == CompareString(LOCALE_SYSTEM_DEFAULT,
NORM_IGNORECASE, psz1 + i, cch2, psz2, cch2))
return TRUE;
}
}
}
return FALSE;
}
int compare(const void *x, const void *y)
{
const LPCTSTR *a = (const LPCTSTR *)x;
const LPCTSTR *b = (const LPCTSTR *)y;
return lstrcmpi(*a, *b);
}
BOOL RegFindRecurse(
HKEY hKey,
LPCTSTR pszSubKey,
LPCTSTR pszValueName,
LPTSTR *ppszFoundSubKey,
LPTSTR *ppszFoundValueName)
{
HKEY hSubKey;
LONG lResult;
TCHAR szSubKey[MAX_PATH];
DWORD i, c, cb, type;
BOOL fPast = FALSE;
LPTSTR *ppszNames = NULL;
LPBYTE pb = NULL;
if (DoEvents())
return FALSE;
lstrcpy(szSubKey, pszSubKey);
hSubKey = NULL;
lResult = RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
if (lResult != ERROR_SUCCESS)
return FALSE;
if (pszValueName == NULL)
pszValueName = s_empty;
lResult = RegQueryInfoKey(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL,
&c, NULL, NULL, NULL, NULL);
if (lResult != ERROR_SUCCESS)
goto err;
ppszNames = (LPTSTR *) malloc(c * sizeof(LPTSTR));
if (ppszNames == NULL)
goto err;
ZeroMemory(ppszNames, c * sizeof(LPTSTR));
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
s_cbName = MAX_PATH * sizeof(TCHAR);
lResult = RegEnumValue(hSubKey, i, s_szName, &s_cbName, NULL, NULL,
NULL, &cb);
if (lResult == ERROR_NO_MORE_ITEMS)
{
c = i;
break;
}
if (lResult != ERROR_SUCCESS)
goto err;
if (s_cbName >= MAX_PATH * sizeof(TCHAR))
continue;
ppszNames[i] = _tcsdup(s_szName);
}
qsort(ppszNames, c, sizeof(LPTSTR), compare);
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
if (!fPast && lstrcmpi(ppszNames[i], pszValueName) == 0)
{
fPast = TRUE;
continue;
}
if (!fPast)
continue;
if ((s_dwFlags & RSF_LOOKATVALUES) &&
CompareName(ppszNames[i], s_szFindWhat))
{
*ppszFoundSubKey = _tcsdup(szSubKey);
if (ppszNames[i][0] == 0)
*ppszFoundValueName = NULL;
else
*ppszFoundValueName = _tcsdup(ppszNames[i]);
goto success;
}
lResult = RegQueryValueEx(hSubKey, ppszNames[i], NULL, &type,
NULL, &cb);
if (lResult != ERROR_SUCCESS)
goto err;
pb = malloc(cb);
if (pb == NULL)
goto err;
lResult = RegQueryValueEx(hSubKey, ppszNames[i], NULL, &type,
pb, &cb);
if (lResult != ERROR_SUCCESS)
goto err;
if ((s_dwFlags & RSF_LOOKATDATA) &&
CompareData(type, (LPTSTR) pb, s_szFindWhat))
{
*ppszFoundSubKey = _tcsdup(szSubKey);
if (ppszNames[i][0] == 0)
*ppszFoundValueName = NULL;
else
*ppszFoundValueName = _tcsdup(ppszNames[i]);
goto success;
}
free(pb);
pb = NULL;
}
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
ppszNames = NULL;
lResult = RegQueryInfoKey(hSubKey, NULL, NULL, NULL, &c, NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
if (lResult != ERROR_SUCCESS)
goto err;
ppszNames = (LPTSTR *) malloc(c * sizeof(LPTSTR));
if (ppszNames == NULL)
goto err;
ZeroMemory(ppszNames, c * sizeof(LPTSTR));
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
s_cbName = MAX_PATH * sizeof(TCHAR);
lResult = RegEnumKeyEx(hSubKey, i, s_szName, &s_cbName, NULL, NULL,
NULL, NULL);
if (lResult == ERROR_NO_MORE_ITEMS)
{
c = i;
break;
}
if (lResult != ERROR_SUCCESS)
goto err;
if (s_cbName >= MAX_PATH * sizeof(TCHAR))
continue;
ppszNames[i] = _tcsdup(s_szName);
}
qsort(ppszNames, c, sizeof(LPTSTR), compare);
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
if ((s_dwFlags & RSF_LOOKATKEYS) &&
CompareName(ppszNames[i], s_szFindWhat))
{
*ppszFoundSubKey = malloc(
(lstrlen(szSubKey) + lstrlen(ppszNames[i]) + 2) *
sizeof(TCHAR));
if (*ppszFoundSubKey == NULL)
goto err;
if (szSubKey[0])
{
lstrcpy(*ppszFoundSubKey, szSubKey);
lstrcatW(*ppszFoundSubKey, s_backslash);
}
else
**ppszFoundSubKey = 0;
lstrcatW(*ppszFoundSubKey, ppszNames[i]);
*ppszFoundValueName = NULL;
goto success;
}
if (RegFindRecurse(hSubKey, ppszNames[i], NULL, ppszFoundSubKey,
ppszFoundValueName))
{
LPTSTR psz = *ppszFoundSubKey;
*ppszFoundSubKey = malloc(
(lstrlen(szSubKey) + lstrlen(psz) + 2) * sizeof(TCHAR));
if (*ppszFoundSubKey == NULL)
goto err;
if (szSubKey[0])
{
lstrcpy(*ppszFoundSubKey, szSubKey);
lstrcatW(*ppszFoundSubKey, s_backslash);
}
else
**ppszFoundSubKey = 0;
lstrcatW(*ppszFoundSubKey, psz);
free(psz);
goto success;
}
}
err:
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
free(pb);
RegCloseKey(hSubKey);
return FALSE;
success:
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
RegCloseKey(hSubKey);
return TRUE;
}
BOOL RegFindWalk(
HKEY * phKey,
LPCTSTR pszSubKey,
LPCTSTR pszValueName,
LPTSTR *ppszFoundSubKey,
LPTSTR *ppszFoundValueName)
{
LONG lResult;
DWORD i, c;
HKEY hBaseKey, hSubKey;
TCHAR szKeyName[MAX_PATH];
TCHAR szSubKey[MAX_PATH];
LPTSTR pch;
BOOL fPast;
LPTSTR *ppszNames = NULL;
hBaseKey = *phKey;
if (RegFindRecurse(hBaseKey, pszSubKey, pszValueName, ppszFoundSubKey,
ppszFoundValueName))
return TRUE;
if (lstrlen(pszSubKey) >= MAX_PATH)
return FALSE;
lstrcpy(szSubKey, pszSubKey);
while(szSubKey[0] != 0)
{
if (DoEvents())
return FALSE;
pch = _tcsrchr(szSubKey, _T('\\'));
if (pch == NULL)
{
lstrcpy(szKeyName, szSubKey);
szSubKey[0] = 0;
hSubKey = hBaseKey;
}
else
{
lstrcpyn(szKeyName, pch + 1, MAX_PATH);
*pch = 0;
lResult = RegOpenKeyEx(hBaseKey, szSubKey, 0, KEY_ALL_ACCESS,
&hSubKey);
if (lResult != ERROR_SUCCESS)
return FALSE;
}
lResult = RegQueryInfoKey(hSubKey, NULL, NULL, NULL, &c, NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
if (lResult != ERROR_SUCCESS)
goto err;
ppszNames = (LPTSTR *) malloc(c * sizeof(LPTSTR));
if (ppszNames == NULL)
goto err;
ZeroMemory(ppszNames, c * sizeof(LPTSTR));
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
s_cbName = MAX_PATH * sizeof(TCHAR);
lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cbName,
NULL, NULL, NULL, NULL);
if (lResult == ERROR_NO_MORE_ITEMS)
{
c = i;
break;
}
if (lResult != ERROR_SUCCESS)
break;
ppszNames[i] = _tcsdup(s_szName);
}
qsort(ppszNames, c, sizeof(LPTSTR), compare);
fPast = FALSE;
for(i = 0; i < c; i++)
{
if (DoEvents())
goto err;
if (!fPast && lstrcmpi(ppszNames[i], szKeyName) == 0)
{
fPast = TRUE;
continue;
}
if (!fPast)
continue;
if ((s_dwFlags & RSF_LOOKATKEYS) &&
CompareName(ppszNames[i], s_szFindWhat))
{
*ppszFoundSubKey = malloc(
(lstrlen(szSubKey) + lstrlen(ppszNames[i]) + 2) *
sizeof(TCHAR));
if (*ppszFoundSubKey == NULL)
goto err;
if (szSubKey[0])
{
lstrcpy(*ppszFoundSubKey, szSubKey);
lstrcatW(*ppszFoundSubKey, s_backslash);
}
else
**ppszFoundSubKey = 0;
lstrcatW(*ppszFoundSubKey, ppszNames[i]);
*ppszFoundValueName = NULL;
goto success;
}
if (RegFindRecurse(hSubKey, ppszNames[i], NULL,
ppszFoundSubKey, ppszFoundValueName))
{
LPTSTR psz = *ppszFoundSubKey;
*ppszFoundSubKey = malloc(
(lstrlen(szSubKey) + lstrlen(psz) + 2) *
sizeof(TCHAR));
if (*ppszFoundSubKey == NULL)
goto err;
if (szSubKey[0])
{
lstrcpy(*ppszFoundSubKey, szSubKey);
lstrcatW(*ppszFoundSubKey, s_backslash);
}
else
**ppszFoundSubKey = 0;
lstrcatW(*ppszFoundSubKey, psz);
free(psz);
goto success;
}
}
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
ppszNames = NULL;
if (hBaseKey != hSubKey)
RegCloseKey(hSubKey);
}
if (*phKey == HKEY_CLASSES_ROOT)
{
*phKey = HKEY_CURRENT_USER;
if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
ppszFoundValueName))
return TRUE;
}
if (*phKey == HKEY_CURRENT_USER)
{
*phKey = HKEY_LOCAL_MACHINE;
if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
ppszFoundValueName))
goto success;
}
if (*phKey == HKEY_LOCAL_MACHINE)
{
*phKey = HKEY_USERS;
if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
ppszFoundValueName))
goto success;
}
if (*phKey == HKEY_USERS)
{
*phKey = HKEY_CURRENT_CONFIG;
if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey,
ppszFoundValueName))
goto success;
}
err:
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
if (hBaseKey != hSubKey)
RegCloseKey(hSubKey);
return FALSE;
success:
if (ppszNames != NULL)
{
for(i = 0; i < c; i++)
free(ppszNames[i]);
free(ppszNames);
}
if (hBaseKey != hSubKey)
RegCloseKey(hSubKey);
return TRUE;
}
static DWORD GetFindFlags(void)
{
HKEY hKey;
DWORD dwType, dwValue, cbData;
DWORD dwFlags = RSF_LOOKATKEYS | RSF_LOOKATVALUES | RSF_LOOKATDATA;
if (RegOpenKey(HKEY_CURRENT_USER, g_szGeneralRegKey, &hKey) == ERROR_SUCCESS)
{
/* Retrieve flags from registry key */
cbData = sizeof(dwValue);
if (RegQueryValueEx(hKey, s_szFindFlags, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS)
{
if (dwType == REG_DWORD)
dwFlags = (dwFlags & ~0x0000FFFF) | ((dwValue & 0x0000FFFF) << 0);
}
/* Retrieve ReactOS Regedit specific flags from registry key */
cbData = sizeof(dwValue);
if (RegQueryValueEx(hKey, s_szFindFlagsR, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS)
{
if (dwType == REG_DWORD)
dwFlags = (dwFlags & ~0xFFFF0000) | ((dwValue & 0x0000FFFF) << 16);
}
RegCloseKey(hKey);
}
return dwFlags;
}
static void SetFindFlags(DWORD dwFlags)
{
HKEY hKey;
DWORD dwDisposition;
DWORD dwData;
if (RegCreateKeyEx(HKEY_CURRENT_USER, g_szGeneralRegKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS)
{
dwData = (dwFlags >> 0) & 0x0000FFFF;
RegSetValueEx(hKey, s_szFindFlags, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData));
dwData = (dwFlags >> 16) & 0x0000FFFF;
RegSetValueEx(hKey, s_szFindFlagsR, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData));
RegCloseKey(hKey);
}
}
static INT_PTR CALLBACK AbortFindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(hDlg);
switch(uMsg)
{
case WM_CLOSE:
s_bAbort = TRUE;
break;
case WM_COMMAND:
switch(HIWORD(wParam))
{
case BN_CLICKED:
switch(LOWORD(wParam))
{
case IDCANCEL:
s_bAbort = TRUE;
break;
}
break;
}
break;
}
return 0;
}
BOOL FindNext(HWND hWnd)
{
HKEY hKeyRoot;
LPCTSTR pszKeyPath;
BOOL fSuccess;
TCHAR szFullKey[512];
LPCTSTR pszValueName;
LPTSTR pszFoundSubKey, pszFoundValueName;
if (_tcslen(s_szFindWhat) == 0)
{
FindDialog(hWnd);
return TRUE;
}
s_dwFlags = GetFindFlags();
pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
if (pszKeyPath == NULL)
{
hKeyRoot = HKEY_CLASSES_ROOT;
pszKeyPath = s_empty;
}
/* Create abort find dialog */
s_hwndAbortDialog = CreateDialog(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDD_FINDING), hWnd, AbortFindDialogProc);
if (s_hwndAbortDialog)
{
ShowWindow(s_hwndAbortDialog, SW_SHOW);
UpdateWindow(s_hwndAbortDialog);
}
s_bAbort = FALSE;
pszValueName = GetValueName(g_pChildWnd->hListWnd, -1);
EnableWindow(hFrameWnd, FALSE);
EnableWindow(g_pChildWnd->hTreeWnd, FALSE);
EnableWindow(g_pChildWnd->hListWnd, FALSE);
EnableWindow(g_pChildWnd->hAddressBarWnd, FALSE);
fSuccess = RegFindWalk(&hKeyRoot, pszKeyPath, pszValueName,
&pszFoundSubKey, &pszFoundValueName);
EnableWindow(hFrameWnd, TRUE);
EnableWindow(g_pChildWnd->hTreeWnd, TRUE);
EnableWindow(g_pChildWnd->hListWnd, TRUE);
EnableWindow(g_pChildWnd->hAddressBarWnd, TRUE);
if (s_hwndAbortDialog)
{
DestroyWindow(s_hwndAbortDialog);
s_hwndAbortDialog = NULL;
}
if (fSuccess)
{
GetKeyName(szFullKey, COUNT_OF(szFullKey), hKeyRoot, pszFoundSubKey);
SelectNode(g_pChildWnd->hTreeWnd, szFullKey);
SetValueName(g_pChildWnd->hListWnd, pszFoundValueName);
free(pszFoundSubKey);
free(pszFoundValueName);
SetFocus(g_pChildWnd->hListWnd);
}
return fSuccess || s_bAbort;
}
static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
INT_PTR iResult = 0;
HWND hControl;
LONG lStyle;
DWORD dwFlags;
static TCHAR s_szSavedFindValue[256];
switch(uMsg)
{
case WM_INITDIALOG:
dwFlags = GetFindFlags();
hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS);
if (hControl)
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATKEYS) ? TRUE : FALSE, 0);
hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES);
if (hControl)
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATVALUES) ? TRUE : FALSE, 0);
hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA);
if (hControl)
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATDATA) ? TRUE : FALSE, 0);
/* Match whole string */
hControl = GetDlgItem(hDlg, IDC_MATCHSTRING);
if (hControl)
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_WHOLESTRING) ? TRUE : FALSE, 0);
/* Case sensitivity */
hControl = GetDlgItem(hDlg, IDC_MATCHCASE);
if (hControl)
SendMessage(hControl, BM_SETCHECK, (dwFlags & RSF_MATCHCASE) ? TRUE : FALSE, 0);
hControl = GetDlgItem(hDlg, IDC_FINDWHAT);
if (hControl)
{
SetWindowText(hControl, s_szSavedFindValue);
SetFocus(hControl);
SendMessage(hControl, EM_SETSEL, 0, -1);
}
break;
case WM_CLOSE:
EndDialog(hDlg, 0);
break;
case WM_COMMAND:
switch(HIWORD(wParam))
{
case BN_CLICKED:
switch(LOWORD(wParam))
{
case IDOK:
dwFlags = 0;
hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS);
if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
dwFlags |= RSF_LOOKATKEYS;
hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES);
if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
dwFlags |= RSF_LOOKATVALUES;
hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA);
if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
dwFlags |= RSF_LOOKATDATA;
hControl = GetDlgItem(hDlg, IDC_MATCHSTRING);
if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
dwFlags |= RSF_WHOLESTRING;
hControl = GetDlgItem(hDlg, IDC_MATCHCASE);
if (hControl && (SendMessage(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED))
dwFlags |= RSF_MATCHCASE;
SetFindFlags(dwFlags);
hControl = GetDlgItem(hDlg, IDC_FINDWHAT);
if (hControl)
GetWindowText(hControl, s_szFindWhat, sizeof(s_szFindWhat) / sizeof(s_szFindWhat[0]));
EndDialog(hDlg, 1);
break;
case IDCANCEL:
EndDialog(hDlg, 0);
break;
}
break;
case EN_CHANGE:
switch(LOWORD(wParam))
{
case IDC_FINDWHAT:
GetWindowText((HWND) lParam, s_szSavedFindValue, sizeof(s_szSavedFindValue) / sizeof(s_szSavedFindValue[0]));
hControl = GetDlgItem(hDlg, IDOK);
if (hControl)
{
lStyle = GetWindowLongPtr(hControl, GWL_STYLE);
if (s_szSavedFindValue[0])
lStyle &= ~WS_DISABLED;
else
lStyle |= WS_DISABLED;
SetWindowLongPtr(hControl, GWL_STYLE, lStyle);
RedrawWindow(hControl, NULL, NULL, RDW_INVALIDATE);
}
break;
}
}
break;
}
return iResult;
}
void FindDialog(HWND hWnd)
{
if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_FIND),
hWnd, FindDialogProc, 0) != 0)
{
if (!FindNext(hWnd))
{
TCHAR msg[128], caption[128];
LoadString(hInst, IDS_FINISHEDFIND, msg, sizeof(msg)/sizeof(TCHAR));
LoadString(hInst, IDS_APP_TITLE, caption, sizeof(caption)/sizeof(TCHAR));
MessageBox(0, msg, caption, MB_ICONINFORMATION);
}
}
}