Win32自定义绘制树视图控件

时间:2013-09-14 19:52:44

标签: c++ winapi dialog treeview

我正在尝试使用NM_CUSTOMDRAW消息自定义树视图控件。我只是想用灰色绘制每个其他可见项目。这是要绘制的代码:

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

问题是在CDDS_PREPAINT通知消息上返回CDRF_NOTIFYITEMDRAW后,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 个答案:

答案 0 :(得分:4)

对话程序中的大多数返回代码需要通过DWLP_MSGRESULT设置,例如:

SetWindowLongPtr(hWnd, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW);

此规则的例外情况非常少(WM_CTLCOLORSTATIC是一个直接返回的示例),因为dialog procedure通常定义为返回TRUEFALSE,具体取决于是否消息是否得到处理。