I implemented some debug functions (the syslog calls below just map to
OutputDebugString, which I monitor with DebugView). What seems to happen
is that I get CDDS_PREPAINT messages, but I never get CDDS_ITEMPREPAINT
or (CDDS_SUBITEM | CDDS_ITEMPREPAINT) messages, so the color-selection
code never gets executed. I saw a message somewhere which claimed that
this symptom will occur if the OWNERDRAW flag is set in the ListView, but
as you can see below, I don't set that flag.
The only difference that I can *see* is that my listview is inserted in a
regular window, while his is on a dialog. Is that the problem, or
something else that I don't understand??
//*********************************************************************
HWND CreateListView(int x, int y, int width, int height,
int identifier, HWND hwnd, HINSTANCE g_hInst)
{
return CreateWindowEx(WS_EX_CLIENTEDGE,
"SysListView32", NULL,
WS_CHILD | WS_VISIBLE |
LVS_REPORT | LVS_EDITLABELS | WS_BORDER | WS_TABSTOP,
x, y, width, height,
hwnd, (HMENU) identifier, g_hInst, NULL);
}
// creating the ListView, in WM_CREATE:
// dx,dy don't matter, because it will get resized in WM_SIZE
hwndLVtop = CreateListView(0, LV_Y, 100, 100, IDC_LISTVIEW1, hwnd,
g_hinst) ;
if (hwndLVtop == NULL)
syslog("CreateWindow (ListView) : %s\n", get_system_message()) ;
// in WM_SIZE, additional options are set:
SendMessage (hwndLVtop, LVM_SETEXTENDEDLISTVIEWSTYLE,
LVS_EX_SUBITEMIMAGES, LVS_EX_SUBITEMIMAGES);
SendMessage (hwndLVtop, LVM_SETEXTENDEDLISTVIEWSTYLE,
LVS_EX_GRIDLINES, LVS_EX_GRIDLINES);
// a timer is used to add fields to the ListView
// in WM_NOTIFY:
switch (LOWORD (wParam)) {
case IDC_LISTVIEW1:
LPNMLISTVIEW pnm = (LPNMLISTVIEW) lParam;
if (pnm->hdr.hwndFrom == hwndLVtop &&
pnm->hdr.code == (unsigned) NM_CUSTOMDRAW) {
SetWindowLong (hwnd, DWL_MSGRESULT,
(LONG) ProcessCustomDraw (lParam));
}
break;
}
// finally, ProcessCustomDraw() :
//****************************************************************
LRESULT ProcessCustomDraw (LPARAM lParam)
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW) lParam;
switch (lplvcd->nmcd.dwDrawStage) {
case CDDS_PREPAINT: //Before the paint cycle begins
syslog("CDDS_PREPAINT\n") ; // I see this, repeatedly
//request notifications for individual listview items
return CDRF_NOTIFYITEMDRAW;
// I tried some other return values,
// but none made any difference:
// return (CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYITEMDRAW);
// return CDRF_NOTIFYSUBITEMDRAW;
case CDDS_ITEMPREPAINT: //Before an item is drawn
syslog("CDDS_ITEMPREPAINT\n") ; // but I never see this
return CDRF_NOTIFYSUBITEMDRAW;
case CDDS_SUBITEM | CDDS_ITEMPREPAINT: //Before a subitem is drawn
{ // nor do I see either of these
if (lplvcd->nmcd.dwDrawStage == CDDS_SUBITEM)
syslog("CDDS_SUBITEM\n") ;
else
syslog("CDDS_ITEMPREPAINT\n") ;
}
return CDRF_NEWFONT;
default: // and I never see this
syslog("Unknown CDDS code %u\n", lplvcd->nmcd.dwDrawStage) ;
break;
}
return CDRF_DODEFAULT;
}
(WM_CREATE is sent before CreateWindow() returns.)
--
Norm
To reply, change domain to an adult feline.
This has no sense if not in a dialog box.
> // in WM_NOTIFY:
> switch (LOWORD (wParam)) {
> case IDC_LISTVIEW1:
> LPNMLISTVIEW pnm = (LPNMLISTVIEW) lParam;
>
> if (pnm->hdr.hwndFrom == hwndLVtop &&
> pnm->hdr.code == (unsigned) NM_CUSTOMDRAW) {
> SetWindowLong (hwnd, DWL_MSGRESULT,
> (LONG) ProcessCustomDraw (lParam));
> }
> break;
Yes, this code is fir dialog boxes
BTW, never copy code from codeproject (not professional, many bugs)
Always use MSDN code (several ones for Listviews)
Custom draw is well explained
http://msdn.microsoft.com/en-us/library/bb761817(VS.85).aspx
Ahhh... yes, I wasn't thinking carefully...
DWL_MSGRESULT is specifically for dialogs.
Unfortunately, if I change my top-level application from Window to
Dialog, I get other problems, but I'll broach that in a separate topic
(after I do a little more research).
Thanks for the responses!!