Geoff Chappell - Software Analyst
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 and messages and the GetBackgroundImage and SetBackgroundImage methods.
typedef struct tagLVBKIMAGE { ULONG ulFlags; HBITMAP hbm; LPTSTR pszImage; UINT cchImageMax; int xOffsetPercent; int yOffsetPercent; } LVBKIMAGE, *PLVBKIMAGE;
For the GetBackgroundImage method and message, the structure both provides input and receives output. For SetBackgroundImage and , the structure only provides input.
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.
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.
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.
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).
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 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 messages report this bitmap handle as being in use for the background image, until an induces COMCTL32 to delete the bitmap handle.
The ANSI forms of the LVBKIF_TYPE_WATERMARK bit is clear.
and messages behave as if the