LAPTOP-SNT8I5JK\Boounion
2025-06-25 a4f4d9aa60ac7b9137047ed1e7dc8e1ef822ff19
1.日志窗口的自动流动模式和固定模式自动切换;
已修改2个文件
73 ■■■■■ 文件已修改
SourceCode/Bond/Servo/LogEdit.cpp 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/LogEdit.h 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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,13 @@
BEGIN_MESSAGE_MAP(CLogEdit, CEdit)
    ON_WM_CONTEXTMENU()
    ON_WM_VSCROLL()
END_MESSAGE_MAP()
void CLogEdit::SetMaxLineCount(int line)
{
    m_nMaxLineCount = line;
    m_nMaxLines = line;
    m_nTrimLines = min(m_nMaxLines, 100);
}
void CLogEdit::OnContextMenu(CWnd* pWnd, CPoint point)
@@ -49,39 +53,47 @@
    }
}
void CLogEdit::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // 每次滚动时检查是否还在底部
    m_bAutoScroll = IsScrollBarAtBottom();
    CEdit::OnVScroll(nSBCode, nPos, pScrollBar);
}
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);            // 第0行首字符位置
        int endChar = LineIndex(m_nTrimLines);    // 第N行首字符位置
    // 超过指定行数则删除最前面的行
    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;
        SetSel(0, nLin1End);
        ReplaceSel(_T(""));
        nLineCount = GetLineCount();
        if (startChar >= 0 && endChar > startChar) {
            SetSel(startChar, endChar);
            ReplaceSel(_T("")); // 删除前面行
        }
    }
    // 追加到最后
    int length = GetWindowTextLength();
    SetSel(length, length);
    int len = GetWindowTextLength();
    SetSel(len, len);
    ReplaceSel(pszText);
    PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
    // 恢复
    if (nStart == 0 && nEnd == 0) {
        nStart = GetWindowTextLength();
        nEnd = nStart;
    if (m_bAutoScroll) {
        LineScroll(GetLineCount());
    }
    SetSel(nStart, nEnd);
    SetRedraw(TRUE);
    Invalidate();
    UpdateWindow();
}
SourceCode/Bond/Servo/LogEdit.h
@@ -10,12 +10,15 @@
public:
    void SetMaxLineCount(int line);
    void AppendText(const char* pszText);
    BOOL IsScrollBarAtBottom();
private:
    int m_nMaxLineCount;
    int m_nMaxLines;
    int m_nTrimLines;
    BOOL m_bAutoScroll;        // 是否自动滚动
    DECLARE_MESSAGE_MAP()
    afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
};