This seemingly simple scenario is quite hard to perfect, and it is
impossible for windows vista.
Let's take an example where we have a listview with 3 items, where the 2
first are selected and the focus is on the 2nd (see below for sample source
code). We want to press the right arrow key to focus the 3rd item without
loosing the selection on the first 2. Here's what would be the reasonable
thing to do in LVN_ITEMCHANGING
1. decline the LVIS_SELECTED change requests for items 0 & 1 (return TRUE)
2. allow #1 to lose the focus (return 0)
3. don't allow the 3rd item to get selected, only focused
Here's a simple MFC program that demonstrates these steps:
note that step #3 involves a roundabout call to SetItemState at a later
stage (so that we don't get into recursion).
if you follow the instructions and observe the debug stream messages
printed, in the end the listview will end up in an unstable state, where 2
items appear to be selected visually, yet GetSelectedCount() returns 0.
In XP I had an ugly workaround where I would keep a separate record of
selected items, and forcibly reselect them. That created an ugly flash, but
at least it "worked". In Vista, not even that works, and items appear
selected without any real internal selection.
Is there any "proper" way to do this kind of sticky selection other than
reinventing the wheel?
1) Do nothing. The user can use Ctrl+Up/Down to move the focus without changing the selection. Press Ctrl+Space to toggle the selection of the focused item.
2) Reimplement the arrow keys by handling WM_KEYDOWN for VK_UP and VK_DOWN to only remove the LVIS_FOCUSED from the current item and add it to the next and preserve the LVIS_SELECTED.
3) Store the "selection" separately as in your workaround. You can store it in the item's lParam, or some external data structure. Then use customdraw to set the font/background colors based only on your own state. You can't use GetSelectedCount any more though.
BTW, I don't know if any of these will work on Vista.
"nikosZ" <nik...@newsgroup.nospam> wrote in message news:1B8CC8FC-11A9-40BD...@microsoft.com...
> I can think of 3 ways:
Thanks but no. I've got enough workarounds myself and want to hear the
"official" way to do it.
At worst you can see this as a bug in syslistview32 since after a series or
allowable steps you mess up the internal state of the control (visually
selected not equal to selected count)
I will try to discuss this issue with other GUI experts internally to see
if we have any better solution in this scenario. I will get back to you
Microsoft Online Community Support
Get notification to my posts through email? Please refer to
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
This posting is provided "AS IS" with no warranties, and confers no rights.
Based on my disucssion to other GUI experts in Microsoft, I was told that
there is no better official way for this task. The recommended way is to
use the standard selection behavior rather than confusing users with
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
> The recommended way is to
> use the standard selection behavior rather than confusing users with
> non-standard behavior.
I would appreciate if you allowed me to decide what's best for my users!
This is an optional switch that users can turn on because they *prefer* it.
Are your colleagues arguing that it is not a bug? It is clear to me that
this is a BUG, and I have given you code that manifests it.
Pre-vista at least you could "shake" the control back to its senses, by
first unselecting all items (using SetItemState(-1, &lvi)) and then
reselecting them from the selection information kept separately
in vista the control falls into a permanent unstable mode and the above
"trick" doesn't work
And all after a sequence of valid documented steps.
At least I need a workaround to make vista listview correct its internal
We mean that the list view was not designed for this level of
customization. Our recommendation would be for you to create a custom
control where you can define the selection behavior rather than trying to
use the list view in a manner for which it was not designed.
or i could just rewrite vista OS from scratch so that it behaves a bit more
like XP plus UAC :)
looks like i'll have to disable this feature for vista...