Annotation of mstools/mfc/samples/multipad/mpfind.cpp, revision 1.1.1.2

1.1       root        1: // mpfind.cpp : Defines the class behaviors for the text searches.
                      2: //
                      3: // This is a part of the Microsoft Foundation Classes C++ library.
                      4: // Copyright (C) 1992 Microsoft Corporation
                      5: // All rights reserved.
                      6: //
                      7: // This source code is only intended as a supplement to the
                      8: // Microsoft Foundation Classes Reference and Microsoft
                      9: // QuickHelp documentation provided with the library.
                     10: // See these sources for detailed information regarding the
                     11: // Microsoft Foundation Classes product.
                     12: 
                     13: #include "multipad.h"
                     14: #include "ctype.h" // for _tolower
                     15: 
1.1.1.2 ! root       16: #ifndef _NTWIN
1.1       root       17: #pragma code_seg("_MPFIND")
1.1.1.2 ! root       18: #endif
1.1       root       19: 
                     20: // HIWORD and LOWORD as defined are not able to be used as lvalues, so
                     21: // "HIWORD(dwVar) = 0xFFFF" are normally impossible.  These macros allow it.
                     22: //
                     23: #undef HIWORD
                     24: #undef LOWORD
                     25: #define HIWORD(l) (((WORD*)&(l))[1])
                     26: #define LOWORD(l) (((WORD*)&(l))[0])
                     27: 
                     28: ///////////////////////////////////////////////////////////////////////////
                     29: // Search dialog stuff
                     30: UINT CMPFrame::m_nMsgFind = ::RegisterWindowMessage(FINDMSGSTRING);
                     31: CFindReplaceDialog* CMPFrame::m_pFindReplace = NULL;
                     32: CString CMPFrame::m_strFind;
                     33: static BOOL bMatchCase = FALSE;
                     34: 
                     35: LONG
                     36: CMPFrame::CmdFindHelper(UINT wParam, LONG lParam)
                     37: {
                     38:        CFindReplaceDialog* pDlgFR = CFindReplaceDialog::GetNotifier(lParam);
                     39:        ASSERT(pDlgFR == m_pFindReplace);
                     40: 
                     41:        if (pDlgFR->IsTerminating())
                     42:        {
                     43:                SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
                     44:                m_pFindReplace = NULL;  // DO NOT DELETE, DONE AUTOMATICALLY
                     45: 
                     46:                GetMenu()->EnableMenuItem(IDM_SEARCHFIND, MF_ENABLED);
                     47:                if (m_strFind.GetLength() > 0)
                     48:                {
                     49:                        GetMenu()->EnableMenuItem(IDM_SEARCHNEXT, MF_ENABLED);
                     50:                        GetMenu()->EnableMenuItem(IDM_SEARCHPREV, MF_ENABLED);
                     51:                }
                     52:        }
                     53:        else
                     54:        {
                     55:                ASSERT(m_pActiveChild != NULL);
                     56: 
                     57:                // look for string
                     58:                m_strFind = m_pFindReplace->GetFindString();
                     59:                if (m_strFind.GetLength() == 0)
                     60:                        return 0;
                     61: 
                     62:                if (m_pActiveChild->FindText(m_strFind,
                     63:                        m_pFindReplace->SearchDown() ? 
                     64:                                        CMPChild::searchDown : CMPChild::searchUp,
                     65:                        bMatchCase = m_pFindReplace->MatchCase()) == FALSE)
                     66:                {
                     67:                        MPError(MB_OK|MB_ICONEXCLAMATION, IDS_CANTFIND, (LPCSTR)m_strFind);
                     68:                }
                     69:                else
                     70:                {
                     71:                        GetMenu()->EnableMenuItem(IDM_SEARCHNEXT, MF_ENABLED);
                     72:                        GetMenu()->EnableMenuItem(IDM_SEARCHPREV, MF_ENABLED);
                     73:                        SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
                     74:                }
                     75:        }
                     76:        return 0;
                     77: }
                     78: 
                     79: // CmdFind:
                     80: // Invoke the search dialog.  Returns when the dialog is closed by the user.
                     81: //
                     82: void CMPFrame::CmdFind()
                     83: {
                     84:        ASSERT(m_pFindReplace == NULL);
                     85: 
                     86:        m_pFindReplace = new CFindReplaceDialog;
                     87:        if (m_pFindReplace->Create(TRUE, m_strFind, NULL,
                     88:                        FR_HIDEWHOLEWORD | FR_DOWN) == FALSE)
                     89:        {
                     90:                delete m_pFindReplace;
                     91:                m_pFindReplace = NULL;
                     92:                return;
                     93:        }
                     94:        GetMenu()->EnableMenuItem(IDM_SEARCHFIND, MF_GRAYED);
                     95: }
                     96: 
                     97: // CmdFindPrev:
                     98: //
                     99: void CMPFrame::CmdFindPrev(void)
                    100: {
                    101:        ASSERT(m_strFind.GetLength() != 0);
                    102:        ASSERT(m_pActiveChild != NULL);
                    103: 
                    104:        if (m_pActiveChild->FindText(m_strFind, CMPChild::searchUp,
                    105:                        bMatchCase) == FALSE)
                    106:                MPError(MB_OK | MB_ICONEXCLAMATION, IDS_CANTFIND, (LPCSTR)m_strFind);
                    107:        else
                    108:                SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
                    109: }
                    110: 
                    111: // CmdFindNext:
                    112: //
                    113: void CMPFrame::CmdFindNext(void)
                    114: {
                    115:        ASSERT(m_strFind.GetLength() != 0);
                    116:        ASSERT(m_pActiveChild != NULL);
                    117: 
                    118:        if (m_pActiveChild->FindText(m_strFind, CMPChild::searchDown,
                    119:                        bMatchCase) == FALSE)
                    120:                MPError(MB_OK | MB_ICONEXCLAMATION, IDS_CANTFIND, (LPCSTR)m_strFind);
                    121:        else
                    122:                SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
                    123: }
                    124: 
                    125: /////////////////////////////////////////////////////////////////////////////
                    126: // Search Engine code
                    127: // This code is the workhorse code to search through the text buffer looking
                    128: // for a particular substring.
                    129: 
                    130: // RealSlowCompare:
                    131: // This is the brute-force method, which leaves a lot to be desired in
                    132: // performance.  However, this works fine for the typical text-file-sized
                    133: // buffer, which is currently limited by Windows to 32Kb anyway.
                    134: //
                    135: BOOL NEAR PASCAL RealSlowCompare(PSTR pSubject, LPSTR pTarget, 
                    136:                BOOL fCase = FALSE)
                    137: {
                    138:        if (fCase)
                    139:        {
                    140:                while (*pTarget)
                    141:                {
                    142:                        if (*pTarget++ != *pSubject++)
                    143:                                return FALSE;
                    144:                }
                    145:        }
                    146:        else
                    147:        {
                    148:                // If case-insensitive, convert both subject and target
                    149:                // to lowercase before comparing.
                    150:                //
                    151:                while (*pTarget)
                    152:                {
                    153:                        if (::AnsiLower((LPSTR)(DWORD)*pTarget++) != 
                    154:                                ::AnsiLower((LPSTR)(DWORD)*pSubject++))
                    155:                                return FALSE;
                    156:                }
                    157:        }
                    158:        return TRUE;
                    159: }
                    160: 
                    161: // FindText:
                    162: // Takes the szSearch buffer and tries to find it in the text buffer.
                    163: // The nDirection may be 1 for forward searches or -1 for backward searches.
                    164: //
                    165: BOOL CMPChild::FindText(LPCSTR lpszSearch, 
                    166:                int nDirection /* = searchDown */, 
                    167:                BOOL bMatchCase /* = FALSE */,
                    168:                BOOL bWholeWord /* = FALSE */)
                    169: {
                    170:        PSTR pText;
                    171:        HANDLE hText;
                    172:        LONG lSel;
                    173:        UINT cch;
                    174:        int i;
                    175:        
                    176:        if (*lpszSearch == '\0')
                    177:                return TRUE;
                    178:        
                    179:        // Find the current selection range.
                    180:        //
                    181:        lSel = m_edit.GetSel();
                    182:        
                    183:        // Get the handle to the text buffer and lock it.
                    184:        //
                    185:        hText = m_edit.GetHandle();
                    186:        pText = (PSTR)LocalLock(hText);
                    187:        
                    188:        // Get the length of the text.
                    189:        //
                    190:        cch = m_edit.GetWindowTextLength();
                    191:        
                    192:        // Start with the next char in selected range.
                    193:        //
                    194:        pText += LOWORD(lSel) + nDirection;
                    195:        
                    196:        // Compute how many characters are before/after the current selection.
                    197:        //
                    198:        if (nDirection < 0)
                    199:                i = LOWORD(lSel);
                    200:        else
                    201:                i = cch - LOWORD(lSel) + 1 - lstrlen(lpszSearch);
                    202:        
                    203:        // While there are uncompared substrings.
                    204:        //
                    205:        while (i > 0)
                    206:        {
                    207:                LOWORD(lSel) += nDirection;
                    208:        
                    209:                // Does this substring match?
                    210:                //
                    211:                if (RealSlowCompare(pText, (LPSTR)lpszSearch, bMatchCase))
                    212:                {
                    213:                        // Unlock the buffer.
                    214:                        //
                    215:                        LocalUnlock(hText);
                    216:                        
                    217:                        // Select the located string.
                    218:                        //
                    219:                        HIWORD(lSel) = LOWORD(lSel) + lstrlen(lpszSearch);
                    220:                        m_edit.SetSel(lSel);
                    221:                        return TRUE;
                    222:                }
                    223:                i--;
                    224:                
                    225:                // Increment/decrement start position.
                    226:                //
                    227:                pText += nDirection;
                    228:        }
                    229:        
                    230:        // Not found... unlock buffer.
                    231:        //
                    232:        LocalUnlock(hText);
                    233:        
                    234:        return FALSE;
                    235: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.