Link to home
Start Free TrialLog in
Avatar of wzhxxj
wzhxxj

asked on

Changing the cell background color of a listview cell in an OCX

I am creating an MFC ocx - i've subclassed it based on the syslistview.

I am trying to change the background color of individual cells.  I'm handling the OnNotify message and using the following.  This doesn't work.
Am I handling the right msg ??
      
LPNMLVCUSTOMDRAW lplvcd = reinterpret_cast<LPNMLVCUSTOMDRAW>(lParam);
   switch(lplvcd->nmcd.dwDrawStage)
      {
            case CDDS_PREPAINT:
                  // Request prepaint notifications for each item.
                  *pResult = CDRF_NOTIFYITEMDRAW;
                  break;

            case CDDS_ITEMPREPAINT: // Requested notification
                  if(lplvcd->nmcd.dwItemSpec % 2)
                  {      
                        lplvcd->clrText = COLOUR_BLACK;
                        lplvcd->clrTextBk = COLOUR_LIGHT_GRAY;
      AfxMessageBox("OnNotify");
                  }

                  *pResult = CDRF_DODEFAULT;
                  break;
      }
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

I looked at this a couple of months back - searched google the whole thing - what I found was that general opinion was that it was not actually possible. Someone apparently had a solution for highlighting a row but not individual cells.

Avatar of wzhxxj
wzhxxj

ASKER

I'll settle for highlighting the row.  I was trying to alternate the background color of each row to make it more readable.

I've done this in a Windows app where the view is derived from CListView.  It works.  The control must be handling WM_NOTIFY messages differently.

If you have the option to buy a third-party component then I suggest buying the "PowerList" control. www.arcadiahome.com It has all those features and it is an ActiveX control.

Regards,
if you want this funcnality use the owner draw list control
Avatar of wzhxxj

ASKER

I've got this working in a mfc windows app.  The listview style was not owner drawn and I was able to hightlight the row.

The MFC ocx messaging must be different.  This will be a fairly custom mfc control so the "PowerList" is not an option.
Avatar of wzhxxj

ASKER

I figured it out - I just had to handle the NM_CUSTOMDRAW msg.  I didn't need to do the owner draw thing.

ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
I would be interested to see your solution - is it possible for you to post it?
Avatar of wzhxxj

ASKER

To the ocx Ctrl class header:
- declare as: afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);

Implementation:
Add to message map:       ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)

void CedsPrtRegionCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
      int i = 0;      // 0=item, 1=subitem - for testing only

      LPNMLVCUSTOMDRAW lplvcd = LPNMLVCUSTOMDRAW lplvcd = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
    switch(lplvcd->nmcd.dwDrawStage)
      {
            case CDDS_PREPAINT:
            {
                  // Request prepaint notifications for each item.
                  *pResult = ( i == 0 ) ? CDRF_NOTIFYITEMDRAW : CDRF_NOTIFYSUBITEMDRAW;
                  //*pResult = CDRF_NOTIFYITEMDRAW;
                  break;
            }
            case CDDS_ITEMPREPAINT: // Requested notification
            {
                  if( !i )
                  {
                        *pResult = CDRF_DODEFAULT;
                        
                        if(lplvcd->nmcd.dwItemSpec % 2)            // alternate colour of rows
                        {      
                              lplvcd->clrText = COLOUR_BLACK;
                              lplvcd->clrTextBk = COLOUR_LIGHT_GRAY;
                              *pResult = CDRF_NEWFONT;
                        }
                  }
                  else
                  {
                        *pResult = CDRF_NOTIFYSUBITEMDRAW;
                  }

                  break;
            }
            case CDDS_ITEMPREPAINT | CDDS_SUBITEM: // recd when CDRF_NOTIFYSUBITEMDRAW is returned in
            {                                      // response to CDDS_ITEMPREPAINT.
                  *pResult = CDRF_DODEFAULT;

                  int iCol = lplvcd->iSubItem;
                  int iRow = lplvcd->nmcd.dwItemSpec;

                  if((iRow & 1) && (iCol & 1))
                  {
                        lplvcd->clrTextBk = COLOUR_RED;
                        lplvcd->clrText = COLOUR_YELLOW;
                        *pResult = CDRF_NEWFONT;
                  }
                  break;
            }
            
            default:
                  *pResult = CDRF_DODEFAULT;
      }
}
ASKER CERTIFIED SOLUTION
Avatar of GranMod
GranMod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial