简体   繁体   中英

Need help understanding LVITEM state and stateMask

I'm confused. The LVITEM structure states:

state

Type: UINT

Indicates the item's state, state image, and overlay image. The stateMask member indicates the valid bits of this member.

Bits 0 through 7 of this member contain the item state flags. This can be one or more of the item state values.

So my question is, what are bits 0 through 7 for? They appear not to indicate what is used by the other bits, otherwise the stateMask wouldn't be needed.

MSDN tells you exactly what the bits in state are:

Bits 0 through 7 of this member contain the item state flags. This can be one or more of the item state values .

Bits 8 through 11 of this member specify the one-based overlay image index. ... To isolate these bits, use the LVIS_OVERLAYMASK mask.

Bits 12 through 15 of this member specify the state image index. To isolate these bits, use the LVIS_STATEIMAGEMASK mask.

It does not make sense to set the bottom bits to LVIS_*MASK , only the other LVIS_* states. stateMask specifies which bits in state are required/valid when you query or set the state.

The bit layout of state and stateMask is the same and if someone hands you a LVITEM you would calculate the valid bits as valid = lvi.state & lvi.stateMask . If the state bits you care about are not set in stateMask you would have to query the listview for those bits.

In the source code for the listview the query code might look something like this:

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_...) && ...
}

There are two bits of information you want to communicate: The final value of each flag, and the set of flags you want to adjust. Those are represented by the state and stateMask members, respectively.

The operation performed is:

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

An example: Assuming prev_flags is 101 and you wish to reset flag 0, set flag 1, and keep flag 2 unchanged, you'd pass 010 as the state and 011 as the stateMask . Note, that the stateMask denotes 0 for flag 2, to retain its current value.

state & stateMask evaluates to 010 .

~( state | stateMask ) evaluates to 101 .

flags = prev_flags & ~( state & stateMask ) evaluates to 101 &= 100 , ie 100

flags | ( state & stateMask ) flags | ( state & stateMask ) evaluates to 100 | 010 100 | 010 , ie 110 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM