需要帮助理解LVITEM状态和stateMask

时间:2018-02-12 20:41:39

标签: winapi common-controls

我很困惑。 LVITEM structure州:

  

状态

     

输入: UINT

     

指示项目的状态,状态图像和叠加图像。 stateMask 成员指示此成员的有效位。

     

该成员的0到7位包含项状态标志。这可以是一个或多个项目状态值。

所以我的问题是,0到7位是什么?它们似乎不表示其他位使用的是什么,否则将不需要 stateMask

2 个答案:

答案 0 :(得分:0)

MSDN确切地告诉您state中的位是什么:

  

该成员的0到7位包含项状态标志。这可以是item state values中的一个或多个。

     

该成员的第8位至第11位指定基于一的叠加图像索引。 ...要隔离这些位,请使用LVIS_OVERLAYMASK掩码。

     

该成员的第12至15位指定状态图像索引。要隔离这些位,请使用LVIS_STATEIMAGEMASK掩码。

将底部位设置为LVIS_*MASK,仅设置其他LVIS_*状态是没有意义的。 stateMask指定查询或设置状态时state中哪些位是必需/有效的。

statestateMask的位布局相同,如果有人向您发送LVITEM,您可以将有效位计算为valid = lvi.state & lvi.stateMask。如果您关心的状态位未在stateMask中设置,则必须在列表视图中查询这些位。

在listview的源代码中,查询代码可能如下所示:

void ListView::GetItemState(LVITEM&lvi, int idx)
{
  lvi.state = 0;
  if ((lvi.stateMask & LVIS_CUT) && isItemInCutState(idx, lvi)) lvi.state |= LVIS_CUT;
  if ((lvi.stateMask & LVIS_...) && ...
}

答案 1 :(得分:0)

您要传达两个信息位:每个标志的最终值,以及您要调整的标志集。这些成员分别由statestateMask成员代表。

执行的操作是:

auto flags = prev_flags & ~( state | stateMask ); // reset flags
     flags = flags      |  ( state & stateMask ); // set flags

示例:假设prev_flags101并且您希望重置标志0,设置标志1并保持标志2不变,则将010作为{{1}传递}和state作为011。请注意,stateMask表示标志2的stateMask,以保留其当前值。

0评估为state & stateMask

010评估为~( state | stateMask )

101评估为flags = prev_flags & ~( state & stateMask ),即101 &= 100

100评估为flags | ( state & stateMask ),即100 | 010