⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 viewedit.cpp

📁 vc6.0完整版
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

void CEditView::OnEditReplace()
{
	ASSERT_VALID(this);
	OnEditFindReplace(FALSE);
	ASSERT_VALID(this);
}

void CEditView::OnEditRepeat()
{
	ASSERT_VALID(this);
	_AFX_EDIT_STATE* pEditState = _afxEditState;
	if (!FindText(pEditState->strFind,
		pEditState->bNext,
		pEditState->bCase))
	{
		OnTextNotFound(pEditState->strFind);
	}
	ASSERT_VALID(this);
}

void CEditView::OnEditFindReplace(BOOL bFindOnly)
{
	ASSERT_VALID(this);
	_AFX_EDIT_STATE* pEditState = _afxEditState;
	if (pEditState->pFindReplaceDlg != NULL)
	{
		if (pEditState->bFindOnly == bFindOnly)
		{
			pEditState->pFindReplaceDlg->SetActiveWindow();
			pEditState->pFindReplaceDlg->ShowWindow(SW_SHOW);
			return;
		}
		ASSERT(pEditState->bFindOnly != bFindOnly);
		pEditState->pFindReplaceDlg->SendMessage(WM_CLOSE);
		ASSERT(pEditState->pFindReplaceDlg == NULL);
		ASSERT_VALID(this);
	}

	CString strFind;
	GetSelectedText(strFind);
	if (strFind.IsEmpty())
		strFind = pEditState->strFind;
	CString strReplace = pEditState->strReplace;
	pEditState->pFindReplaceDlg = new CFindReplaceDialog;
	ASSERT(pEditState->pFindReplaceDlg != NULL);
	DWORD dwFlags = FR_HIDEWHOLEWORD;
	if (pEditState->bNext)
		dwFlags |= FR_DOWN;
	if (pEditState->bCase)
		dwFlags |= FR_MATCHCASE;
	if (!pEditState->pFindReplaceDlg->Create(bFindOnly, strFind,
		strReplace, dwFlags, this))
	{
		pEditState->pFindReplaceDlg = NULL;
		ASSERT_VALID(this);
		return;
	}

	pEditState->pFindReplaceDlg->SetActiveWindow();
	pEditState->pFindReplaceDlg->ShowWindow(SW_SHOW);
	ASSERT(pEditState->pFindReplaceDlg != NULL);
	pEditState->bFindOnly = bFindOnly;
	ASSERT_VALID(this);
}

void CEditView::OnFindNext(LPCTSTR lpszFind, BOOL bNext, BOOL bCase)
{
	ASSERT_VALID(this);
	_AFX_EDIT_STATE* pEditState = _afxEditState;
	pEditState->strFind = lpszFind;
	pEditState->bCase = bCase;
	pEditState->bNext = bNext;

	if (!FindText(pEditState->strFind, bNext, bCase))
		OnTextNotFound(pEditState->strFind);
	ASSERT_VALID(this);
}

void CEditView::OnReplaceSel(LPCTSTR lpszFind, BOOL bNext, BOOL bCase,
	LPCTSTR lpszReplace)
{
	ASSERT_VALID(this);
	_AFX_EDIT_STATE* pEditState = _afxEditState;
	pEditState->strFind = lpszFind;
	pEditState->strReplace = lpszReplace;
	pEditState->bCase = bCase;
	pEditState->bNext = bNext;

	if (!InitializeReplace())
		return;

	GetEditCtrl().ReplaceSel(pEditState->strReplace);
	FindText(pEditState->strFind, bNext, bCase);
	ASSERT_VALID(this);
}

void CEditView::OnReplaceAll(LPCTSTR lpszFind, LPCTSTR lpszReplace, BOOL bCase)
{
	ASSERT_VALID(this);
	_AFX_EDIT_STATE* pEditState = _afxEditState;
	pEditState->strFind = lpszFind;
	pEditState->strReplace = lpszReplace;
	pEditState->bCase = bCase;
	pEditState->bNext = TRUE;

	if (!InitializeReplace() &&
		!SameAsSelected(pEditState->strFind, pEditState->bCase))
	{
		// initial find was not successful
		return;
	}

	do
	{
		GetEditCtrl().ReplaceSel(pEditState->strReplace);
	} while (FindText(pEditState->strFind, 1, bCase));

	ASSERT_VALID(this);
}

BOOL CEditView::InitializeReplace()
	// helper to do find first if no selection
{
	ASSERT_VALID(this);

	_AFX_EDIT_STATE* pEditState = _afxEditState;

	// do find next if no selection
	int nStartChar, nEndChar;
	GetEditCtrl().GetSel(nStartChar, nEndChar);
	if (nStartChar == nEndChar)
	{
		if (!FindText(pEditState->strFind, pEditState->bNext,
			pEditState->bCase))
		{
			// text not found
			OnTextNotFound(pEditState->strFind);
		}
		return FALSE;
	}

	if (!SameAsSelected(pEditState->strFind, pEditState->bCase))
	{
		if (!FindText(pEditState->strFind, pEditState->bNext,
			pEditState->bCase))
		{
			// text not found
			OnTextNotFound(pEditState->strFind);
		}
		return FALSE;
	}

	ASSERT_VALID(this);
	return TRUE;
}

LRESULT CEditView::OnFindReplaceCmd(WPARAM, LPARAM lParam)
{
	ASSERT_VALID(this);

	_AFX_EDIT_STATE* pEditState = _afxEditState;
	CFindReplaceDialog* pDialog = CFindReplaceDialog::GetNotifier(lParam);
	ASSERT(pDialog != NULL);
	ASSERT(pDialog == pEditState->pFindReplaceDlg);
	if (pDialog->IsTerminating())
	{
		pEditState->pFindReplaceDlg = NULL;
	}
	else if (pDialog->FindNext())
	{
		OnFindNext(pDialog->GetFindString(),
			pDialog->SearchDown(), pDialog->MatchCase());
	}
	else if (pDialog->ReplaceCurrent())
	{
		ASSERT(!pEditState->bFindOnly);
		OnReplaceSel(pDialog->GetFindString(),
			pDialog->SearchDown(), pDialog->MatchCase(),
			pDialog->GetReplaceString());
	}
	else if (pDialog->ReplaceAll())
	{
		ASSERT(!pEditState->bFindOnly);
		OnReplaceAll(pDialog->GetFindString(), pDialog->GetReplaceString(),
			pDialog->MatchCase());
	}
	ASSERT_VALID(this);
	return 0;
}

typedef int (WINAPI* AFX_COMPARE_PROC)(LPCTSTR str1, LPCTSTR str2);

BOOL CEditView::SameAsSelected(LPCTSTR lpszCompare, BOOL bCase)
{
	// check length first
	size_t nLen = lstrlen(lpszCompare);
	int nStartChar, nEndChar;
	GetEditCtrl().GetSel(nStartChar, nEndChar);
	if (nLen != (size_t)(nEndChar - nStartChar))
		return FALSE;

	// length is the same, check contents
	CString strSelect;
	GetSelectedText(strSelect);
	return (bCase && lstrcmp(lpszCompare, strSelect) == 0) ||
		(!bCase && lstrcmpi(lpszCompare, strSelect) == 0);
}

BOOL CEditView::FindText(LPCTSTR lpszFind, BOOL bNext, BOOL bCase)
{
	ASSERT_VALID(this);
	ASSERT(lpszFind != NULL);
	ASSERT(*lpszFind != '\0');

	UINT nLen = GetBufferLength();
	int nStartChar, nEndChar;
	GetEditCtrl().GetSel(nStartChar, nEndChar);
	UINT nStart = nStartChar;
	int iDir = bNext ? +1 : -1;

	// can't find a match before the first character
	if (nStart == 0 && iDir < 0)
		return FALSE;

	CWaitCursor wait;
	LPCTSTR lpszText = LockBuffer();

	if (iDir < 0)
	{
		// always go back one for search backwards
		nStart -= (lpszText+nStart) -
			_tcsdec(lpszText, lpszText+nStart);
	}
	else if (nStartChar != nEndChar && SameAsSelected(lpszFind, bCase))
	{
		// easy to go backward/forward with SBCS
		if (_istlead(lpszText[nStart]))
			nStart++;
		nStart += iDir;
	}

	// handle search with nStart past end of buffer
	size_t nLenFind = lstrlen(lpszFind);
	if (nStart+nLenFind-1 >= nLen)
	{
		if (iDir < 0 && nLen >= nLenFind)
		{
			if (_afxDBCS)
			{
				// walk back to previous character n times
				nStart = nLen;
				int n = nLenFind;
				while (n--)
				{
					nStart -= (lpszText+nStart) -
						_tcsdec(lpszText, lpszText+nStart);
				}
			}
			else
			{
				// single-byte character set is easy and fast
				nStart = nLen - nLenFind;
			}
			ASSERT(nStart+nLenFind-1 <= nLen);
		}
		else
		{
			UnlockBuffer();
			return FALSE;
		}
	}

	// start the search at nStart
	LPCTSTR lpsz = lpszText + nStart;
	AFX_COMPARE_PROC pfnCompare = bCase ? lstrcmp : lstrcmpi;

	if (_afxDBCS)
	{
		// double-byte string search
		LPCTSTR lpszStop;
		if (iDir > 0)
		{
			// start at current and find _first_ occurrance
			lpszStop = lpszText + nLen - nLenFind + 1;
		}
		else
		{
			// start at top and find _last_ occurrance
			lpszStop = lpsz;
			lpsz = lpszText;
		}

		LPCTSTR lpszFound = NULL;
		while (lpsz <= lpszStop)
		{
			if (!bCase || (*lpsz == *lpszFind &&
				(!_istlead(*lpsz) || lpsz[1] == lpszFind[1])))
			{
				LPTSTR lpch = (LPTSTR)(lpsz + nLenFind);
				TCHAR chSave = *lpch;
				*lpch = '\0';
				int nResult = (*pfnCompare)(lpsz, lpszFind);
				*lpch = chSave;
				if (nResult == 0)
				{
					lpszFound = lpsz;
					if (iDir > 0)
						break;
				}
			}
			lpsz = _tcsinc(lpsz);
		}
		UnlockBuffer();

		if (lpszFound != NULL)
		{
			int n = (int)(lpszFound - lpszText);
			GetEditCtrl().SetSel(n, n+nLenFind);
			return TRUE;
		}
	}
	else
	{
		// single-byte string search
		UINT nCompare;
		if (iDir < 0)
			nCompare = (UINT)(lpsz - lpszText) + 1;
		else
			nCompare = nLen - (UINT)(lpsz - lpszText) - nLenFind + 1;

		while (nCompare > 0)
		{
			ASSERT(lpsz >= lpszText);
			ASSERT(lpsz+nLenFind-1 <= lpszText+nLen-1);

			LPSTR lpch = (LPSTR)(lpsz + nLenFind);
			char chSave = *lpch;
			*lpch = '\0';
			int nResult = (*pfnCompare)(lpsz, lpszFind);
			*lpch = chSave;
			if (nResult == 0)
			{
				UnlockBuffer();
				int n = (int)(lpsz - lpszText);
				GetEditCtrl().SetSel(n, n+nLenFind);
				ASSERT_VALID(this);
				return TRUE;
			}

			// restore character at end of search
			*lpch = chSave;

			// move on to next substring
			nCompare--;
			lpsz += iDir;
		}
		UnlockBuffer();
	}

	ASSERT_VALID(this);
	return FALSE;
}

void CEditView::OnTextNotFound(LPCTSTR)
{
	ASSERT_VALID(this);
	MessageBeep(0);
}

/////////////////////////////////////////////////////////////////////////////
// CEditView Tab Stops

void CEditView::SetTabStops(int nTabStops)
{
	ASSERT_VALID(this);
	m_nTabStops = nTabStops;
	GetEditCtrl().SetTabStops(m_nTabStops);
	Invalidate();
	ASSERT_VALID(this);
}

/////////////////////////////////////////////////////////////////////////////
// CEditView diagnostics

#ifdef _DEBUG
void CEditView::AssertValid() const
{
	CCtrlView::AssertValid();
	ASSERT_VALID(&m_aPageStart);
	if (m_hPrinterFont != NULL)
		ASSERT_VALID(CFont::FromHandle(m_hPrinterFont));
	if (m_hMirrorFont != NULL)
		ASSERT_VALID(CFont::FromHandle(m_hMirrorFont));
	_AFX_EDIT_STATE* pEditState = _afxEditState;
	if (pEditState->pFindReplaceDlg != NULL)
		ASSERT_VALID(pEditState->pFindReplaceDlg);
}

void CEditView::Dump(CDumpContext& dc) const
{
	CCtrlView::Dump(dc);

	dc << "m_nTabStops = " << m_nTabStops;
	if (m_hPrinterFont != NULL)
		dc << "\nm_hPrinterFont " << (UINT)m_hPrinterFont;
	if (m_hMirrorFont != NULL)
		dc << "\nm_hMirrorFont " << (UINT)m_hMirrorFont;
	dc << "\nm_aPageStart: " << &m_aPageStart;
	dc << "\nstatic member data:";
	_AFX_EDIT_STATE* pEditState = _afxEditState;
	if (pEditState->pFindReplaceDlg != NULL)
	{
		dc << "\npFindReplaceDlg = "
			<< (void*)pEditState->pFindReplaceDlg;
		dc << "\nbFindOnly = " << pEditState->bFindOnly;
	}
	dc << "\nstrFind = " << pEditState->strFind;
	dc << "\nstrReplace = " << pEditState->strReplace;
	dc << "\nbCase = " << pEditState->bCase;
	dc << "\nbNext = " << pEditState->bNext;

	dc << "\n";
}
#endif //_DEBUG

#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif

IMPLEMENT_DYNCREATE(CEditView, CCtrlView)

#pragma warning(disable: 4074)
#pragma init_seg(lib)

PROCESS_LOCAL(_AFX_EDIT_STATE, _afxEditState)

/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -