/*++

Copyright (c) 1990-1998,  Microsoft Corporation  All rights reserved.

Module Name:

    find.c

Abstract:

    This module implements the Win32 find dialog.

Revision History:

--*/


// precompiled headers
#include "precomp.h"
#pragma hdrstop

#include "find.h"
#include "util.h"

#ifdef UNICODE

////////////////////////////////////////////////////////////////////////////
//
//  FindTextA
//
//  ANSI entry point for FindText when this code is built UNICODE.
//
////////////////////////////////////////////////////////////////////////////

HWND WINAPI FindTextA(
    LPFINDREPLACEA pFRA)
{
    return (CreateFindReplaceDlg((LPFINDREPLACEW)pFRA, DLGT_FIND, COMDLG_ANSI));
}

#else

////////////////////////////////////////////////////////////////////////////
//
//  FindTextW
//
//  Stub UNICODE function for FindText when this code is built ANSI.
//
////////////////////////////////////////////////////////////////////////////

HWND WINAPI FindTextW(
    LPFINDREPLACEW pFRW)
{
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return (FALSE);
}

#endif



////////////////////////////////////////////////////////////////////////////
//
//  FindText
//
//  The FindText function creates a system-defined modeless dialog box
//  that enables the user to find text within a document.
//
////////////////////////////////////////////////////////////////////////////

HWND WINAPI FindText(
    LPFINDREPLACE pFR)
{
    return ( CreateFindReplaceDlg(pFR, DLGT_FIND, COMDLG_WIDE) );
}


#ifdef UNICODE

////////////////////////////////////////////////////////////////////////////
//
//  ReplaceTextA
//
//  ANSI entry point for ReplaceText when this code is built UNICODE.
//
////////////////////////////////////////////////////////////////////////////

HWND WINAPI ReplaceTextA(
    LPFINDREPLACEA pFRA)
{
    return (CreateFindReplaceDlg((LPFINDREPLACEW)pFRA, DLGT_REPLACE, COMDLG_ANSI));
}

#else

////////////////////////////////////////////////////////////////////////////
//
//  ReplaceTextW
//
//  Stub UNICODE function for ReplaceText when this code is built ANSI.
//
////////////////////////////////////////////////////////////////////////////

HWND WINAPI ReplaceTextW(
    LPFINDREPLACEW pFRW)
{
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return (FALSE);
}

#endif


////////////////////////////////////////////////////////////////////////////
//
//  ReplaceText
//
//  The ReplaceText function creates a system-defined modeless dialog box
//  that enables the user to find and replace text within a document.
//
////////////////////////////////////////////////////////////////////////////

HWND WINAPI ReplaceText(
    LPFINDREPLACE pFR)
{
    return ( CreateFindReplaceDlg(pFR, DLGT_REPLACE, COMDLG_WIDE) );
}


////////////////////////////////////////////////////////////////////////////
//
//  CreateFindReplaceDlg
//
//  Creates FindText modeless dialog.
//
//  pFR     - ptr to FINDREPLACE structure set up by user
//  DlgType - type of dialog to create (DLGT_FIND, DLGT_REPLACE)
//  ApiType - type of FINDREPLACE ptr (COMDLG_ANSI or COMDLG_WIDE)
//
//  Returns   success => HANDLE to created dlg
//            failure => HNULL = ((HANDLE) 0)
//
////////////////////////////////////////////////////////////////////////////

HWND CreateFindReplaceDlg(
    LPFINDREPLACE pFR,
    UINT DlgType,
    UINT ApiType)
{
    HWND hWndDlg;                      // handle to created modeless dialog
    HANDLE hDlgTemplate;               // handle to loaded dialog resource
    LPCDLGTEMPLATE lpDlgTemplate;      // pointer to loaded resource block
#ifdef UNICODE
    UINT uiWOWFlag = 0;
#endif

    if (!pFR)
    {
        StoreExtendedError(CDERR_INITIALIZATION);
        return (FALSE);
    }

    if (!SetupOK(pFR, DlgType, ApiType))
    {
        return (HNULL);
    }

    if (!(hDlgTemplate = GetDlgTemplate(pFR, DlgType, ApiType)))
    {
        return (FALSE);
    }

    if (lpDlgTemplate = (LPCDLGTEMPLATE)LockResource(hDlgTemplate))
    {
        PFINDREPLACEINFO pFRI;

        if (pFRI = (PFINDREPLACEINFO)LocalAlloc(LPTR, sizeof(FINDREPLACEINFO)))
        {
            //
            //  CLEAR extended error on new instantiation.
            //
            StoreExtendedError(0);

            if (pFR->Flags & FR_ENABLEHOOK)
            {
                glpfnFindHook = GETHOOKFN(pFR);
            }

            pFRI->pFR = pFR;
            pFRI->ApiType = ApiType;
            pFRI->DlgType = DlgType;

#ifdef UNICODE
            if (IS16BITWOWAPP(pFR))
            {
                uiWOWFlag = SCDLG_16BIT;
            }

            hWndDlg = CreateDialogIndirectParamAorW( g_hinst,
                                                     lpDlgTemplate,
                                                     pFR->hwndOwner,
                                                     FindReplaceDlgProc,
                                                     (LPARAM)pFRI,
                                                     uiWOWFlag );
#else
            hWndDlg = CreateDialogIndirectParam( g_hinst,
                                                 lpDlgTemplate,
                                                 pFR->hwndOwner,
                                                 FindReplaceDlgProc,
                                                 (LPARAM)pFRI );
#endif
            if (!hWndDlg)
            {
                glpfnFindHook = 0;
                LocalFree(pFRI);
            }
        }
        else
        {
            StoreExtendedError(CDERR_MEMALLOCFAILURE);
            return (NULL);
        }
    }
    else
    {
        StoreExtendedError(CDERR_LOCKRESFAILURE);
        return (HNULL);
    }

    return (hWndDlg);
}


////////////////////////////////////////////////////////////////////////////
//
//  SetupOK
//
//  Checks setup for unmet preconditions.
//
//  pFR       ptr to FINDREPLACE structure
//  DlgType   dialog type (either FIND or REPLACE)
//  ApiType   findreplace type (either COMDLG_ANSI or COMDLG_UNICODE)
//
//  Returns   TRUE   - success
//            FALSE  - failure
//
////////////////////////////////////////////////////////////////////////////

BOOL SetupOK(
   LPFINDREPLACE pFR,
   UINT DlgType,
   UINT ApiType)
{
    LANGID LangID = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);

    //
    //  Sanity
    //
    if (!pFR)
    {
        return (FALSE);
    }

    if (pFR->lStructSize != sizeof(FINDREPLACE))
    {
        StoreExtendedError(CDERR_STRUCTSIZE);
        return (FALSE);
    }

    //
    //  Verify window handle and text pointers.
    //
    if (!IsWindow(pFR->hwndOwner))
    {
        StoreExtendedError(CDERR_DIALOGFAILURE);
        return (FALSE);
    }

    if (!pFR->lpstrFindWhat ||
        ((DlgType == DLGT_REPLACE) && !pFR->lpstrReplaceWith) ||
        !pFR->wFindWhatLen)
    {
        StoreExtendedError(FRERR_BUFFERLENGTHZERO);
        return (FALSE);
    }

    //
    //  Verify lpfnHook has a ptr if ENABLED.
    //
    if (pFR->Flags & FR_ENABLEHOOK)
    {
        if (!pFR->lpfnHook)
        {
            StoreExtendedError(CDERR_NOHOOK);
            return (FALSE);
        }
    }
    else
    {
        pFR->lpfnHook = 0;
    }

    //
    // Get LangID 
    //
    if (
        !(pFR->Flags & FR_ENABLETEMPLATE) &&
        !(pFR->Flags & FR_ENABLETEMPLATEHANDLE) )
    {
        LangID = GetDialogLanguage(pFR->hwndOwner, NULL);
    }

    //
    // Warning! Warning! Warning!
    //
    // We have to set g_tlsLangID before any call for CDLoadString
    //
    TlsSetValue(g_tlsLangID, (LPVOID) LangID);

    //
    //  Load "CLOSE" text for Replace.
    //
    if ((DlgType == DLGT_REPLACE) &&
        !CDLoadString(g_hinst, iszClose, (LPTSTR)szClose, CCHCLOSE))
    {
        StoreExtendedError(CDERR_LOADSTRFAILURE);
        return (FALSE);
    }


    //
    //  Setup unique msg# for talking to hwndOwner.
    //
#ifdef UNICODE
    if (ApiType == COMDLG_ANSI)
    {
        if (!(wFRMessage = RegisterWindowMessageA((LPCSTR)FINDMSGSTRINGA)))
        {
            StoreExtendedError(CDERR_REGISTERMSGFAIL);
            return (FALSE);
        }
    }
    else
#endif
    {
        if (!(wFRMessage = RegisterWindowMessage((LPCTSTR)FINDMSGSTRING)))
        {
            StoreExtendedError(CDERR_REGISTERMSGFAIL);
            return (FALSE);
        }
    }

    return (TRUE);
}


////////////////////////////////////////////////////////////////////////////
//
//  GetDlgTemplate
//
//  Finds and loads the dialog template.
//
//  pFR       ptr to FINDREPLACE structure
//  ApiType   findreplace type (either COMDLG_ANSI or COMDLG_UNICODE)
//
//  Returns   handle to dialog template   - success
//            HNULL = ((HANDLE) 0)        - failure
//
////////////////////////////////////////////////////////////////////////////

HANDLE GetDlgTemplate(
    LPFINDREPLACE pFR,
    UINT DlgType,
    UINT ApiType)
{
    HANDLE hRes;                 // handle of res. block with dialog
    HANDLE hDlgTemplate;         // handle to loaded dialog resource
    LANGID LangID;

    if (pFR->Flags & FR_ENABLETEMPLATE)
    {
        //
        //  Find/Load TEMP NAME and INSTANCE from pFR.
        //
#ifdef UNICODE
        if (ApiType == COMDLG_ANSI)
        {
            hRes = FindResourceA( (HMODULE)pFR->hInstance,
                                  (LPCSTR)pFR->lpTemplateName,
                                  (LPCSTR)RT_DIALOG );
        }
        else
#endif
        {
            hRes = FindResource( pFR->hInstance,
                                 (LPCTSTR)pFR->lpTemplateName,
                                 (LPCTSTR)RT_DIALOG );
        }
        if (!hRes)
        {
            StoreExtendedError(CDERR_FINDRESFAILURE);
            return (HNULL);
        }
        if (!(hDlgTemplate = LoadResource(pFR->hInstance, hRes)))
        {
            StoreExtendedError(CDERR_LOADRESFAILURE);
            return (HNULL);
        }
    }
    else if (pFR->Flags & FR_ENABLETEMPLATEHANDLE)
    {
        //
        //  Get whole PRELOADED resource handle from user.
        //
        if (!(hDlgTemplate = pFR->hInstance))
        {
            StoreExtendedError(CDERR_NOHINSTANCE);
            return (HNULL);
        }
    }
    else
    {
        //
        //  Get STANDARD dialog from DLL instance block.
        //
        LangID = (LANGID) TlsGetValue(g_tlsLangID);

        if (DlgType == DLGT_FIND)
        {
            hRes = FindResourceExFallback( g_hinst,
                                   RT_DIALOG, 
                                   MAKEINTRESOURCE(FINDDLGORD),
                                   LangID);
        }
        else
        {
            hRes = FindResourceExFallback( g_hinst,
                                   RT_DIALOG, 
                                   MAKEINTRESOURCE(REPLACEDLGORD),
                                   LangID);
        }

        //
        //  !!!!!  definitely ORD here?
        //
        if (!hRes)
        {
            StoreExtendedError(CDERR_FINDRESFAILURE);
            return (HNULL);
        }
        if (!(hDlgTemplate = LoadResource(g_hinst, hRes)))
        {
            StoreExtendedError(CDERR_LOADRESFAILURE);
            return (HNULL);
        }
    }

    return (hDlgTemplate);
}


////////////////////////////////////////////////////////////////////////////
//
//  FindReplaceDlgProc
//
//  Handles messages to FindText/ReplaceText dialogs.
//
//  hDlg   -  handle to dialog
//  wMsg   -  window message
//  wParam -  w parameter of message
//  lParam -  l parameter of message
//
//  Note: lparam contains ptr to FINDREPLACEINITPROC upon
//        initialization from CreateDialogIndirectParam...
//
//  Returns:   TRUE (or dlg fcn return vals) - success
//             FALSE                         - failure
//
////////////////////////////////////////////////////////////////////////////

BOOL_PTR CALLBACK FindReplaceDlgProc(
    HWND hDlg,
    UINT wMsg,
    WPARAM wParam,
    LPARAM lParam)
{
    PFINDREPLACEINFO pFRI;
    LPFINDREPLACE pFR;
    BOOL_PTR bRet;

    //
    //  If a hook exists, let hook function do procing.
    //
    if (pFRI = (PFINDREPLACEINFO)GetProp(hDlg, FINDREPLACEPROP))
    {
        if ((pFR = (LPFINDREPLACE)pFRI->pFR) &&
            (pFR->Flags & FR_ENABLEHOOK))
        {
            LPFRHOOKPROC lpfnHook = GETHOOKFN(pFR);

            if ((bRet = (*lpfnHook)(hDlg, wMsg, wParam, lParam)))
            {
                return (bRet);
            }
        }
    }
    else if (glpfnFindHook &&
             (wMsg != WM_INITDIALOG) &&
             (bRet = (* glpfnFindHook)(hDlg, wMsg, wParam, lParam)))
    {
        return (bRet);
    }

    //
    //  Dispatch MSG to appropriate HANDLER.
    //
    switch (wMsg)
    {
        case ( WM_INITDIALOG ) :
        {
            //
            //  Set Up P-Slot.
            //
            pFRI = (PFINDREPLACEINFO)lParam;
            SetProp(hDlg, FINDREPLACEPROP, (HANDLE)pFRI);

            glpfnFindHook = 0;

            //
            //  Init dlg controls accordingly.
            //
            pFR = pFRI->pFR;
            InitControlsWithFlags(hDlg, pFR, pFRI->DlgType, pFRI->ApiType);

            //
            //  If Hook function, do extra processing.
            //
            if (pFR->Flags & FR_ENABLEHOOK)
            {
                LPFRHOOKPROC lpfnHook = GETHOOKFN(pFR);

                bRet = (*lpfnHook)(hDlg, wMsg, wParam, (LPARAM)pFR);
            }
            else
            {
                bRet = TRUE;
            }

            if (bRet)
            {
                //
                //  If the hook function returns FALSE, then we must call
                //  these functions here.
                //
                ShowWindow(hDlg, SW_SHOWNORMAL);
                UpdateWindow(hDlg);
            }

            return (bRet);
            break;
        }
        case ( WM_COMMAND ) :
        {
            if (!pFRI || !pFR)
            {
                return (FALSE);
            }

            switch (GET_WM_COMMAND_ID (wParam, lParam))
            {
                //
                //  FIND NEXT button clicked.
                //
                case ( IDOK ) :
                {
                    UpdateTextAndFlags( hDlg,
                                        pFR,
                                        FR_FINDNEXT,
                                        pFRI->DlgType,
                                        pFRI->ApiType );
                    NotifyUpdateTextAndFlags(pFR);
                    break;
                }
                case ( IDCANCEL ) :
                case ( IDABORT ) :
                {
                    EndDlgSession(hDlg, pFR);
                    LocalFree(pFRI);
                    break;
                }
                case ( psh1 ) :
                case ( psh2 ) :
                {
                    UpdateTextAndFlags( hDlg,
                                        pFR,
                                        (wParam == psh1)
                                            ? FR_REPLACE
                                            : FR_REPLACEALL,
                                        pFRI->DlgType,
                                        pFRI->ApiType );
                    if (NotifyUpdateTextAndFlags(pFR) == TRUE)
                    {
                        //
                        //  Change <Cancel> button to <Close> if function
                        //  returns TRUE.
                        //  IDCANCEL instead of psh1.
                        SetWindowText( GetDlgItem(hDlg, IDCANCEL),
                                       (LPTSTR)szClose );
                    }
                    break;
                }
                case ( pshHelp ) :
                {
                    //
                    //  Call HELP app.
                    //
#ifdef UNICODE
                    if (pFRI->ApiType == COMDLG_ANSI)
                    {
                        if (msgHELPA && pFR->hwndOwner)
                        {
                            SendMessage( pFR->hwndOwner,
                                         msgHELPA,
                                         (WPARAM)hDlg,
                                         (LPARAM)pFR );
                        }
                    }
                    else
#endif
                    {
                        if (msgHELPW && pFR->hwndOwner)
                        {
                            SendMessage( pFR->hwndOwner,
                                         msgHELPW,
                                         (WPARAM)hDlg,
                                         (LPARAM)pFR );
                        }
                    }
                    break;
                }
                case ( edt1 ) :
                {
                    if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
                    {
                        BOOL fAnythingToFind =
                            (BOOL)SendDlgItemMessage( hDlg,
                                                      edt1,
                                                      WM_GETTEXTLENGTH,
                                                      0,
                                                      0L );
                        EnableWindow(GetDlgItem(hDlg, IDOK), fAnythingToFind);
                        if (pFRI->DlgType == DLGT_REPLACE)
                        {
                            EnableWindow(GetDlgItem(hDlg, psh1), fAnythingToFind);
                            EnableWindow(GetDlgItem(hDlg, psh2), fAnythingToFind);
                        }
                    }

                    if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
                    {
                        EnableWindow( GetDlgItem(hDlg, IDOK),
                                      (BOOL)SendDlgItemMessage(
                                                   hDlg,
                                                   edt1,
                                                   WM_GETTEXTLENGTH,
                                                   0,
                                                   0L ));
                    }
                    break;
                }
                default :
                {
                    return (FALSE);
                }
            }
            break;
        }
        case ( WM_HELP ) :
        {
            if (IsWindowEnabled(hDlg))
            {
                WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
                         NULL,
                         HELP_WM_HELP,
                         (ULONG_PTR)(LPTSTR)aFindReplaceHelpIDs );
            }
            break;
        }
        case ( WM_CONTEXTMENU ) :
        {
            if (IsWindowEnabled(hDlg))
            {
                WinHelp( (HWND)wParam,
                         NULL,
                         HELP_CONTEXTMENU,
                         (ULONG_PTR)(LPVOID)aFindReplaceHelpIDs );
            }
            break;
        }
        case ( WM_CLOSE ) :
        {
            SendMessage(hDlg, WM_COMMAND, GET_WM_COMMAND_MPS(IDCANCEL, 0, 0));
            return (TRUE);
            break;
        }
        default:
        {
            return (FALSE);
            break;
        }
    }

    return (TRUE);
}


////////////////////////////////////////////////////////////////////////////
//
//  EndDlgSession
//
//  Cleans up upon destroying the dialog.
//
////////////////////////////////////////////////////////////////////////////

VOID EndDlgSession(
   HWND hDlg,
   LPFINDREPLACE pFR)
{
    //
    //  Need to terminate regardless of app testing order ... so:
    //

    //
    //  No SUCCESS on termination.
    //
    pFR->Flags &= ~((DWORD)(FR_REPLACE | FR_FINDNEXT | FR_REPLACEALL));

    //
    //  Tell caller dialog is about to terminate.
    //
    pFR->Flags |= FR_DIALOGTERM;
    NotifyUpdateTextAndFlags(pFR);

    if (IS16BITWOWAPP(pFR))
    {
        if ((pFR->Flags & FR_ENABLEHOOK) && (pFR->lpfnHook))
        {
            (*pFR->lpfnHook)(hDlg, WM_DESTROY, 0, 0);
        }
    }

    //
    //  Free property slots.
    //
    RemoveProp(hDlg, FINDREPLACEPROP);
    DestroyWindow(hDlg);
}


////////////////////////////////////////////////////////////////////////////
//
//  InitControlsWithFlags
//
////////////////////////////////////////////////////////////////////////////

VOID InitControlsWithFlags(
   HWND hDlg,
   LPFINDREPLACE pFR,
   UINT DlgType,
   UINT ApiType)
{
    HWND hCtl;

    //
    //  Set EDIT control to FindText.
    //
#ifdef UNICODE
    if (ApiType == COMDLG_ANSI)
    {
        SetDlgItemTextA(hDlg, edt1, (LPSTR)pFR->lpstrFindWhat);
    }
    else
#endif
    {
        SetDlgItemText(hDlg, edt1, (LPTSTR)pFR->lpstrFindWhat);
    }
    SendMessage(hDlg, WM_COMMAND, GET_WM_COMMAND_MPS(edt1, 0, EN_CHANGE));

    //
    //  Set HELP push button state.
    //
    if (!(pFR->Flags & FR_SHOWHELP))
    {
        ShowWindow(hCtl = GetDlgItem(hDlg, pshHelp), SW_HIDE);
        EnableWindow(hCtl, FALSE);
    }

    //
    //  Dis/Enable check state of WHOLE WORD control.
    //
    if (pFR->Flags & FR_HIDEWHOLEWORD)
    {
        ShowWindow(hCtl = GetDlgItem(hDlg, chx1), SW_HIDE);
        EnableWindow(hCtl, FALSE);
    }
    else if (pFR->Flags & FR_NOWHOLEWORD)
    {
        EnableWindow(GetDlgItem(hDlg, chx1), FALSE);
    }
    CheckDlgButton(hDlg, chx1, (pFR->Flags & FR_WHOLEWORD) ? TRUE: FALSE);

    //
    //  Dis/Enable check state of MATCH CASE control.
    //
    if (pFR->Flags & FR_HIDEMATCHCASE)
    {
        ShowWindow(hCtl = GetDlgItem(hDlg, chx2), SW_HIDE);
        EnableWindow(hCtl, FALSE);
    }
    else if (pFR->Flags & FR_NOMATCHCASE)
    {
        EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
    }
    CheckDlgButton(hDlg, chx2, (pFR->Flags & FR_MATCHCASE) ? TRUE: FALSE);

    //
    //  Dis/Enable check state of UP/DOWN buttons.
    //
    if (pFR->Flags & FR_HIDEUPDOWN)
    {
        ShowWindow(GetDlgItem(hDlg, grp1), SW_HIDE);
        ShowWindow(hCtl = GetDlgItem(hDlg, rad1), SW_HIDE);
        EnableWindow(hCtl, FALSE);
        ShowWindow(hCtl = GetDlgItem(hDlg, rad2), SW_HIDE);
        EnableWindow(hCtl, FALSE);
    }
    else if (pFR->Flags & FR_NOUPDOWN)
    {
        EnableWindow(GetDlgItem(hDlg, rad1), FALSE);
        EnableWindow(GetDlgItem(hDlg, rad2), FALSE);
    }

    if (DlgType == DLGT_FIND)
    {
        //
        //  Find Text only search direction setup.
        //
        CheckRadioButton( hDlg,
                          rad1,
                          rad2,
                          (pFR->Flags & FR_DOWN ? rad2 : rad1) );
    }
    else
    {
        //
        //  Replace Text only operations.
        //
#ifdef UNICODE
        if (ApiType == COMDLG_ANSI)
        {
             SetDlgItemTextA(hDlg, edt2, (LPSTR)pFR->lpstrReplaceWith);
        }
        else
#endif
        {
             SetDlgItemText(hDlg, edt2, pFR->lpstrReplaceWith);
        }
        SendMessage( hDlg,
                     WM_COMMAND,
                     GET_WM_COMMAND_MPS(edt2, 0, EN_CHANGE) );
    }
}


////////////////////////////////////////////////////////////////////////////
//
//  UpdateTextAndFlags
//
//  chx1 is whether or not to match entire words
//  chx2 is whether or not case is relevant
//  chx3 is whether or not to wrap scans
//
////////////////////////////////////////////////////////////////////////////

VOID UpdateTextAndFlags(
    HWND hDlg,
    LPFINDREPLACE pFR,
    DWORD dwActionFlag,
    UINT DlgType,
    UINT ApiType)
{
    //
    //  Only clear flags that this routine sets.  The hook and template
    //  flags should not be anded off here.
    //
    pFR->Flags &= ~((DWORD)(FR_WHOLEWORD | FR_MATCHCASE | FR_REPLACE |
                            FR_FINDNEXT | FR_REPLACEALL | FR_DOWN));
    if (IsDlgButtonChecked(hDlg, chx1))
    {
        pFR->Flags |= FR_WHOLEWORD;
    }

    if (IsDlgButtonChecked(hDlg, chx2))
    {
        pFR->Flags |= FR_MATCHCASE;
    }

    //
    //  Set ACTION flag FR_{REPLACE,FINDNEXT,REPLACEALL}.
    //
    pFR->Flags |= dwActionFlag;

#ifdef UNICODE
    if (ApiType == COMDLG_ANSI)
    {
        GetDlgItemTextA(hDlg, edt1, (LPSTR)pFR->lpstrFindWhat, pFR->wFindWhatLen);
    }
    else
#endif
    {
        GetDlgItemText(hDlg, edt1, pFR->lpstrFindWhat, pFR->wFindWhatLen);
    }

    if (DlgType == DLGT_FIND)
    {
        //
        //  Assume searching down.  Check if UP button is NOT pressed, rather
        //  than if DOWN button IS.  So, if buttons have been hidden or
        //  disabled, FR_DOWN flag will be set correctly.
        //
        if (!IsDlgButtonChecked(hDlg, rad1))
        {
            pFR->Flags |= FR_DOWN;
        }
    }
    else
    {
#ifdef UNICODE
        if (ApiType == COMDLG_ANSI)
        {
            GetDlgItemTextA( hDlg,
                             edt2,
                             (LPSTR)pFR->lpstrReplaceWith,
                             pFR->wReplaceWithLen );
        }
        else
#endif
        {
            GetDlgItemText( hDlg,
                            edt2,
                            pFR->lpstrReplaceWith,
                            pFR->wReplaceWithLen );
        }
        pFR->Flags |= FR_DOWN;
    }
}


////////////////////////////////////////////////////////////////////////////
//
//  NotifyUpdateTextAndFlags
//
////////////////////////////////////////////////////////////////////////////

LRESULT NotifyUpdateTextAndFlags(
    LPFINDREPLACE pFR)
{
    if (IS16BITWOWAPP(pFR))
    {
        return ( SendMessage( pFR->hwndOwner,
                              WM_NOTIFYWOW,
                              WMNW_UPDATEFINDREPLACE,
                              (DWORD_PTR)pFR ) );
    }
    return ( SendMessage(pFR->hwndOwner, wFRMessage, 0, (DWORD_PTR)pFR) );
}
