Click here to Skip to main content
14,218,975 members
Rate this:
Please Sign up or sign in to vote.
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)

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

Rate this:
Please Sign up or sign in to vote.

Solution 1

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[^]).
   
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, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100