Hi Nikolay,
Why do you need this restoring code?
I tried to replicate the way that Windows did the selections. Testing various manners of selection with Windows Explorer, that code was needed for a relatively specific scenario:
If you're starting a selection box with some items already selected and Shift is pressed, then the items should, as you say, remain selected. If you then highlight some different items, but then un-highlight them before releasing the mouse button, the original items should remain selected. However, if in that time you highlight some of the already highlighted items, and then unhighlight them, they should not remain highlighted.
Due to the fact that, with this code, I'm deselecting all the items (if neither shift nor ctrl are pressed) whenever the bounding box is altered, we obviously need to keep a record of how the items were highlighted before the selection was started.
The alternative would be, I believe, to maintain a list of all the items that have become highlighted or de-highlighted during the selection process, so that they can be restored if need. This would probably be more efficient, at least with large numbers of items, but it would be more complex to implement. If need be, of course, I can try to reimplement the code in this manner.
If you're starting selection box with some items selected they should be deselected if not Shift pressed and leaved untouched if Shift used. I don't see a reason to restore it - when you want to toggle selected state moving rectangle with Ctrl pressed you could just:
LISTVIEW_GetItemState() and place inverted state with following LISTVIEW_SetItemState().
The issue with doing it this way is it would result in massive flickering every time you moved the mouse, unless I perhaps misunderstood you. Otherwise I guess there would have to be some way of tracking that the pointer is still within the hit area of a certain item, and has not moved out from that area, and hence the state should not be inverted again.
Also such large cycles shouldn't be used if you could manage not to use them.
See above - but that was indeed a concern of mine. I tested with some reasonably large collections of items (in the hundreds), and it did not seem noticeably slow, but I admit to not trying with thousands if items.
Anyway this part: ... is wrong. You can't do it that way cause selected state could also be cached at parent side with corresponding callback bit set (look at LISTVIEW_GetItemT()).
I'll look into that, thanks.
P.S. No need to split in two patches here, fist is useless if we can't see rectangle.
I can of course combine the two patches. However, the first isn't actually useless on its own - even if the rectangle can't be seen, it is obvious where the selection box is due to the highlighting of the icons. :)
Thanks for your comments!