我在CDDS_POSTPAINT中渲染时ListView渲染更改

问题描述 投票:0回答:1

所以我花了很多时间试图渲染一些文字。我终于设法通过继承ListView并添加WndProc覆盖来获得某个地方,如下所示:

protected override void WndProc(ref message m){base.WndProc(ref m);

            //NM_CUSTOMDRAW =-12
            switch( m.Msg )
            {
                case 0x004e://WM_NOTIFY:
                case 0x204e://WM_REFLECT_NOTIFY
                    {
                        NMHDR nmhdr     = (NMHDR)System.Runtime.InteropServices.Marshal.PtrToStructure( m.LParam, typeof( NMHDR ) );
                        if ( nmhdr.code == -12 )   //NM_CUSTOMDRAW
                        {
                            NMLVCUSTOMDRAW nmlvcd     = (NMLVCUSTOMDRAW)System.Runtime.InteropServices.Marshal.PtrToStructure( m.LParam, typeof( NMLVCUSTOMDRAW ) );
                            System.Diagnostics.Trace.WriteLine( nmlvcd.nmcd.dwDrawStage.ToString() );
                            if      ( nmlvcd.nmcd.dwDrawStage == 1 ) //CDDS_PREPAINT
                            {
                                int result  = (int)m.Result;
                                result      |= 0x10;//CDRF_NOTIFYPOSTPAINT;
                                m.Result    = (IntPtr)result;
                            }
                            else if ( nmlvcd.nmcd.dwDrawStage == 2 ) //CDDS_POSTPAINT
                            {
                                Graphics g  = Graphics.FromHdc( nmlvcd.nmcd.hdc );
                                if ( DrawFloatingItem != null )
                                { 
                                    PaintEventArgs pe   = new PaintEventArgs( g, nmlvcd.nmcd.rc );
                                    DrawFloatingItem( this, pe );
                                }
                            } 
                            else if ( nmlvcd.nmcd.dwDrawStage == 65537 )    //CDDS_ITEMPREPAINT 
                            {
                                int result  = (int)m.Result;
                                result      |= 0x10;//CDRF_NOTIFYPOSTPAINT;
                                m.Result    = (IntPtr)result;
                            }
                            else if ( nmlvcd.nmcd.dwDrawStage == 65538 )    //CDDS_ITEMPOSTPAINT 
                            {

                            }

                        }
                    }
                    break;
            }
        }

有了这个,我成功地设法渲染列表视图。然而,当我进行渲染时(从DrawFloatingItem事件),然后所有项目向上移动标题的高度(即第一项是在列标题下的rendererd)。

这是以前的清单:

enter image description here

这是之后的清单:

enter image description here

有谁知道我在这里做错了什么?如果我注释掉我的绘图命令(在“DrawFloatingItem”函数内),那么一切都按预期工作。但是,当我进行任何绘图时,渲染出现错误,如上所述。

任何帮助都将受到大力赞赏!

c# winforms listview ownerdrawn
1个回答
0
投票

它的典型我总是在发布问题后立即弄明白。我的错误是我在调用DrawFloatingItem事件之前没有处理我正在创建的Graphics对象。

更改为以下修复了问题:

 using( Graphics g  = Graphics.FromHdc( nmlvcd.nmcd.hdc ) )
 { 
     if ( DrawFloatingItem != null )
     { 
         PaintEventArgs pe   = new PaintEventArgs( g, nmlvcd.nmcd.rc );
         DrawFloatingItem( this, pe );
     }
 }
© www.soinside.com 2019 - 2024. All rights reserved.