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

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

unix.superglobalmegacorp.com

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