[1/2] comctl32: Implement highlighting (marquee) selection support in listview

Owen Rudge owen at owenrudge.net
Mon Sep 14 14:57:16 CDT 2009

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 

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!

Owen Rudge

More information about the wine-devel mailing list