CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Apr 2008
    Posts
    26

    Custom draw listview

    I'm using visual c++ 8. I am trying to implement custom drawn listview in pure win32(NO MFC) based on articles on the web, however it doesn't seem to work.What am i doing wrong? PLEASE help. (This code is based on an article i found on the web,which used the same code, to colour a lisview on a dialog.I am not using dialogs here) Here is the code ...

    Code:
    #include <windows.h>
    #include <commctrl.h>
    #include<shellapi.h>
    #pragma comment (lib,"comctl32.lib")
    
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    LRESULT ProcessCustomDraw (LPARAM lParam);
    
    
    HWND frmhwnd,lvhwnd;               
    HIMAGELIST hSmallImageList;
    
    int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance,LPSTR lpszArgument,int nFunsterStil)
    
    {
       
           /* Create form using CreateWindowEx function*/            
        
    	INITCOMMONCONTROLSEX iccx;
    	iccx.dwSize=sizeof(INITCOMMONCONTROLSEX);
    	iccx.dwICC=ICC_LISTVIEW_CLASSES;
    	InitCommonControlsEx(&iccx);     
    	lvhwnd=CreateWindowEx(0,                              
                          WC_LISTVIEW, 0, WS_CHILD | WS_VISIBLE | LVS_REPORT, 30,                                     
                          30,  700, 400,  frmhwnd,0, hThisInstance, 0);                                    
    
    	hSmallImageList=ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLOR32|ILC_MASK,1,1);
    	ListView_SetImageList(lvhwnd,hSmallImageList,LVSIL_SMALL);
    
    	ListView_SetImageList(lvhwnd,0,LVSIL_SMALL);
    	HICON hicon=ExtractIcon(0,L"C:\\icon1.ico",0);
    	ImageList_ReplaceIcon(hSmallImageList,-1,hicon);
    	hicon=ExtractIcon(0,L"C:\\icon2.ico",0);
    	ImageList_ReplaceIcon(hSmallImageList,-1,hicon);
    	hicon=ExtractIcon(0,L"C:\\icon3.ico",0);
    	ImageList_ReplaceIcon(hSmallImageList,-1,hicon);
    	ListView_SetImageList(lvhwnd,hSmallImageList,LVSIL_SMALL);
    		
            /*Just adding Random Data.You can avoid reading this part, if you find the code is too long*/
    
    	LV_COLUMN lv;
    	lv.fmt=0;
    	lv.cx = 250;
    	lv.mask=LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
    	lv.pszText=L"Column1";
    	lv.cchTextMax=wcslen(lv.pszText);
    	lv.iSubItem=0;
    	ListView_InsertColumn(lvhwnd,0,&lv);
    	lv.pszText=L"Column2";
    	lv.iSubItem=1;
    	ListView_InsertColumn(lvhwnd,1,&lv);
    	lv.pszText=L"Column3";
    	lv.iSubItem=2;
    	ListView_InsertColumn(lvhwnd,2,&lv);
    
    	LVITEM lvi={0};
    	lvi.mask=LVIF_TEXT | LVIF_IMAGE | LVIF_STATE ;  
    	lvi.state= 0;
    	lvi.stateMask= 0;
    	lvi.iSubItem=0;
    	lvi.iImage=0;                    //image list index
    	lvi.pszText=L"TEST";
    	//lvi.pszText=LPSTR_TEXTCALLBACK;
    	lvi.cchTextMax =wcslen(lvi.pszText);
    	lvi.iItem=0;
    	ListView_InsertItem(lvhwnd,&lvi);
    	lvi.mask=LVIF_TEXT | LVIF_IMAGE | LVIF_STATE ;  
    	lvi.state= 0;
    	lvi.stateMask= 0;
    	lvi.iImage=0;       
    	lvi.iSubItem=1;
    	lvi.pszText=L"TEST2";
    	lvi.cchTextMax =wcslen(lvi.pszText);
    	ListView_SetItem(lvhwnd,&lvi);
    
    	lvi.iSubItem=0;
    	lvi.iImage=1;                    //image list index
    	lvi.pszText=L"TE";
    	lvi.cchTextMax =wcslen(lvi.pszText);
    	lvi.iItem=1;
    	ListView_InsertItem(lvhwnd,&lvi);
    
    	lvi.iImage=2;                    //image list index
    	lvi.pszText=L"dfffff";
    	lvi.cchTextMax =wcslen(lvi.pszText);
    	lvi.iItem=2;
    	
    	ListView_InsertItem(lvhwnd,&lvi);
    
    
        while (GetMessage (&messages, NULL, 0, 0))
        {
            TranslateMessage(&messages);
            DispatchMessage(&messages);
        }
       
        return messages.wParam;
    }
    
    
    
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  
        {
            case WM_DESTROY:
                PostQuitMessage (0);       
                break;
    
    	case WM_NOTIFY:
    		LPNMLISTVIEW pnm;
    		pnm= (LPNMLISTVIEW)lParam;
    		if(pnm->hdr.hwndFrom == lvhwnd &&pnm->hdr.code == NM_CUSTOMDRAW )
                    {
                       SetWindowLong(hwnd, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam));
                       return TRUE;
                    }
    
    		break;
            default:                      
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    
    LRESULT ProcessCustomDraw (LPARAM lParam)
    {
        LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
    
        switch(lplvcd->nmcd.dwDrawStage) 
        {
            case CDDS_PREPAINT : //Before the paint cycle begins
                //request notifications for individual listview items
                return CDRF_NOTIFYITEMDRAW;
                
            case CDDS_ITEMPREPAINT: //Before an item is drawn
                {
                    return CDRF_NOTIFYSUBITEMDRAW;
                }
                break;
        
            case CDDS_SUBITEM | CDDS_ITEMPREPAINT: //Before a subitem is drawn
                {
    				
                    switch(lplvcd->iSubItem)
                    {
                        case 0:
                        {
                          lplvcd->clrText   = RGB(255,255,255);
    					  if(lplvcd->nmcd.dwItemSpec==0)
    							lplvcd->clrText   = RGB(0,0,0);
    
    					  lplvcd->clrTextBk = RGB(240,55,23);
                          return CDRF_NEWFONT;
                        }
                        break;
                        
                        case 1:
                        {
                          lplvcd->clrText   = RGB(255,255,0);
                          lplvcd->clrTextBk = RGB(0,0,0);
                          return CDRF_NEWFONT;
                        }
                        break;  
    
                        case 2:
                        {
                          lplvcd->clrText   = RGB(20,26,158);
                          lplvcd->clrTextBk = RGB(200,200,10);
                          return CDRF_NEWFONT;
                        }
                        break;
    
                        case 3:
                        {
                          lplvcd->clrText   = RGB(12,15,46);
                          lplvcd->clrTextBk = RGB(200,200,200);
                          return CDRF_NEWFONT;
                        }
                        break;
    
                        case 4:
                        {
                          lplvcd->clrText   = RGB(120,0,128);
                          lplvcd->clrTextBk = RGB(20,200,200);
                          return CDRF_NEWFONT;
                        }
                        break;
    
                        case 5:
                        {
                          lplvcd->clrText   = RGB(255,255,255);
                          lplvcd->clrTextBk = RGB(0,0,150);
                          return CDRF_NEWFONT;
                        }
                        break;
    
                    }
     
                }
        }
        return CDRF_DODEFAULT;
    }
    Last edited by blastingblast; June 10th, 2008 at 11:58 AM.

  2. #2
    Join Date
    Jun 2002
    Location
    Colorado, U.S.A.
    Posts
    980

    Re: Custom draw listview

    Please use CODE tags when posting code.

    I don't think you can use DWL_MSGRESULT unless you are using a dialog. Instead, call ProcessCustomDraw yourself when necessary.

    Kelly
    Last edited by Runt888; June 9th, 2008 at 04:31 PM.

  3. #3
    Join Date
    Apr 2008
    Posts
    26

    Re: Custom draw listview

    Thanks for the reply.

    About the calling of ProcessCustomDraw when i need to, the problem is that I am not sure when i should be calling it.

    I tried removing the setwindowlong and calling processcustomdraw but it still doesn't work. I would appreciate any help in this problem.

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Custom draw listview

    Please, define "doesn't work" and edit your OP, adding Code tags (read the Announcement: Before you post.... )around the code snippet, otherwise no one will care to read/understand it!
    Victor Nijegorodov

  5. #5
    Join Date
    Apr 2008
    Posts
    26

    Re: Custom draw listview

    Terribly sorry about the code tag. I wasn't aware i should use it. I will use it in my next thread.

    My code is not working. By this I mean the code given here, which is meant to change the forecolor and backcolor of items in a listview, is not working. The creation and adding of items of the listview are working well and the program also runs, however only the default forecolor(black) and backcolor is used.

    Using breakpoints i found that "case CDDS_PREPAINT" is the only case that hits, the other cases are never true at any point in the program.

    I'm not sure what i'm doing wrong, please help.

  6. #6
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Custom draw listview

    Quote Originally Posted by blastingblast
    Terribly sorry about the code tag. I wasn't aware i should use it. I will use it in my next thread...
    Then let's wait for the next thread...

    As I already wrote you, no one will care to read/understand your code written without any indents.
    Victor Nijegorodov

  7. #7
    Join Date
    Jun 2002
    Location
    Colorado, U.S.A.
    Posts
    980

    Re: Custom draw listview

    What VictorN is saying is that you should edit your original post, adding CODE tags around the code portion. That will make it much easier for us to read and try to figure out.

    Kelly

  8. #8
    Join Date
    Apr 2008
    Posts
    26

    Re: Custom draw listview

    Sorry I caused so much trouble. I edited the original post and put the code tags. Please help me solve the problem i.e. changing the forecolor and backcolor of a listitem. Thanks in advance

  9. #9
    Join Date
    Jun 2002
    Location
    Colorado, U.S.A.
    Posts
    980

    Re: Custom draw listview

    Here's how I to custom drawing, to make some items look disabled. Maybe it will help:

    Code:
    switch( message )
    {
    	case WM_NOTIFY:
    	{
    		if( ( (LPNMHDR)lParam )->code == NM_CUSTOMDRAW )
    		{
    			switch( ( (LPNMLVCUSTOMDRAW)lParam )->nmcd.dwDrawStage )
    			{
    			case CDDS_PREPAINT:
    				return CDRF_NOTIFYITEMDRAW;
    			case CDDS_ITEMPREPAINT:
    			{
    				if( !isElementActive( ( (LPNMLVCUSTOMDRAW)lParam )->nmcd.dwItemSpec ) )
    				{
    					( (LPNMLVCUSTOMDRAW)lParam )->clrText = RGB( 200, 200, 200 );
    				}
    				else
    				{
    					tInt32 color = getElementColor( ( (LPNMLVCUSTOMDRAW)lParam )->nmcd.dwItemSpec );
    
    					( (LPNMLVCUSTOMDRAW)lParam )->clrText = RGB( (color >> 24), ((color >> 16) & 0xFF), ((color >> 8) & 0xFF) );
    				}
    
    				return CDRF_NEWFONT;
    			}
    			default:
    				return CDRF_DODEFAULT;
    			}
    		}
    Kelly

  10. #10
    Join Date
    Apr 2008
    Posts
    26

    Resolved Re: Custom draw listview

    Thanks everyone. I tried Kelly's initial suggestion to call the ProcessCustomDraw instead of the setwindowlong fn, but i found it didn't work. This was because I called it as

    ProcessCustomDraw(lParam);

    rather than

    return ProcessCustomDraw(lParam);

    It is working now. You guys are the best.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured