title: Win32 Custom Draw Treeview Control
body: <p>I'm trying to customize a treeview control using NM_CUSTOMDRAW messages. I simply want to draw every other visible item with a grey color. Here is code to draw:</p>
  
  <pre><code>INT CResourceOutliner::On_WM_NOTIFY( HWND hDlg, WPARAM wParam, LPARAM lParam )
  {
      HWND hTree = GetDlgItem( hDlg, IDC_TREE1 ); 
      switch( ( ( LPNMHDR )lParam )-&gt;code )
      {
      ...
      case NM_CUSTOMDRAW:
              {           
                  LPNMTVCUSTOMDRAW pCustomDraw = ( LPNMTVCUSTOMDRAW )lParam;
                  switch( pCustomDraw-&gt;nmcd.dwDrawStage )
                  {               
                  case CDDS_PREPAINT:
                      return CDRF_NOTIFYITEMDRAW;
                  case CDDS_ITEMPREPAINT:
                      {
                          switch ( pCustomDraw-&gt;iLevel )                  
                          {
                              // painting all 0-level items blue,                     
                              // and all 1-level items red (GGH)25.                       
                          case 0:
                              {
                              if( pCustomDraw-&gt;nmcd.uItemState == ( CDIS_FOCUS | CDIS_SELECTED ) )                            
                                  pCustomDraw-&gt;clrTextBk = RGB( 255, 255, 255 );                          
                              else                                    
                                  pCustomDraw-&gt;clrTextBk = RGB( 128, 128, 128 );                          
                                  break;
                              }
                          case 1:                         
                              {
                                  if( pCustomDraw-&gt;nmcd.uItemState == ( CDIS_FOCUS | CDIS_SELECTED ) )                            
                                      pCustomDraw-&gt;clrTextBk = RGB( 255, 255, 255 );                          
                                  else    
                                      pCustomDraw-&gt;clrTextBk = RGB( 128, 128, 128 );
                                  break;
                              }
                          default:
                              break;
                          }
                          return CDRF_SKIPDEFAULT;
                      }
                  default:
                      break;
                  }
              }
      ...
      }
  }
  </code></pre>
  
  <p>This code is from <a href="http://www.codeguru.com/cpp/controls/treeview/misc-advanced/article.php/c651/Custom-Draw-Tree-Control.htm" rel="nofollow"> here </a>.</p>
  
  <p>The problem is that after returning CDRF_NOTIFYITEMDRAW on CDDS_PREPAINT notification message, the CDDS_ITEMPREPAINT message never comes...Is there an option to set in order to enable custom drawing..? I imagine that there isn't because the CDDS_PREPAINT message is sent by the control...</p>
  
  <p>...also the code above is not meant to draw every other item...its just a demo from codeguru.com</p>
  
  <p>here is message handling implementation...</p>
  
  <pre><code>int CResourceOutliner::DoModal( int resID, RECT rct, HWND hParent )
  {   
      // Set properties
      m_dwpSaveThis = ( DWORD_PTR )this; /// store this pointer
      m_nResId = resID;
      m_hParent = hParent;
  
      m_hWindow = CreateDialog( GetModuleHandle( NULL ), MAKEINTRESOURCE( m_nResId ), m_hParent, ( DLGPROC )MsgProcStatic );
  
      // Set window position
      SetWindowPos( m_hWindow, 0, rct.left, rct.top, rct.right, rct.bottom, 0 );
  
      ShowWindow( m_hWindow, SW_HIDE );
  
      if( m_hWindow )
          return 1;
  
      return 0; 
  }
  INT CALLBACK CResourceOutliner::MsgProcStatic( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  {
      if( !m_hWindow )
          m_hWindow = hWnd;
  
      CResourceOutliner *pDlg = ( CResourceOutliner* )m_dwpSaveThis;
      if( pDlg )
          return pDlg-&gt;MsgProc( hWnd, uMsg, wParam, lParam );
      else
          return 0;
  }
  INT CALLBACK CResourceOutliner::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  {
      switch( uMsg )
      {
      case WM_INITDIALOG:
          On_WM_INITDIALOG( hWnd, wParam, lParam );
          break;
      case WM_COMMAND:
          On_WM_COMMAND( hWnd, wParam, lParam );
          break;
      case WM_NOTIFY:
          {           
              return On_WM_NOTIFY( hWnd, wParam, lParam );
          }
      case WM_LBUTTONDOWN:
          On_WM_LBUTTONDOWN( hWnd, wParam, lParam );
          break;
      case WM_LBUTTONUP:
          On_WM_LBUTTONUP( hWnd, wParam, lParam );
          break;
      case WM_MOUSEMOVE:
          On_WM_MOUSEMOVE( hWnd, wParam, lParam );
          break;
      case WM_PAINT:
          On_WM_PAINT( hWnd, wParam, lParam );
          break;
      case WM_CLOSE:
          On_WM_CLOSE( hWnd, wParam, lParam );
          break;
      default:
          return 0;
      }
      return 0;
  }
  </code></pre>