views:

15

answers:

2

Hi,

I’ve come across a problem with Windows list controls (I am specifically using MFC, but it looks like it applies to all list controls in the Windows common controls library).

In my specific case, I want to create a list control that has two or more columns. The first column (0) is text-only and is used to allow the user to jump to entries by typing the text in that row. Column two (or three, or four, or whatever) has an image (or an image and text; either way).

This much is all well and good and can be done easily without problem, however the final list control then ends up having a space to the left of the text in column 0 (it may be on the right on an RTL system). This spacer appears to be reserved for an image and I cannot figure out a way to prevent it. (Arranging the specific order of the columns did not change anything.)

Looking around, I found some other people complaining of the same thing, specifically this thread which leads to this thread. The proposed solution does not work because as was stated, simply shrinking the width of column zero merely cuts off the text rather than the image spacer (plus, you then have to prevent and/or process any changes to column widths that the user tries to make).

Does anyone have any ideas of how to fix this bug short of writing a list control from scratch or using one of the too-fancy grid controls on CodeProject/CodeGuru/etc.?

Thanks a lot.

A: 

Did you try to change the iIndent member of the LVITEM struct? MSDN says this:

iIndent
Version 4.70. Number of image widths to indent the item. A single indentation equals the width of an item image. Therefore, the value 1 indents the item by the width of one image, the value 2 indents by two images, and so on. Note that this field is supported only for items. Attempting to set subitem indentation will cause the calling function to fail.

humbagumba
Hmm, I have not noticed (or used) that member before. It sounds very promising though, so I’ll give it a shot today. Thanks!
Synetech inc.
Actually, I just found a line in one of my projects with that. Apparently I *had* already tried it and it didn’t work. I tried it again anyway, and while setting it to 1 caused the indent to increase, setting it to 0 or even -1 did nothing (the spacer was still there). `:(`
Synetech inc.
Hm too bad. Then I'm afraid that probably your only choice is to owner-draw all items, at least then you can exactly control the look of the individual columns...
humbagumba
And you're also sure that you haven't set the LVIF_IMAGE for the column in question?
humbagumba
Yup; it looks like when you set the `LVS_EX_SUBITEMIMAGES` style, the first column automatically gets an image (which seems absurd and very much like a bug).
Synetech inc.
A: 

Column 0 is special in a ListView. As soon as you assign a small image list to the ListView, the control expects you to show an image in column 0, so it leaves space for it.

Solutions:

  1. make column 0 zero-width, give it the value you want the user to be able to type. Column 1 becomes your "first" text column. Columns 2+ are for your images. You need full row select style for this to work. Yes, you have to prevent the user from resizing column 0. Yes, that is a pain.
  2. make a column that does have an image to be column 0 and use LVM_SETCOLUMNORDERARRAY to rearrange the display order
  3. owner draw the items.
  4. give column 0 an icon (just to cover all bases)
Grammarian
**(1)** - But then when you press keys, it won’t jump to the next item that matches. **(2)** - Same as **1**. **(3)** Sigh, that’s what I was *really* hoping to avoid. :(
Synetech inc.
With (1), you could give column 0 a value and then it would used when they type into the list. I've edited my answer to explain better.
Grammarian
(1) - But then column one would just be a duplicate of column 0. (4) - Kind of defeats the whole purpose.
Synetech inc.