chenluhua1980
2026-01-06 4d9d8d22e3666076988c30afb4e7c6fe365c19aa
SourceCode/Bond/Servo/LogEdit.cpp
@@ -8,7 +8,9 @@
CLogEdit::CLogEdit()
{
   m_nMaxLineCount = 0xffff;
   m_nMaxLines = 0xffff;
   m_nTrimLines = 100;
   m_bAutoScroll = TRUE;
}
@@ -18,11 +20,14 @@
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)
@@ -49,39 +54,64 @@
   }
}
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();
    }
}