| | |
| | | |
| | | CLogEdit::CLogEdit() |
| | | { |
| | | m_nMaxLineCount = 0xffff; |
| | | m_nMaxLines = 0xffff; |
| | | m_nTrimLines = 100; |
| | | m_bAutoScroll = TRUE; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | BEGIN_MESSAGE_MAP(CLogEdit, CEdit) |
| | | ON_WM_CONTEXTMENU() |
| | | ON_WM_VSCROLL() |
| | | ON_WM_MOUSEWHEEL() |
| | | END_MESSAGE_MAP() |
| | | |
| | | void CLogEdit::SetMaxLineCount(int line) |
| | | { |
| | | m_nMaxLineCount = line; |
| | | m_nMaxLines = line; |
| | | m_nTrimLines = min(m_nMaxLines, 4000); |
| | | } |
| | | |
| | | void CLogEdit::OnContextMenu(CWnd* pWnd, CPoint point) |
| | |
| | | } |
| | | } |
| | | |
| | | void CLogEdit::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) |
| | | { |
| | | // 每次滚动时检查是否还在底部 |
| | | m_bAutoScroll = IsScrollBarAtBottom(); |
| | | CEdit::OnVScroll(nSBCode, nPos, pScrollBar); |
| | | } |
| | | |
| | | BOOL CLogEdit::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) |
| | | { |
| | | // 每次滚动时检查是否还在底部 |
| | | m_bAutoScroll = IsScrollBarAtBottom(); |
| | | return CEdit::OnMouseWheel(nFlags, zDelta, pt); |
| | | } |
| | | |
| | | BOOL CLogEdit::IsScrollBarAtBottom() |
| | | { |
| | | SCROLLINFO si = { sizeof(si), SIF_ALL }; |
| | | GetScrollInfo(SB_VERT, &si); |
| | | return (si.nPos + (int)si.nPage >= si.nMax); |
| | | } |
| | | |
| | | void CLogEdit::AppendText(const char* pszText) |
| | | { |
| | | // 获取选择范围以便恢复 |
| | | int nStart, nEnd; |
| | | GetSel(nStart, nEnd); |
| | | SetRedraw(FALSE); |
| | | |
| | | // 剪切过多行 |
| | | int totalLines = GetLineCount(); |
| | | if (totalLines > m_nMaxLines) { |
| | | int startChar = LineIndex(0); |
| | | int endChar = LineIndex(m_nTrimLines); |
| | | if (startChar >= 0 && endChar > startChar) { |
| | | SetSel(startChar, endChar); |
| | | ReplaceSel(_T("")); |
| | | } |
| | | } |
| | | |
| | | // 超过指定行数则删除最前面的行 |
| | | int nLineCount = GetLineCount(); |
| | | while (nLineCount > m_nMaxLineCount) { |
| | | int nLin1End = LineIndex(1); |
| | | nStart -= nLin1End; |
| | | if (nStart < 0) nStart = 0; |
| | | nEnd -= nLin1End; |
| | | if (nEnd < 0) nEnd = 0; |
| | | // 保存当前选择 |
| | | int start, end; |
| | | GetSel(start, end); |
| | | bool hasSelection = (start != end); |
| | | |
| | | SetSel(0, nLin1End); |
| | | ReplaceSel(_T("")); |
| | | nLineCount = GetLineCount(); |
| | | } |
| | | int endPos = GetWindowTextLength(); |
| | | SetSel(endPos, endPos); |
| | | ReplaceSel(pszText); |
| | | |
| | | if (m_bAutoScroll && !hasSelection) { |
| | | LineScroll(GetLineCount()); |
| | | } |
| | | |
| | | // 追加到最后 |
| | | int length = GetWindowTextLength(); |
| | | SetSel(length, length); |
| | | ReplaceSel(pszText); |
| | | PostMessage(WM_VSCROLL, SB_BOTTOM, 0); |
| | | // 恢复选择 |
| | | if (hasSelection) { |
| | | SetSel(start, end); |
| | | } |
| | | |
| | | SetRedraw(TRUE); |
| | | |
| | | // 恢复 |
| | | if (nStart == 0 && nEnd == 0) { |
| | | nStart = GetWindowTextLength(); |
| | | nEnd = nStart; |
| | | } |
| | | SetSel(nStart, nEnd); |
| | | if (m_bAutoScroll && !hasSelection) { |
| | | Invalidate(); |
| | | UpdateWindow(); |
| | | } |
| | | } |