📄 viewedit.cpp
字号:
{
// get current screen font object metrics
CFont* pFont = GetFont();
LOGFONT lf;
LOGFONT lfSys;
if (pFont == NULL)
return;
VERIFY(pFont->GetObject(sizeof(LOGFONT), &lf));
VERIFY(::GetObject(::GetStockObject(SYSTEM_FONT), sizeof(LOGFONT),
&lfSys));
if (lstrcmpi((LPCTSTR)lf.lfFaceName, (LPCTSTR)lfSys.lfFaceName) == 0)
return;
// map to printer font metrics
HDC hDCFrom = ::GetDC(NULL);
lf.lfHeight = ::MulDiv(lf.lfHeight, pDC->GetDeviceCaps(LOGPIXELSY),
::GetDeviceCaps(hDCFrom, LOGPIXELSY));
lf.lfWidth = ::MulDiv(lf.lfWidth, pDC->GetDeviceCaps(LOGPIXELSX),
::GetDeviceCaps(hDCFrom, LOGPIXELSX));
::ReleaseDC(NULL, hDCFrom);
// create it, if it fails we just use the printer's default.
m_hMirrorFont = ::CreateFontIndirect(&lf);
m_hPrinterFont = m_hMirrorFont;
}
ASSERT_VALID(this);
}
BOOL CEditView::PaginateTo(CDC* pDC, CPrintInfo* pInfo)
// attempts pagination to pInfo->m_nCurPage, TRUE == success
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
CRect rectSave = pInfo->m_rectDraw;
UINT nPageSave = pInfo->m_nCurPage;
ASSERT(nPageSave > 1);
ASSERT(nPageSave >= (UINT)m_aPageStart.GetSize());
VERIFY(pDC->SaveDC() != 0);
pDC->IntersectClipRect(0, 0, 0, 0);
pInfo->m_nCurPage = m_aPageStart.GetSize();
while (pInfo->m_nCurPage < nPageSave)
{
ASSERT(pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize());
OnPrepareDC(pDC, pInfo);
ASSERT(pInfo->m_bContinuePrinting);
pInfo->m_rectDraw.SetRect(0, 0,
pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
pDC->DPtoLP(&pInfo->m_rectDraw);
OnPrint(pDC, pInfo);
if (pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize())
break;
++pInfo->m_nCurPage;
}
BOOL bResult = pInfo->m_nCurPage == nPageSave;
pDC->RestoreDC(-1);
pInfo->m_nCurPage = nPageSave;
pInfo->m_rectDraw = rectSave;
ASSERT_VALID(this);
return bResult;
}
void CEditView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
ASSERT(pInfo != NULL); // overriding OnPaint -- never get this.
if (pInfo->m_nCurPage > (UINT)m_aPageStart.GetSize() &&
!PaginateTo(pDC, pInfo))
{
// can't paginate to that page, thus cannot print it.
pInfo->m_bContinuePrinting = FALSE;
}
ASSERT_VALID(this);
}
UINT CEditView::PrintInsideRect(CDC* pDC, RECT& rectLayout,
UINT nIndexStart, UINT nIndexStop)
// worker function for laying out text in a rectangle.
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
BOOL bWordWrap = (GetStyle() & ES_AUTOHSCROLL) == 0;
// get buffer and real starting and ending postions
UINT nLen = GetBufferLength();
if (nIndexStart >= nLen)
return nLen;
LPCTSTR lpszText = LockBuffer();
if (nIndexStop > nLen)
nIndexStop = nLen;
ASSERT(nIndexStart < nLen);
// calculate text & tab metrics
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm);
int cyChar = tm.tmHeight + tm.tmExternalLeading;
int nTabStop = m_nTabStops *
pDC->GetTabbedTextExtent(_T("\t"), 1, 0, NULL).cx / 8 / 4;
int aCharWidths[256];
pDC->GetCharWidth(0, 255, aCharWidths);
int y = rectLayout.top;
UINT cx = rectLayout.right - rectLayout.left;
UINT nIndex = nIndexStart;
VERIFY(pDC->SaveDC() != 0);
BOOL bLayoutOnly = pDC->IntersectClipRect(&rectLayout) == NULLREGION;
do
{
UINT nIndexEnd = _AfxEndOfLine(lpszText, nIndexStop, nIndex);
if (nIndex == nIndexEnd)
{
y += cyChar;
}
else if (bWordWrap)
{
// word-wrap printing
do
{
UINT nIndexWrap = _AfxClipLine(pDC, aCharWidths,
cx, nTabStop, lpszText, nIndex, nIndexEnd);
UINT nIndexWord = nIndexWrap;
if (nIndexWord != nIndexEnd)
{
while (nIndexWord > nIndex &&
!_istspace(lpszText[nIndexWord]))
{
nIndexWord--;
}
if (nIndexWord == nIndex)
nIndexWord = nIndexWrap;
}
CRect rect(rectLayout.left, y, rectLayout.right, y+cyChar);
if (!bLayoutOnly && pDC->RectVisible(rect))
{
pDC->TabbedTextOut(rect.left, y,
(LPCTSTR)(lpszText+nIndex), nIndexWord-nIndex, 1,
&nTabStop, rect.left);
}
y += cyChar;
nIndex = nIndexWord;
while (nIndex < nIndexEnd && _istspace(lpszText[nIndex]))
nIndex++;
} while (nIndex < nIndexEnd && y+cyChar <= rectLayout.bottom);
nIndexEnd = nIndex;
}
else
{
// non-word wrap printing (much easier and faster)
CRect rect(rectLayout.left, y, rectLayout.right, y+cyChar);
if (!bLayoutOnly && pDC->RectVisible(rect))
{
UINT nIndexClip = _AfxClipLine(pDC, aCharWidths, cx, nTabStop,
lpszText, nIndex, nIndexEnd);
if (nIndexClip < nIndexEnd)
{
if (_istlead(*(lpszText+nIndexClip)))
nIndexClip++;
nIndexClip++;
}
pDC->TabbedTextOut(rect.left, y,
(LPCTSTR)(lpszText+nIndex), nIndexClip-nIndex, 1,
&nTabStop, rect.left);
}
y += cyChar;
}
nIndex = _AfxNextLine(lpszText, nIndexStop, nIndexEnd);
}
while (nIndex < nIndexStop && y+cyChar <= rectLayout.bottom);
pDC->RestoreDC(-1);
UnlockBuffer();
ASSERT_VALID(this);
rectLayout.bottom = y;
return nIndex;
}
void CEditView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
ASSERT(pInfo != NULL);
ASSERT(pInfo->m_bContinuePrinting);
CFont* pOldFont = NULL;
if (m_hPrinterFont != NULL)
pOldFont = pDC->SelectObject(CFont::FromHandle(m_hPrinterFont));
pDC->SetBkMode(TRANSPARENT);
UINT nPage = pInfo->m_nCurPage;
ASSERT(nPage <= (UINT)m_aPageStart.GetSize());
UINT nIndex = m_aPageStart[nPage-1];
// print as much as possible in the current page.
nIndex = PrintInsideRect(pDC, pInfo->m_rectDraw, nIndex, GetBufferLength());
if (pOldFont != NULL)
pDC->SelectObject(pOldFont);
// update pagination information for page just printed
if (nPage == (UINT)m_aPageStart.GetSize())
{
if (nIndex < GetBufferLength())
m_aPageStart.Add(nIndex);
}
else
{
ASSERT(nPage+1 <= (UINT)m_aPageStart.GetSize());
ASSERT(nIndex == m_aPageStart[nPage+1-1]);
}
}
void CEditView::OnEndPrinting(CDC*, CPrintInfo*)
{
ASSERT_VALID(this);
m_aPageStart.RemoveAll();
if (m_hMirrorFont != NULL && m_hPrinterFont == m_hMirrorFont)
{
AfxDeleteObject((HGDIOBJ*)&m_hMirrorFont);
m_hPrinterFont = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////
// CEditView commands
void CEditView::OnUpdateNeedSel(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
int nStartChar, nEndChar;
GetEditCtrl().GetSel(nStartChar, nEndChar);
pCmdUI->Enable(nStartChar != nEndChar);
ASSERT_VALID(this);
}
void CEditView::OnUpdateNeedClip(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
pCmdUI->Enable(::IsClipboardFormatAvailable(CF_TEXT));
ASSERT_VALID(this);
}
void CEditView::OnUpdateNeedText(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
pCmdUI->Enable(GetWindowTextLength() != 0);
ASSERT_VALID(this);
}
void CEditView::OnUpdateNeedFind(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
_AFX_EDIT_STATE* pEditState = _afxEditState;
pCmdUI->Enable(GetWindowTextLength() != 0 &&
!pEditState->strFind.IsEmpty());
ASSERT_VALID(this);
}
void CEditView::OnUpdateEditUndo(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
pCmdUI->Enable(GetEditCtrl().CanUndo());
ASSERT_VALID(this);
}
BOOL CEditView::OnEditChange()
{
ASSERT_VALID(this);
GetDocument()->SetModifiedFlag();
ASSERT_VALID(this);
return FALSE; // continue routing
}
void CEditView::OnEditCut()
{
ASSERT_VALID(this);
GetEditCtrl().Cut();
ASSERT_VALID(this);
}
void CEditView::OnEditCopy()
{
ASSERT_VALID(this);
GetEditCtrl().Copy();
ASSERT_VALID(this);
}
void CEditView::OnEditPaste()
{
ASSERT_VALID(this);
GetEditCtrl().Paste();
ASSERT_VALID(this);
}
void CEditView::OnEditClear()
{
ASSERT_VALID(this);
GetEditCtrl().Clear();
ASSERT_VALID(this);
}
void CEditView::OnEditUndo()
{
ASSERT_VALID(this);
GetEditCtrl().Undo();
ASSERT_VALID(this);
}
void CEditView::OnEditSelectAll()
{
ASSERT_VALID(this);
GetEditCtrl().SetSel(0, -1);
ASSERT_VALID(this);
}
/////////////////////////////////////////////////////////////////////////////
// CEditView Font Handling
LRESULT CEditView::OnSetFont(WPARAM, LPARAM)
{
ASSERT_VALID(this);
Default();
GetEditCtrl().SetTabStops(m_nTabStops);
ASSERT_VALID(this);
return 0;
}
void CEditView::SetPrinterFont(CFont* pFont)
{
ASSERT_VALID(this);
m_hPrinterFont = (HFONT)pFont->GetSafeHandle();
ASSERT_VALID(this);
}
CFont* CEditView::GetPrinterFont() const
{
ASSERT_VALID(this);
return CFont::FromHandle(m_hPrinterFont);
}
/////////////////////////////////////////////////////////////////////////////
// CEditView attributes
LPCTSTR CEditView::LockBuffer() const
{
ASSERT_VALID(this);
ASSERT(m_hWnd != NULL);
#ifndef _UNICODE
if (afxData.bWin95)
{
// under Win32s, it is necessary to maintain a shadow buffer
// it is only updated when the control contents have been changed.
if (m_pShadowBuffer == NULL || GetEditCtrl().GetModify())
{
ASSERT(m_pShadowBuffer != NULL || m_nShadowSize == 0);
UINT nSize = GetWindowTextLength()+1;
if (nSize > m_nShadowSize)
{
// need more room for shadow buffer
CEditView* pThis = (CEditView*)this;
delete[] m_pShadowBuffer;
pThis->m_pShadowBuffer = NULL;
pThis->m_nShadowSize = 0;
pThis->m_pShadowBuffer = new TCHAR[nSize];
pThis->m_nShadowSize = nSize;
}
// update the shadow buffer with GetWindowText
ASSERT(m_nShadowSize >= nSize);
ASSERT(m_pShadowBuffer != NULL);
GetWindowText(m_pShadowBuffer, nSize);
// turn off edit control's modify bit
GetEditCtrl().SetModify(FALSE);
}
return m_pShadowBuffer;
}
#endif
// else -- running under non-subset Win32 system
HLOCAL hLocal = GetEditCtrl().GetHandle();
ASSERT(hLocal != NULL);
LPCTSTR lpszText = (LPCTSTR)LocalLock(hLocal);
ASSERT(lpszText != NULL);
ASSERT_VALID(this);
return lpszText;
}
void CEditView::UnlockBuffer() const
{
ASSERT_VALID(this);
ASSERT(m_hWnd != NULL);
#ifndef _UNICODE
if (afxData.bWin95)
return;
#endif
HLOCAL hLocal = GetEditCtrl().GetHandle();
ASSERT(hLocal != NULL);
LocalUnlock(hLocal);
}
// this function returns the length in characters
UINT CEditView::GetBufferLength() const
{
ASSERT_VALID(this);
ASSERT(m_hWnd != NULL);
LPCTSTR lpszText = LockBuffer();
UINT nLen = lstrlen(lpszText);
UnlockBuffer();
return nLen;
}
void CEditView::GetSelectedText(CString& strResult) const
{
ASSERT_VALID(this);
int nStartChar, nEndChar;
GetEditCtrl().GetSel(nStartChar, nEndChar);
ASSERT((UINT)nEndChar <= GetBufferLength());
LPCTSTR lpszText = ((CEditView*)this)->LockBuffer();
UINT nLen = _AfxEndOfLine(lpszText, nEndChar, nStartChar) - nStartChar;
memcpy(strResult.GetBuffer(nLen), lpszText + nStartChar,
nLen * sizeof(TCHAR));
strResult.ReleaseBuffer(nLen);
UnlockBuffer();
ASSERT_VALID(this);
}
/////////////////////////////////////////////////////////////////////////////
// CEditView Find & Replace
void CEditView::OnEditFind()
{
ASSERT_VALID(this);
OnEditFindReplace(TRUE);
ASSERT_VALID(this);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -