Annotation of mstools/mfc/samples/multipad/mpfind.cpp, revision 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.