首页 > 解决方案 > Win32 Listview Tilemode 可交互项目空间问题

问题描述

在 tileview 中自定义绘制列表视图项目时,在 CDDS_ITEMPREPAINT 期间返回 CDRF_SKIPDEFAULT 会将项目的可交互矩形放大到实际项目的大小(即从 ListView_GetItemRect(LVIR_BOUNDS) 接收的大小),而不仅仅是图标+标签的大小。这究竟是如何以及为什么会发生的?我在文档或网络上找不到明确的答案。我的意思是,处理自定义绘画不应该只影响项目的绘画而不影响您与之交互的方式吗?

代码示例:

::NMLVCUSTOMDRAW* pNMCustomDraw = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);

switch (pNMCustomDraw->nmcd.dwDrawStage)
{

    // Before the painting cycle begins. 
    case CDDS_PREPAINT:
    {

        return CDRF_NOTIFYITEMDRAW;

    }

    // Before an item is drawn.
    case CDDS_ITEMPREPAINT:
    {

        return CDRF_SKIPDEFAULT;
        
    }
    
}

问题的视觉表示:

在此处输入图像描述

标签: c++listviewwinapi

解决方案


该行case CDDS_ITEM | CDDS_PREPAINT正在检查 "or'ing" 的结果值CDDS_ITEM | CDDS_PREPAINT。另外,您已经在上面检查CDDS_PREPAINT过。不应该CDDS_ITEMPREPAINT吗?

应该是这样的,大概:

switch (pNMCustomDraw->nmcd.dwDrawStage)
{

    // Before the painting cycle begins. 
    case CDDS_PREPAINT:
    {
        return CDRF_NOTIFYITEMDRAW;

    }

    // Before an item is drawn.
    case CDDS_ITEM: // fall through
    case CDDS_ITEMPREPAINT:
    {

        return CDRF_SKIPDEFAULT;
        
    }
}

另外,MSDN 指出:

CDRF_SKIPDEFAULT 应用程序手动绘制项目。控件不会绘制项目。这在 dwDrawStage 等于 CDDS_ITEMPREPAINT 时发生。

https://docs.microsoft.com/en-us/windows/win32/controls/nm-customdraw-list-view

也检查这里(MSDN):

https://docs.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmcustomdraw

试试看:)。如果需要,不要忘记在案件之后添加休息时间。问候


推荐阅读