I was just wondering if anybody knows how to use a bitmap as a background image in a CListView.
I was just wondering if anybody knows how to use a bitmap as a background image in a CListView.
I do lots of owner draw listviews in WIN32.
Each cell is drawn independently in response to a WM_DRAWITEM msg for a single row.
I think that using an image as a background would reqire you to draw all the cells at once (Or for you to break the image up into rectangles that represent one cell.) thus negating the benifits of using a listview.
Custom draw may be different though.
LVM_GETITEMTEXT gets the text
DRAWITEMSTRUCT contains the HDC, ID and the items rect
I also use FillRect(), FrameRect() and of course TextOut()
"Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
Friedrich Nietzsche
"I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
George Best
"If you are going through hell....keep going."
Winston Churchill
novacain, thanks for the response. I am quite new to programming in C++ so I have not had much experience with owner drawn controls. I found a demonstration on how to use a bitmap as a background in a listview but I don't know how good it is. I was wondering if you, or anyone else more advanced then me, would look at the sample and just give me your opinion. Is it decent looking code, and how hard is it? Thank you again.
EDIT: I guess it would help to have the link. Here is the article on Codeguru.
EDIT2: Also, I tried playing around with SetBkImage for the CListView derived class and I couldn't get it to do anything. What is this function for and how is it used?
Last edited by mepaco; 12-02-2002 at 09:59 AM.
>>SetBkImage<<
Is a member function of CListCtrl which simply duplicates/wraps the functionality of a LVM_SETBKIMAGE.
It can set the background image to a whole bunch of different file types beyond just bitmaps - gif,png,ico,wmf,emf and jpg. Bitmaps will always be redrawn faster though.
The critical thing to remember when using it is to use an absolute path to the image file you wish to use, eg:where listview is your CListCtrl object. Replace C:\\back.bmp with the full path to your image which need not be a bitmap as noted above.Code:LVBKIMAGE lvbi; ZeroMemory(&lvbi,sizeof(lvbi)); lvbi.ulFlags=LVBKIF_SOURCE_URL|LVBKIF_STYLE_TILE; /*note the path MUST be absolute!!*/ lvbi.pszImage= TEXT ("C:\\back.bmp"); if (listview.SetBkImage(&lvbi)) { /*to colour text labels, CLR_NONE for transparent*/ listview.SetTextBkColor(CLR_NONE); /*colour text labels*/ listview.SetTextColor(RGB(255,255,255)); }
Note for Win32: Need to #define _WIN32_DCOM prior to #include <objbase.h>. You also need to use CoInitializeEx (best before parent window creation) to activate COM (for image processing) and CoUnitialize to release it (best just as app quits). To change text back colour send a LVM_SETTEXTBKCOLOR msg, to change text colour, send a LVM_SETTEXTCOLOR.
Note to MinGW users: commctrl.h is incomplete for use of this facility but will hopefully be patched soon .
edit: formatting.
Last edited by Ken Fitlike; 11-27-2002 at 07:14 PM.
CProgramming FAQ
Caution: this person may be a carrier of the misinformation virus.
Thanks Ken Fitlike, I'm gonna give SetBkImage a try. I have just one more question, though. If SetBkImage will set an image as a background and can deal with multiple file types, why did the person who wrote the article go through so much trouble to implement it himself?
I cannot get SetBkImage to work for some reason. It doesn't have any errors, it compiles fine, but no background image shows up. I don't know if it matters but I am creating an application based off of VS6 MFCAppWizard generated code for a Windows Explorer type application. Any help would be appreciated.
First off, I deleted the mfc example I was playing around with originally because I don't speak mfc too well - and don't really want to anyway. Originally I had actually just created a CListCtrl object and used that rather than a 'view' object. This didn't seem to require COM initialisation but apparently the 'view' classes do. So here's an update which should work:
Using your view object you need to do the following:
1. Add the line:on program initialisation, in your case make it the first line of CSetBkImageApp constructor. This loads in the OLE/COM image stuff ready for use. ( Ideally,CoInitializeEx should be used but I couldn't get it to work with mfc. )Code:CoInitialize(0);
2. Add the lineto your application class destructor to free up the OLE/COM stuff. Use ClassViewer to add an ExitInstance function and add the line there. In your case that would be to the CSetBkImageApp object.Code:CoUninitialize();
3. Create a WM_CREATE handler (use class viewer) for your listview class object (CSetBkImageView):
Note: change the lvbi.pszImage path to the FULL ie absolute path of your image. It should work for other image types too as previously described.Code:CListCtrl& refListCtrl = GetListCtrl(); LVBKIMAGE lvbi; ZeroMemory(&lvbi,sizeof(lvbi)); lvbi.ulFlags=LVBKIF_SOURCE_URL|LVBKIF_STYLE_TILE; /*note the path MUST be absolute!!*/ lvbi.pszImage= TEXT ("C:\\back.bmp"); if (refListCtrl.SetBkImage(&lvbi)) { /*to colour text labels, CLR_NONE for transparent*/ refListCtrl.SetTextBkColor(CLR_NONE); /*colour text labels*/ refListCtrl.SetTextColor(RGB(255,255,255)); }
Hope that helps.
edit: typos, corrections
Last edited by Ken Fitlike; 12-02-2002 at 06:11 PM.
Awesome, awesome, awesome! You are a wonderful person. Works like a charm. Thank you. I can now add this into my code and be ready to go. SWEET!
Ken Fitlike
I allowed myself to bump this old thread just to say that its almost 10 years later now but this facility still doesnt work with MingW.Note to MinGW users: commctrl.h is incomplete for use of this facility but will hopefully be patched soon .
You get error "LVBKIMAGE not defined".
Using Windows 10 with Code Blocks and MingW.
Before someone locks it:
Yes, it does, They were added 5 days after he made that postits almost 10 years later now but this facility still doesnt work with MingW.
It's not MinGW's fault if you don't use the appropriate definesCode:#if _WIN32_IE >= 0x0400 #define LVBKIMAGE LVBKIMAGEW #define LPLVBKIMAGE LPLVBKIMAGEW #define LVM_SETBKIMAGE LVM_SETBKIMAGEW #define LVM_GETBKIMAGE LVM_GETBKIMAGEW #endif /* _WIN32_IE >= 0x400 */
Last edited by adeyblue; 06-15-2011 at 10:27 AM.