BackgroundImage property of Windows Form TreeView control and ListView control appears on the IntelliSense menu in Visual Studio .NET 2002 but has no effect at runtime (834533)



The information in this article applies to:

  • Microsoft Visual Studio .NET (2002), Enterprise Architect Edition
  • Microsoft Visual Studio .NET (2002), Enterprise Developer Edition
  • Microsoft Visual Studio .NET (2002), Professional Edition

SYMPTOMS

You can see the BackgroundImage property on the IntelliSense menu in the Microsoft Visual Studio .NET 2002 code designer. Additionally, you can assign an image to the TreeView control. You can do this by adding a code example that is similar to the following.
treeview1.BackgroundImage.FromFile ("C:\mybitmap.bmp")
After you compile the code, the code appears to compile correctly. However, the image does not appear as you expect it to appear.

CAUSE

The BackgroundImage property of the TreeView control and of the ListView control are not supported in the Microsoft .NET Framework 1.0. This is because the TreeView control and the ListView control are derived from the Control class. The Control class does not support the BackgroundImage property.

WORKAROUND

To work around this problem, you can draw the image by sending a Microsoft Windows message to the underlying control. You can do this by using Platform Invocation Services (PInvoke). Before you can use PInvoke to do this, you have to import the following namespace.
using System.Runtime.InteropServices;
You can use the following code sample to set an image to the ListView control in Microsoft Visual C# .NET.
	[DllImport("ole32.dll")]
	public extern static void CoUninitialize();

	[DllImport("ole32.dll")]
	public extern static int CoInitialize(int pReserved);

	[DllImport("user32.dll")]
	public extern static int SendMessage(IntPtr hwnd, uint msg, uint wParam, uint lParam);

	[DllImport("user32.dll")]
	public extern static int SendMessage(IntPtr hwnd, uint msg, uint wParam, LVBKIMAGE lParam);
		
	private const int NOERROR = 0x0;
	private const int S_OK = 0x0;
	private const int S_FALSE = 0x1;
	private const int LVM_FIRST = 0x1000;
	private const int LVM_SETBKIMAGE = LVM_FIRST + 68;
	private const int LVM_SETTEXTBKCOLOR = LVM_FIRST + 38;
	private const int LVBKIF_SOURCE_URL = 0x02;
	private const int LVBKIF_STYLE_TILE = 0x10;
	private const uint CLR_NONE = 0xFFFFFFFF;

	[StructLayout(LayoutKind.Sequential)]
	public class LVBKIMAGE
	{
		public int ulFlags;
		public IntPtr hbm;
		public string pszImage;
		public int cchImageMax;
		public int xOffsetPercent;
		public int yOffsetPercent;
	}

	void SetBackground()
	{
		string bkImgFile = @"C:\WINDOWS\Angler.bmp";
		LVBKIMAGE tLBI = new LVBKIMAGE();
		tLBI.pszImage = bkImgFile;
		tLBI.cchImageMax = bkImgFile.Length + 1;
		tLBI.ulFlags = LVBKIF_SOURCE_URL | LVBKIF_STYLE_TILE;
		SendMessage(listView1.Handle, LVM_SETBKIMAGE,0,tLBI);
		SendMessage(listView1.Handle,LVM_SETTEXTBKCOLOR,0,CLR_NONE); 
	}

You can use the following code sample to set an image to the ListView control in Microsoft Visual Basic .NET.
        Private Const NOERROR = &H0
        Private Const S_OK = &H0
        Private Const S_FALSE = &H1
        Private Const LVM_FIRST = &H1000
        Private Const LVM_SETBKIMAGE = (LVM_FIRST + 68)
        Private Const LVM_SETTEXTBKCOLOR = (LVM_FIRST + 38)
        Private Const LVBKIF_SOURCE_URL = &H2
        Private Const LVBKIF_STYLE_TILE = &H10
        Private Const CLR_NONE = &HFFFFFFFF

        Private Structure LVBKIMAGE
            Public ulFlags As Int32
            Public hbm As IntPtr
            Public pszImage As String
            Public cchImageMax As Int32
            Public xOffsetPercent As Int32
            Public yOffsetPercent As Int32
        End Structure

        Private Declare Sub CoUninitialize Lib "OLE32.DLL" ()

        Private Declare Function CoInitialize Lib "OLE32.DLL" ( _
            ByVal pvReserved As Int32 _
        ) As Int32

        Private Declare Function SendMessage Lib "user32" _
            Alias "SendMessageA" ( _
            ByVal hwnd As IntPtr, _
            ByVal wMsg As Int32, _
            ByVal wParam As Int32, _
            ByVal lParam As Int32 _
        ) As Int32

        Private Declare Function SendMessage Lib "user32" _
            Alias "SendMessageA" ( _
            ByVal hwnd As IntPtr, _
            ByVal wMsg As Int32, _
            ByVal wParam As Int32, _
            ByRef lParam As LVBKIMAGE _
        ) As Int32

        Private Sub SetBackground()
            Dim sI As String
            Dim lHDC As Int32
            sI = "C:\WINDOWS\Angler.bmp"
            Dim tLBI As LVBKIMAGE
            tLBI.pszImage = sI & ControlChars.NullChar
            tLBI.cchImageMax = Len(sI) + 1
            tLBI.ulFlags = LVBKIF_SOURCE_URL Or LVBKIF_STYLE_TILE
            SendMessage(Me.ListView1.Handle, LVM_SETBKIMAGE, 0, tLBI)
            Dim res As Int32 = SendMessage( _
                Me.ListView1.Handle, _
                LVM_SETTEXTBKCOLOR, _
                0, _
                CLR_NONE _
            )
        End Sub

Note We recommend that you call the CoInitialize function when the application is initialized. Then, call the CoUninitialize function when the application is closed.

STATUS

Microsoft has confirmed that this is a problem in the Microsoft products that are listed in the "Applies to" section.

MORE INFORMATION

For additional information about InterOp and using unmanaged DLL functions, visit the following Microsoft Developer Network (MSDN) Web site:

Modification Type:MajorLast Reviewed:11/16/2004
Keywords:kbtshoot kbui kbinterop kbProgramming kbprb KB834533 kbAudDeveloper