univers1314 2026-01-02 20:22 采纳率: 36.4%
浏览 3

FMC EDIT控件怎样才能清空缓存,可以回滚的显示?

我在网上翻了一下资料,EDIT控件的缓存有32KB。我写了一个显示当前时间的小代码,并显示在EDIT控件里显示。刷了几秒就显示不了啦,要怎样处理才行? 也就是说FMC EDIT控件怎样才能清空缓存,可以回滚的显示?

img


```c++
LRESULT WINAPI Thread3()
{
    //定义一个struct tm的 结构体t
    struct tm t;
    //获取当前时间:要使用 time(NULL) 这个函数获取当前时间,time()函数的返回值类型是 time_t 类型(这个类型用来表示时间),
    //然后将获取到的时间的格式转换为 struct tm 的格式,转换格式可以使用 localtime(&time_t) 函数, 这个函数传入一个 time_t的指针.
    //在vs中使用这个函数不安全,推荐使用更安全的函数 localtime_s()函数,localtime_s(Now_time,&tem)接受两个参数.
    CString rn = _T("\r\n");
    stop_flag = 1;
    while (stop_flag)
    {
        //获取当前时间并赋值给时间变量tem
        time_t tem = time(NULL);        //time_t tem; time(&tem);两者等价
                                        //将tem转换为struct tm 格式,并赋给 t 指针
        localtime_s(&t, &tem);

        char timeChar[26];        //生成一个表 现用的只有19个

        strftime(timeChar, sizeof(timeChar), "%Y-%m-%d %H:%M:%S", &t); //在C程序中按照你想要的格式输出时间 放到timeChar表里
    //    cout << "你的系统当前时间是: " << timeChar << endl;
        pExDlg->m_edit1.SetSel(-1);                //编辑框定位到末尾
        pExDlg->m_edit1.ReplaceSel(timeChar);    //输出字符串

        pExDlg->m_edit1.SetSel(-1);            //编辑框定位到末尾
        pExDlg->m_edit1.ReplaceSel(rn);        //输出字符串    写一个回车换行

    //    Sleep(1000);                    //延时500毫秒
    }
    return TRUE;
}

```

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-01-02 20:23
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    你提到的 FMC EDIT控件,在 MFC(Microsoft Foundation Classes)中通常指的是 CEdit 控件。你遇到的问题是:编辑框无法持续显示时间信息,可能由于缓存或刷新问题导致内容丢失或不更新


    一、问题分析

    1. 缓存问题

      • 你提到“EDIT控件的缓存有32KB”,这可能是你误解了某些资料。
      • 实际上,CEdit 控件本身没有固定大小的缓存限制,它的内容会根据内存和程序逻辑动态变化。
      • 如果你在多线程中操作 CEdit 控件,可能会因为线程安全UI刷新机制导致内容不更新。
    2. 回滚显示问题

      • 你使用 SetSel(-1)ReplaceSel() 来将内容添加到编辑框末尾,但可能因为:
        • 未正确设置光标位置
        • 未正确刷新 UI
        • 线程与主线程通信异常(如未使用 PostMessageSendMessage 操作 UI)。
    3. 性能问题

      • 如果你频繁调用 ReplaceSel(),可能导致编辑框内容堆积,最终导致系统资源不足或界面卡顿。

    二、解决方案

    1. 使用 PostMessage 安全更新 UI

    MFC 中的 UI 控件(如 CEdit)只能在主线程中安全地操作。如果你在子线程中直接操作 CEdit,可能会导致不可预料的错误。

    建议:使用 PostMessage 将消息发送到主窗口线程进行处理。

    修改后的代码如下:
    // 假设 pExDlg 是你的对话框指针
    // 在 Thread3 函数中修改为:
    
    LRESULT WINAPI Thread3()
    {
        struct tm t;
        CString rn = _T("\r\n");
        stop_flag = 1;
    
        while (stop_flag)
        {
            time_t tem = time(NULL);
            localtime_s(&t, &tem);
    
            char timeChar[26];
            strftime(timeChar, sizeof(timeChar), "%Y-%m-%d %H:%M:%S", &t);
    
            // 构造要发送的消息数据
            CString strTime(timeChar);
            strTime += rn;
    
            // 发送消息到主窗口线程
            ::PostMessage(pExDlg->m_hWnd, WM_USER_UPDATE_EDIT, 0, (LPARAM)(LPCTSTR)strTime);
    
            Sleep(1000); // 每秒更新一次
        }
    
        return TRUE;
    }
    

    2. 在对话框中处理消息

    在你的对话框类中,添加一个自定义的消息处理函数:

    // 在对话框头文件中声明
    afx_msg LRESULT OnUpdateEdit(WPARAM wParam, LPARAM lParam);
    
    // 在对话框的 .cpp 文件中添加映射
    BEGIN_MESSAGE_MAP(CYourDialog, CDialogEx)
        ON_WM_INITDIALOG()
        ON_MESSAGE(WM_USER_UPDATE_EDIT, OnUpdateEdit)
    END_MESSAGE_MAP()
    
    // 处理消息的函数
    LRESULT CYourDialog::OnUpdateEdit(WPARAM wParam, LPARAM lParam)
    {
        CString strText = (LPCTSTR)lParam;
    
        // 定位到编辑框末尾
        m_edit1.SetSel(-1);
        // 替换选中的内容(即插入到末尾)
        m_edit1.ReplaceSel(strText);
    
        return 0;
    }
    

    注意: WM_USER_UPDATE_EDIT 是你自定义的消息 ID,需要在头文件中定义,例如:

    #define WM_USER_UPDATE_EDIT (WM_USER + 1)
    

    三、清空缓存并实现回滚显示

    如果你想清空编辑框内容实现回滚效果(比如只保留最后 N 行),可以这样处理:

    1. 清空编辑框内容

    m_edit1.SetWindowText(_T("")); // 清空整个编辑框
    

    2. 实现回滚显示(只保留最后 N 行)

    你可以通过获取当前内容长度,判断是否超过限制,然后截断内容。

    CString strContent;
    m_edit1.GetWindowText(strContent);
    
    int nLength = strContent.GetLength();
    int maxLines = 50; // 最大行数
    
    if (nLength > maxLines * 100) // 假设每行约 100 字符
    {
        // 截取最后 maxLines 行
        int i = 0;
        int lineCount = 0;
        for (i = strContent.GetLength() - 1; i >= 0 && lineCount < maxLines; i--)
        {
            if (strContent[i] == '\n')
                lineCount++;
        }
    
        strContent = strContent.Mid(i + 1);
        m_edit1.SetWindowText(strContent);
    }
    

    四、总结

    | 问题 | 解决方案 | |------|----------| | 线程操作 UI 不安全 | 使用 PostMessage 将 UI 操作委托给主线程 | | 编辑框内容无法持续更新 | 确保每次写入后调用 SetSel(-1)ReplaceSel() | | 编辑框缓存过大 | 可以通过截断内容实现回滚显示 | | 如何清空缓存 | 使用 SetWindowText("") 清空所有内容 |


    五、推荐优化建议

    • 避免频繁调用 ReplaceSel(),可考虑使用 SetWindowText()InsertLine() 方法;
    • 使用 CListBox 替代 CEdit,如果只是用于显示日志信息,CListBox 更加高效;
    • 使用 CriticalSectionMutex 保护共享数据,防止多线程冲突。

    如果你能提供完整的代码结构或更多上下文信息,我可以进一步帮助你调试和优化。

    评论

报告相同问题?

问题事件

  • 创建了问题 1月2日