Win32 Custom Draw Treeview Control

半世苍凉 提交于 2021-01-28 00:49:34

问题


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:

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;
                }
            }
    ...
    }
}

This code is from here .

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...

...also the code above is not meant to draw every other item...its just a demo from codeguru.com

here is message handling implementation...

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:


Most return codes from the dialog procedure need to be set via DWLP_MSGRESULT, for example:

SetWindowLongPtr(hWnd, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW);

There are very few exceptions to this rule (WM_CTLCOLORSTATIC is one example that returns directly) as a dialog procedure is generally defined as returning TRUE or FALSE depending on whether the message was handled or not.



来源:https://stackoverflow.com/questions/18805801/win32-custom-draw-treeview-control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!