LVBKIMAGE

This is the main structure for operating on List-View backgrounds, to set either a background image or watermark, or to get information about them. It is used for the LVM_GETBKIMAGE and LVM_SETBKIMAGE messages and the GetBackgroundImage and SetBackgroundImage methods.

Declaration

typedef struct tagLVBKIMAGE {
    ULONG ulFlags;
    HBITMAP hbm;
    LPTSTR pszImage;
    UINT cchImageMax;
    int xOffsetPercent;
    int yOffsetPercent;
} LVBKIMAGE, *PLVBKIMAGE;

Members

For the GetBackgroundImage method and LVM_GETBKIMAGE message, the structure both provides input and receives output. For SetBackgroundImage and LVM_SETBKIMAGE, the structure only provides input.

Flags

Bits of the ulFlags member determine which other members are valid and what they mean:

LVBKIF_SOURCE_MASK 0x03 masked bits specify source of background image;
can be meaningful on input when setting and on output when getting
LVBKIF_STYLE_MASK 0x10 masked bits specify style of background image;
can be meaningful on input when setting and on output when getting
LVBKIF_FLAG_TILEOFFSET 0x0100 placement is specified for first background image in tiled style;
can be meaningful on input when setting and on output when getting
LVBKIF_TYPE_WATERMARK 0x10000000 operate on watermark (described by hbm member);
always meaningful on input when getting or setting
LVBKIF_FLAG_ALPHABLEND 0x20000000 draw watermark with alpha blend;
can be meaningful on input when setting

The LVBKIF_TYPE_WATERMARK bit is unusual in being meaningful on input when getting information. If this bit is set on input either when getting or setting, then the request is to get or set the watermark, rather than the ordinary background image. When getting, all other flags are meaningless, both on input and output. When setting, all other flags except LVBKIF_FLAG_ALPHABLEND are invalid. The watermark itself is described by a bitmap handle, passed through the hbm member.

The LVBKIF_FLAG_ALPHABLEND bit is meaningful only as input when setting information, and only then if LVBKIF_TYPE_WATERMARK is also set. Its effect is to direct that the watermark be drawn with a very particular alpha-blending. In terms of the BLENDFUNCTION structure used for the GDI function GdiAlphaBlend, the SourceConstantAlpha and AlphaFormat are constrained to 0xFF and AC_SRC_ALPHA respectively.

With LVBKIF_TYPE_WATERMARK clear on input, the request is to get or set the (ordinary) background image. The source mask is meaningful on input when setting and on output when getting. Bits in the source mask have the values:

LVBKIF_SOURCE_NONE 0x00 no background image
LVBKIF_SOURCE_HBITMAP 0x01 background image known as bitmap handle (described by hbm member)
LVBKIF_SOURCE_URL 0x02 background image known by URL (described by pszImage member, and possibly cchImageMax)

When no background image is indicated, all other flags and members are best regarded as meaningless.

Whether the background image is known as a bitmap handle or by a URL, the style mask is also meaningful on input when setting and on output when getting. Applying the style mask gives the values:

LVBKIF_STYLE_NORMAL 0x00 background image displayed once
LVBKIF_STYLE_TILE 0x10 background image repeated horizontally and vertically as needed to fill client area

The normal style always has additional configuration, specifically of the image’s placement with respect to the List-View control’s client area, which makes the xOffsetPercent and yOffsetPercent members meaningful.

The tiled style has a default placement. Placement for the tiling is indicated if LVBKIF_FLAG_TILEOFFSET is set, which makes the xOffsetPercent and yOffsetPercent members meaningful. Note that LVBKIF_FLAG_TILEOFFSET can be meaningful only if given in combination with LVBKIF_STYLE_TILE.

Bitmap Handle

The hbm member passes the bitmap handle for either the ordinary background image or watermark. It is meaningful on input when setting:

On output when getting, the hbm member describes:

In all other cases, the hbm member is meaningless.

URL

The pszImage and cchImageMax members pass the address and size (in characters) of a URL for the ordinary background image. They are irrelevant if LVBKIF_TYPE_WATERMARK is set in ulFlags on input, whether getting or setting. Their have no meaning on output, except from retaining their input values.

For input when getting, both members matter if the List-View turns out to have a background image that was set through a URL. This case is indicated when the source bits in the output ulFlags mask to LVBKIF_SOURCE_URL. If failure in this case would be acceptable, it suffices to initialise pszImage as NULL.

For input when setting, only pszImage matters and only then if the source bits in the input ulFlags mask to LVBKIF_SOURCE_URL.

Offsets

The xOffsetPercent and yOffsetPercent members describe the placement of the background image. They are irrelevant if LVBKIF_TYPE_WATERMARK is set in ulFlags on input, whether getting or setting. Otherwise, they can be meaningful on input when setting and on output when getting. Interpretation varies with the style bits in ulFlags on input or output, respectively.

For the normal style, indicated when the style bits are LVBKIF_STYLE_NORMAL, placement is relative to the unscrolled client area, meaning here the client area as would be seen were the content scrolled fully to the left and top. The xOffsetPercent and yOffsetPercent values are expressed as a percentage of the space that would be available to the left and top, respectively, of the image were the image placed at the bottom right. Calculating the percentages then gives the offsets to the right and bottom from the top left. Thus,

x = (client.right - image.cx) * xOffsetPercent / 100 + scroll.x;
y = (client.bottom - image.cy) * yOffsetPercent / 100 + scroll.y;

where x and y are client coordinates for the top left of the background image, client is a RECT for the client area (in client coordinates), image is a SIZE for the background image, and scroll is a POINT for the top left of the content (again in client coordinates). Of particular interest is that 0, 50 and 100 align the top left of the image with the top left of the unscrolled client area, the centre with the centre and the bottom right with the bottom right. The arithmetic is signed, and handles images larger than the client area and percentages outside the range 0 to 100.

For a background image in the tiled style, indicated when the style bits are LVBKIF_STYLE_TILE, the xOffsetPercent and yOffsetPercent are meaningful only in combination with LVBKIF_FLAG_TILEOFFSET. Their values are offsets from the top left of the image to the point that is to be drawn at the top left of the client area (or of the unscrolled client area if ListviewScrollOver is disabled in the List-View registry settings).

Applicable Versions

The LVBKIMAGE structure has both ANSI and Unicode forms. Both are meaningful to the NT builds of COMCTL32 in versions 4.71 and higher, but the Unicode form is not supported by the Windows builds until version 5.80.

Though the structure has not changed since version 4.71, some ulFlags bits have version dependencies. The following table lists the earliest COMCTL32 version that recognises the corresponding bit.

LVBKIF_FLAG_TILEOFFSET 6.00
LVBKIF_TYPE_WATERMARK 6.00
LVBKIF_FLAG_ALPHABLEND 6.10

The LVBKIF_SOURCE_HBITMAP flag is known to versions 4.71 and higher, but the coding before version 6.00 is dysfunctional. The early versions always return zero, as if for failure, when sent an LVM_SETBKIMAGE with this flag. This is only appropriate, since these versions of COMCTL32 have no code for drawing a background image from the given bitmap handle. However, it would not be quite correct to say that these versions leave the feature unimplemented. Despite the failure, COMCTL32 does take ownership of the bitmap handle. Subsequent LVM_GETBKIMAGE messages report this bitmap handle as being in use for the background image, until an LVM_SETBKIMAGE induces COMCTL32 to delete the bitmap handle.

The ANSI forms of the LVM_GETBKIMAGE and LVM_SETBKIMAGE messages behave as if the LVBKIF_TYPE_WATERMARK bit is clear.