2013-09-14 2 views
2

Я пытаюсь настроить элемент управления treeview с помощью сообщений NM_CUSTOMDRAW. Я просто хочу нарисовать любой другой видимый предмет с серым цветом. Вот код рисовать:Win32 Custom Draw Treeview Control

INT CResourceOutliner::On_WM_NOTIFY(HWND hDlg, WPARAM wParam, LPARAM lParam) 
{ 
    HWND hTree = GetDlgItem(hDlg, IDC_TREE1); 
    switch(((LPNMHDR)lParam)->code) 
    { 
    ... 
    case NM_CUSTOMDRAW: 
      {   
       LPNMTVCUSTOMDRAW pCustomDraw = (LPNMTVCUSTOMDRAW)lParam; 
       switch(pCustomDraw->nmcd.dwDrawStage) 
       {    
       case CDDS_PREPAINT: 
        return CDRF_NOTIFYITEMDRAW; 
       case CDDS_ITEMPREPAINT: 
        { 
         switch (pCustomDraw->iLevel)     
         { 
          // painting all 0-level items blue,      
          // and all 1-level items red (GGH)25.      
         case 0: 
          { 
          if(pCustomDraw->nmcd.uItemState == (CDIS_FOCUS | CDIS_SELECTED))        
           pCustomDraw->clrTextBk = RGB(255, 255, 255);       
          else          
           pCustomDraw->clrTextBk = RGB(128, 128, 128);       
           break; 
          } 
         case 1:       
          { 
           if(pCustomDraw->nmcd.uItemState == (CDIS_FOCUS | CDIS_SELECTED))        
            pCustomDraw->clrTextBk = RGB(255, 255, 255);       
           else  
            pCustomDraw->clrTextBk = RGB(128, 128, 128); 
           break; 
          } 
         default: 
          break; 
         } 
         return CDRF_SKIPDEFAULT; 
        } 
       default: 
        break; 
       } 
      } 
    ... 
    } 
} 

Этот код из here.

Проблема заключается в том, что после возвращения CDRF_NOTIFYITEMDRAW на уведомление об уведомлении CDDS_PREPAINT сообщение CDDS_ITEMPREPAINT никогда не приходит ... Есть ли возможность установить, чтобы включить пользовательский чертеж ..? Я полагаю, что нет, потому что сообщение CDDS_PREPAINT отправляется с помощью элемента управления ...

... также код, приведенный выше, не предназначен для рисования каждого другого элемента ... его просто демо от codeguru.com

здесь обработки сообщений реализации ...

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->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; 
} 
+1

Я не касался пользовательского кода для рисования, подобного этому, но я проверил один из моих старых рабочих проектов, и кажется, что код возвращает 'CDRF_NOTIFYITEMDRAW' на' dwDrawStage & CDDS_ITEM' вместо 'dwDrawStage & CDDS_PREPAINT'. – nmaier

+0

@nmaier Я попробовал ваше предложение, но функция не получила уведомление об уведомлении CDDS_ITEM ... единственное значение drawstage, полученное функцией, - «1» (CDDS_PREPAINT) ... –

+0

@nmaier, возможно, это связано с моей обработкой сообщений ... проверить отредактированный код выше ... извините за форматирование ... –

ответ

4

Большинство кодов возврата из диалоговой процедуры должны быть установлены с помощью DWLP_MSGRESULT, например:

SetWindowLongPtr(hWnd, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW); 

Существует очень мало исключений из этого правила (WM_CTLCOLORSTATIC - один пример, который возвращается непосредственно), поскольку dialog procedure обычно определяется как возвращающий TRUE или FALSE в зависимости от того, было ли обработано сообщение или нет.

+1

большое спасибо! для тех, кто читает позже, обязательно верните 1 после установки результата сообщения –