如何使 ListView 的背景图片固定?
首先,C#里的 ListView 本身并不提供背景图片的设置。所以我这里用 Win32API 来实现,代码如下:
public void SetBGImage( ListView lst, Bitmap image ) {
int LVBKIF_SOURCE_HBITMAP = 1;
int LVM_SETBKIMAGEA = 0x1000 + 68;
LVBKIMAGE apiItem = new LVBKIMAGE();
apiItem.hbm = (int) image.GetHbitmap();
apiItem.ulFlags = LVBKIF_SOURCE_HBITMAP;
Win32API.SendMessage(lst.Handle, LVM_SETBKIMAGEA, 0, ref apiItem);
}
[StructLayout(LayoutKind.Sequential)]
public struct LVBKIMAGE{
public int ulFlags;
public int hbm;
public string pszImage;
public int cchImageMax;
public int xOffsetPercent;
public int yOffsetPercent;
}
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref LVBKIMAGE lParam);
//===============================================
这样的话背景图片确实可以显示了,调整ListView的大小,图片的显示位置也正确。但有一个问题,就是当ListView数据很多,出现滚动条的时候,拖拽滚动条,背景图片也跟着动。也就是说背景图片没法固定在 ListView 的某个位置(滚动条的情况)
大家可以观察一下 WinXP 或 Win2003 系统的文件夹窗口,当开启【为特定文件夹显示背景图片】功能时,同样的 ListView,拖动系统文件夹的滚动条,背景图就是固定的。
所以我怀疑系统应该有这样的API或者选项。就好像我上面的例子里,是用 LVBKIMAGE.hbm 属性直接设置一个 Bitmap 的 Handle,再利用 LVBKIF_SOURCE_HBITMAP 属性来直接显示图片。但网上的很多例子,包括 MSDN 的文档里,都没有提到 LVBKIMAGE.hbm 和 LVBKIF_SOURCE_HBITMAP 的作用。
在查看了 CommCtrl.h 里面的定义后,我发现 API 里面还提供了一个属性: LVBKIF_TYPE_WATERMARK = 0x10000000。从名字上看像是水印。难道系统就是用这个固定图片??我试了一下 LVBKIMAGE.ulFlags = LVBKIF_SOURCE_HBITMAP | LVBKIF_TYPE_WATERMARK。结果失败。 -_-
现在想请问各位高手,到底怎样才能使 ListView 的背景图片固定下来? 还有 LVBKIF_TYPE_WATERMARK 到底什么作用?怎么用?我在网上、国内国外,还有MSDN都找遍了也没发现这个属性的说明啊。。难道真的是"隐藏"API? 只有微软自己才知道怎样调用?
【注:】如果是通过自己重绘背景图( WM_ERASEBKIMAGE..), 这种方法就算了