Recently, I had a bit of trouble with TreeView_GetItemState [archive] and TVM_GETITEMSTATE [archive].

The TreeView_GetItemState macro is a simple convenience wrapper around the TVM_GETITEMSTATE message. Hence, they should do the same thing: retrieve certain state values for a tree-view item.

However, the documentation for TreeView_GetItemState (and all other tree-view macros I checked) curiously states:

Return Value


Clearly, that cannot be correct, as the state is not returned via the macro arguments either. One would expect the return value of the macro to be the same as the return value of the message, so let’s have a look at the documentation for TVM_GETITEMSTATE instead.

That one states:

Return value

Returns a UINT value with the appropriate state bits set to TRUE. Only those bits that are specified by lParam and that are TRUE will be set. This value is equivalent to the state member of TVITEMEX.

I took that to mean that bits not specified in lParam will not be set (I’m not sure how else it could be interpreted). However, in reality, it does set bits that aren’t specified by lParam (in some cases, at least).

If you manage to find an old copy of the docs for the TreeView_GetItemState macro on MSDN, you’ll find they say:

Returns a UINT value that is equivalent to the state member of  TVITEMEX. The state bits that are both true and were specified in stateMask will be set.

The equivocality of that statement at least means that it’s not false (as it makes no guarantee about the bits not requested in the macro arguments).

If you don’t want unrequested bits to be set, discard the bits of the return value that you aren’t interested in. That’s as simple as:

const auto state = TreeView_GetItemState(wnd, item, mask) & mask

(I did attempt to report the problems with the documentation for both the macro and the message via the ‘Is this page helpful?’ link at the bottom of the respective pages but, alas, that was some time ago, and both pages currently remain unchanged...)