Click here to Skip to main content
15,886,095 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to change the words' color in a ListCtrl ,I Write the code in all Windows SDK ways, I meet the problem,when I response the WM_NOTIFY message(I am sure the NM_CUSTOMDRAW message is sent from my ListCtrl),I find that through I have return
CDRF_NOTIFYITEMDRAW
,I can't receive the next
NM_CUSTOMDRAW notification
with dwDrawStage setting to
CDDS_ITEMPREPAINT
,I receive the
NM_CUSTOMDRAW notification
only once,I don't konw why? who can help me..The following code have problem :(My list Control is already been report mode)

C#
int nResult = CDRF_DODEFAULT; 
// First thing - check the draw stage. If it's the control's prepaint stage, then tell Windows we want messages for every item.
                        int nResult=CDRF_DODEFAULT;
                        if(lpNmlvCustomDraw->nmcd.dwDrawStage==CDDS_PREPAINT)//the value of lpNmlvCustomDraw->nmcd.dwDrawStage will always be CDDS_PREPAINT, I don't know why, who can help me?
                        {
                            nResult = CDRF_NOTIFYITEMDRAW;
                        }
                        else if(lpNmlvCustomDraw->nmcd.dwDrawStage==CDDS_ITEMPREPAINT)
                        {
//This is the notification message for an item.  We'll request notifications before each subitem's prepaint stage.
//CDRF_NOTIFYSUBITEMDRAW:Version 4.71. The control will notify the parent when a list view subitem is being drawn
//CDDS_SUBITEM Version 4.71. Flag combined with CDDS_ITEMPREPAINT or CDDS_ITEMPOSTPAINT if a subitem is being drawn. This will only be set if CDRF_NOTIFYITEMDRAW is returned from CDDS_PREPAINT.
                            //nResult = CDRF_NOTIFYSUBITEMDRAW;
                            nResult=CDRF_NOTIFYITEMDRAW;
                        }






the follow is my all code:

#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#include "MainDlg.h"
#include"ListView.h"


ListView lvMyListView;
HWND hListViewWnd;
BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	hListViewWnd=GetDlgItem(hWnd,IDC_MyListView);
    switch(uMsg)
    {
        HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);
        HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);
		HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);
	case WM_NOTIFY:
		{
			NMHDR* lpNmhdr=(NMHDR*)lParam;
			switch(lpNmhdr-&gt;code)
			{
			case NM_CUSTOMDRAW:
				{
					if(lpNmhdr-&gt;idFrom==IDC_MyListView)//如果是ListCtr控件发送的。
					{

						 LPNMLVCUSTOMDRAW lpNmlvCustomDraw = reinterpret_cast<lpnmlvcustomdraw>(lParam);

						 // Take the default processing unless we set this to something else below.
						int nResult = CDRF_DODEFAULT; // 默认由系统绘制, 除非下面进行了自定义绘制
// First thing - check the draw stage. If it's the control's prepaint stage, then tell Windows we want messages for every item.
						if(lpNmlvCustomDraw-&gt;nmcd.dwDrawStage==CDDS_PREPAINT)//那么需要指定重绘的具体操作。
						{
							nResult = CDRF_NOTIFYITEMDRAW;
						}
						else if(lpNmlvCustomDraw-&gt;nmcd.dwDrawStage==CDDS_ITEMPREPAINT)//重绘需要的具体操作。
						{
							nResult=CDRF_NOTIFYSUBITEMDRAW;
						}
						else if(lpNmlvCustomDraw-&gt;nmcd.dwDrawStage==(CDDS_ITEMPREPAINT | CDDS_SUBITEM))//当是要对子项进行重绘的时候。
						{ 
                                                        int nItem=lpNmlvCustomDraw-&gt;nmcd.dwItemSpec;
							int nSubItem=lpNmlvCustomDraw-&gt;iSubItem;//取得需要重绘的列号。//Version 4.71. Index of the subitem that is being drawn. If the main item is being drawn, this member will be zero.

							COLORREF crText;

							if ( (nItem % 3) == 0 )
							{
								crText = RGB(255,0,0);
								// 获得列绘制区域
								HDC hdc=lpNmlvCustomDraw-&gt;nmcd.hdc;
                                RECT subItemRect;
                                ListView_GetSubItemRect(hListViewWnd, nItem, nSubItem, LVIR_BOUNDS, &subItemRect);
								FillRect(hdc,&subItemRect,CreateSolidBrush(RGB(100,100,100)));
							}
							else if ( (nItem % 3) == 1 )
								crText = RGB(0,255,0);
							else
								crText = RGB(128,128,255);

							// Store the color back in the NMLVCUSTOMDRAW struct.
							lpNmlvCustomDraw-&gt;clrText = crText;

						
							nResult =  CDRF_NEWFONT;
						}
						return nResult;
					}
				}
				break;
			default:
				break;
			}
		}
		break;
    }

    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
	lvMyListView.SetMainWinhwnd(hwnd);
	lvMyListView.SethList(IDC_MyListView);
	lvMyListView.ListView_Init();
	lvMyListView.InsertColumnItem(TEXT("文件下载进度"),500,500);
	lvMyListView.InsertColumnItem(TEXT("歌曲名"),180,180);
	lvMyListView.InsertColumnItem(TEXT("歌手"),151,151);
	for(int index=0;index&lt;3;index++)
	{
		lvMyListView.InsertRowItem(TEXT("周杰伦"));
		lvMyListView.InsertRowItem(TEXT("双截棍"));
		lvMyListView.InsertRowItem(TEXT("50%"));
	}
    return TRUE;
}

void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
    switch(id)
    {
        case IDC_OK:
		{
			MessageBox(hwnd,TEXT("欢迎访问如鹏网 www.RuPeng.com 大学生计算机学习社区"),TEXT("问好"),MB_OK);
		}
        break;
        default:
		break;
    }
}

void Main_OnClose(HWND hwnd)
{
    EndDialog(hwnd, 0);
}
Posted
Updated 25-Oct-13 0:44am
v4

1 solution

When changing colors, you must return CDRF_NEWFONT to notify the control that they has been changed (see last sentence at MSDN article Using Custom Draw[^]).
 
Share this answer
 
Comments
Member 10356713 24-Oct-13 20:13pm    
Thank you.My List Control have already been report mode,the MSDN say that " If the control is in report mode and you want to handle the subitems individually, return CDRF_NOTIFYSUBITEMDRAW. ". I have return CDRF_NOTIFYITEMDRAW in the previous step, now I find that I can't receive the next NM_CUSTOMDRAW notification,so I can't change the color,I don't konw why? Does it involve with the extern style of the List Control? I have seted the List Control ExStyle
dwExStyle|=LVS_EX_FULLROWSELECT;
dwExStyle|=LVS_EX_GRIDLINES;
dwExStyle &=~LVS_EX_CHECKBOXES;
Jochen Arndt 25-Oct-13 2:51am    
Please see the example from the link in my answer. In report mode you must:
return CDRF_NOTIFYITEMDRAW upon CDDS_PREPAINT,
return CDRF_NOTIFYSUBITEMDRAW upon CDDS_ITEMPREPAINT
change the colors and return CDRF_NEWFONT upon CDDS_SUBITEM | CDDS_ITEMPREPAINT.

But your code returns CDRF_DODEFAULT when the colors has been changed resulting in the new colors to be ignored.
Member 10356713 25-Oct-13 6:43am    
Thank you very much. I have read the example carefully,I have changeed the CDRF_DODEFAULT to CDRF_NEWFONT,but the problem doesn't be solved, ...I also can't receive the CDDS_ITEMPREPAINT through I return CDRF_NOTIFYITEMDRAW upon CDDS_PREPAINT, maybe there will be other errors in my code....
Jochen Arndt 25-Oct-13 7:06am    
The code portions are hard to read but I can't see any problems. I suggest to use the debugger or insert some TRACE calls to see which messages are send and handled.
Member 10356713 25-Oct-13 8:06am    
Thank you all the same...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900