我很困惑。LVITEM结构指出:
状态
类型:UINT
指示项目的状态、状态图像和覆盖图像。stateMask成员表示该成员的有效位。
此成员的位 0 到 7 包含项目状态标志。这可以是一个或多个项目状态值。
所以我的问题是,位 0 到 7 有什么用?它们似乎没有指示其他位使用什么,否则不需要 stateMask。
我很困惑。LVITEM结构指出:
状态
类型:UINT
指示项目的状态、状态图像和覆盖图像。stateMask成员表示该成员的有效位。
此成员的位 0 到 7 包含项目状态标志。这可以是一个或多个项目状态值。
所以我的问题是,位 0 到 7 有什么用?它们似乎没有指示其他位使用什么,否则不需要 stateMask。
MSDN 会准确地告诉您其中的位是什么state:
此成员的位 0 到 7 包含项目状态标志。这可以是一个或多个项目状态值。
该成员的位 8 到 11 指定从 1 开始的覆盖图像索引。...要隔离这些位,请使用 LVIS_OVERLAYMASK 掩码。
该成员的位 12 到 15 指定状态图像索引。要隔离这些位,请使用 LVIS_STATEIMAGEMASK 掩码。
将底部位设置为 没有意义LVIS_*MASK,只有其他LVIS_*状态。stateMask指定state查询或设置状态时需要/有效的位。
state和的位布局stateMask是相同的,如果有人递给您 aLVITEM您将计算有效位为valid = lvi.state & lvi.stateMask。如果未设置您关心的状态位,则stateMask必须在列表视图中查询这些位。
在列表视图的源代码中,查询代码可能如下所示:
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_...) && ...
}
您想要传达两种信息:每个标志的最终值,以及您要调整的标志集。它们分别由state和stateMask成员代表。
执行的操作是:
auto flags = prev_flags & ~( state | stateMask ); // reset flags
flags = flags | ( state & stateMask ); // set flags
一个例子:假设prev_flags是101并且您希望重置标志 0,设置标志 1 并保持标志 2 不变,您将010作为state和011作为stateMask. 请注意,标志 2stateMask表示0保留其当前值。
state & stateMask评估为010。
~( state | stateMask )评估为101。
flags = prev_flags & ~( state & stateMask )计算为101 &= 100,即100
flags | ( state & stateMask )计算为100 | 010,即110。