c++ - 如何防止 CListCtrl 闪烁?

标签 c++ windows mfc clistctrl common-controls

我在启用了 LVS_EX_DOUBLEBUFFER 的虚拟模式 (LVS_OWNERDATA) 中使用 CListCtrl/CListView 报告 View (LVS_REPORT),我遇到了难看的问题闪烁。双缓冲有一个真正的效果,但它不会停止所有闪烁(没有它非常慢)。

我不想切换到需要大量返工的其他控件(如 ObjectListView)

闪烁的行为如何:

  • 在调整列大小时 - 首先使用浅灰色清洁背景,然后显示文本(背景为白色)
  • 鼠标滚动(动画)- 在要显示新行的区域中会显示一个浅灰色条,时间很短。

看起来它确实使用默认窗口背景颜色(浅灰色)清理了必须重绘区域的背景。

如何解决闪烁问题?

最佳答案

尝试执行以下操作: - 为List Control 的paremt 对话框设置Clip Children 和Clip Sibling。 - 从 CListCtrl 类中提取。在这个类中覆盖 OnEraseBkgnd。在 OnEraseBkgnd 中,用列表可见项周围的背景颜色区域填充。 OnEraseBkgnd 看起来像:

BOOL CListCtrlEx::OnEraseBkgnd(CDC* pDC) 
{
    CBrush  br;
    CRect   rcCli;
    CRect   rcItemsRect(0, 0, 0, 0);
    int     nHeadHeight = 0;
    int     nItems      = GetItemCount();

    GetClientRect(&rcCli);

    CHeaderCtrl* pHeadCtrl = GetHeaderCtrl();
    if (pHeadCtrl)
    {
        CRect  rcHead;
        pHeadCtrl->GetWindowRect(&rcHead);
        nHeadHeight = rcHead.Height();
    }
    rcCli.top += nHeadHeight;

    if (nItems > 0)
    {
        CPoint  ptItem;
        CRect   rcItem;

        GetItemRect(nItems - 1, &rcItem, LVIR_BOUNDS);
        GetItemPosition(nItems - 1, &ptItem);

        rcItemsRect.top    = rcCli.top;
        rcItemsRect.left   = ptItem.x;
        rcItemsRect.right  = rcItem.right;
        rcItemsRect.bottom = rcItem.bottom;

        if (GetExtendedStyle() & LVS_EX_CHECKBOXES)
            rcItemsRect.left -= GetSystemMetrics(SM_CXEDGE) + 16;
    }

    br.CreateSolidBrush(GetBkColor());

    if (rcItemsRect.IsRectEmpty())
        pDC->FillRect(rcCli, &br);
    else
    {
        if (rcItemsRect.left > rcCli.left)     // fill left rectangle
            pDC->FillRect(
                CRect(0, rcCli.top, rcItemsRect.left, rcCli.bottom), &br);
        if (rcItemsRect.bottom < rcCli.bottom) // fill bottom rectangle
            pDC->FillRect(
                CRect(0, rcItemsRect.bottom, rcCli.right, rcCli.bottom), &br);
        if (rcItemsRect.right < rcCli.right) // fill right rectangle
            pDC->FillRect(
                CRect(rcItemsRect.right, rcCli.top, rcCli.right, rcCli.bottom), &br);
    }

    return TRUE;
}

关于c++ - 如何防止 CListCtrl 闪烁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2486682/

相关文章:

c++ - 我们如何突出显示以 ICON 格式创建的 ClistCtrl 的第一项?

MysqlDump 出现 ShellExecute 错误

c++ - SDL2 : saving image as png error

c++ - 模块信息不适用于 DEBUG_PROCESS

android - 如何将 .cpp 包含文件添加到 android.mk 中的依赖项?

windows - 使用 puppeteer、windows 在 chromium 中播放 mp4

c++ - SetDIBits 可以直接绘制到屏幕或监视器吗?

c++ - C++ 中的指针——需要解释它是如何工作的

C++:奇怪的 float 学结果

c++ - Windows-10 移动版 : "The specified module could not be found. (Exception from HRESULT: 0x8007007E)":null