• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2101
  • Last Modified:

can not get CDDS_ITEMPREPAINT message with ListView control

My code will break at the return of CDDS_PREPAINT, but I never seem to get the CDDS_ITEMPREPAINT I expect.  Any ideas why this would happen?

  case NM_CUSTOMDRAW:
    {
      LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
      switch(lplvcd->nmcd.dwDrawStage)
      {
      case CDDS_PREPAINT:
        return CDRF_NOTIFYITEMDRAW;
      case CDDS_ITEMPREPAINT:
        lplvcd->clrText = RGB(0,255,0);
        lplvcd->clrTextBk = RGB(255,255,0);
        return CDRF_NEWFONT;
      case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
        return CDRF_DODEFAULT;
      }
      return CDRF_DODEFAULT;
    }
    return CDRF_DODEFAULT;
0
Kalvyn
Asked:
Kalvyn
  • 4
  • 4
1 Solution
 
DanRollinsCommented:
Are you getting any NM_CUSTOMDRAW notifs?  
Are you sure you called InitCommonControlsEx() correctly?
Show the code you use to create the control.
-- Dan
0
 
KalvynAuthor Commented:
Yes, I get the CDDS_PREPAINT as expected.  I don't get any other NM_CUSTOMDRAW messages after that, as if the CDRF_NOTIFYITEMDRAW is ignored.

  hWndListbox = CreateWindow(WC_LISTVIEW,"Orders",
    WS_CHILD|LVS_REPORT,
    0,0,0,0,
    hWnd, NULL, hInstance, NULL
    );
  if (hWndListbox == NULL)
  {
    app.MB("failed");
    return;
  }
ListView_SetExtendedListViewStyle(hWndListbox,LVS_EX_HEADERDRAGDROP|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
  if (!InitListViewColumns(hWndListbox))
  {
    DestroyWindow(hWndListbox);
    return;
  }
0
 
DanRollinsCommented:
You are not checking for other notifc.  I think you may be getting SubItem notifs and not detecting them.  If you ever send CDRF_DODEFAULT, that ends the sequence.  I'd add code like:

case NM_CUSTOMDRAW:
   {
     LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
     switch(lplvcd->nmcd.dwDrawStage)
     {
...
     default: //unexpected value in dwDrawStage
         ::MessageBox(0,"woops","bummer", IDOK );
         return CDRF_DODEFAULT;
     } // end of switch (dwDrawStage)
...

-- Dan
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
KalvynAuthor Commented:
I tested for that with this code.  I only ever receive one NM_CUSTOMDRAW message altho I asked for CDRF_NOTIFYITEMDRAW.  Stepping the code I verified that CDDS_PREPAINT is executed, but no other messages are received.

  case NM_CUSTOMDRAW:
    lplvcd = (LPNMLVCUSTOMDRAW)lParam;
    app.debug(ltoa(lplvcd->nmcd.dwDrawStage,app.tmp,10));
    switch(lplvcd->nmcd.dwDrawStage)
    {
    case CDDS_PREPAINT:
      return CDRF_NOTIFYITEMDRAW;
    case CDDS_ITEMPREPAINT:
      lplvcd->clrText = RGB(0,255,0);
      lplvcd->clrTextBk = RGB(255,255,0);
      return CDRF_NEWFONT;
    case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
      lplvcd->clrText = RGB(0,255,0);
      lplvcd->clrTextBk = RGB(255,255,0);
      return CDRF_NEWFONT;
    default:
      app.debug(ltoa(lplvcd->nmcd.dwDrawStage,app.tmp,10));
    }
    return CDRF_DODEFAULT;

0
 
DanRollinsCommented:
Is the code you posted directly in your WinProc?  The reason I ask is that with MFC, or some home-brewed foundation class, the actual return value must be stored into an external variable and the actual return value is a BOOL.  For instance, with MFC, we use:

BOOL CMainFrame::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
   ....
   *lResult= CDRF_NOTIFYITEMDRAW;
   return(1);

-- Dan
0
 
KalvynAuthor Commented:
I'm not using MFC.  It isn't in WinProc directly, however the ListView is a child control of a MDI window.  I have written a test case that works as expected when the ListView is a child windows of WinProc.  It does get the CDDS_PREPAINT so I would expected it to get the CDDS_ITEMPREPAINT as well.  It gets other messages required for the ListView such as NL_DBLCLK, NM_RCLICK, LVN_ITEMCHANGED, LVN_COLUMNCLICK, LVN_DELTEITEM and LVN_GETDISPINFO.  The ListView control draws correctly, I just can't change the font color or background.  
0
 
KalvynAuthor Commented:
Your comments led me to the problem in my code.  I was trapping WM_NOTIFY and then calling a class method.  The class method returned CDRF_NOTIFYITEMDRAW to the original call without passing the value on to WM_NOTIFY. I now use

  case NM_CUSTOMDRAW:
    lplvcd = (LPNMLVCUSTOMDRAW)lParam;
  //app.debug(ltoa(lplvcd->nmcd.dwDrawStage,app.tmp,10));
    switch(lplvcd->nmcd.dwDrawStage)
    {
    case CDDS_PREPAINT:
      result = CDRF_NOTIFYITEMDRAW;
      break;
    case CDDS_ITEMPREPAINT:
      lplvcd->clrText = RGB(255,0,255);
      lplvcd->clrTextBk = RGB(92,0,82);
      result = CDRF_NEWFONT;
      break;
    case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
      lplvcd->clrText = RGB(0,255,0);
      lplvcd->clrTextBk = RGB(255,255,0);
      result = CDRF_NEWFONT;
      break;
    default:
      app.debug(ltoa(lplvcd->nmcd.dwDrawStage,app.tmp,10));
    }
    return result;

...and then return result to WM_NOTIFY.

Thank you so much for your prompt and insightfull contributions to my issue.
0
 
DanRollinsCommented:
>>Thank you so much for your prompt and insightfull contributions to my issue.

The best way to thank a person is to award them with an A (it cost you nothing).  If only I had been even MORE prompt and even MORE insightful, and if only I had been able to read your code and your mind, then I could have eeked out an A.  I'll just have to learn to try harder :)

-- Dan
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now