当我在 CDDS_POSTPAINT 中渲染时,ListView 渲染发生变化
ListView rendering changing when I render in CDDS_POSTPAINT
所以我花了很多时间来尝试呈现一些文本。我终于设法通过子类化 ListView 并添加 WndProc 覆盖,如下所示:
受保护的覆盖 void WndProc(ref Message m)
{
base.WndProc(参考米);
//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 事件)时,所有项目都会向上移动 header 的高度(即第一个项目是在 header 列下的 rendererd)。
这是之前的列表:
这是之后的列表:
有没有人知道我在这里做错了什么?如果我注释掉我的绘图命令(在 "DrawFloatingItem" 函数内),那么一切都会按预期进行。然而,当我做任何绘图时,渲染就会像上面那样出错。
非常感谢任何帮助!
这很典型,我总是在发布问题后不久就弄明白了。我的错误是我没有处理我在调用 DrawFloatingItem 事件之前创建的 Graphics 对象。
更改为以下解决了问题:
using( Graphics g = Graphics.FromHdc( nmlvcd.nmcd.hdc ) )
{
if ( DrawFloatingItem != null )
{
PaintEventArgs pe = new PaintEventArgs( g, nmlvcd.nmcd.rc );
DrawFloatingItem( this, pe );
}
}
所以我花了很多时间来尝试呈现一些文本。我终于设法通过子类化 ListView 并添加 WndProc 覆盖,如下所示:
受保护的覆盖 void WndProc(ref Message m) { base.WndProc(参考米);
//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 事件)时,所有项目都会向上移动 header 的高度(即第一个项目是在 header 列下的 rendererd)。
这是之前的列表:
这是之后的列表:
有没有人知道我在这里做错了什么?如果我注释掉我的绘图命令(在 "DrawFloatingItem" 函数内),那么一切都会按预期进行。然而,当我做任何绘图时,渲染就会像上面那样出错。
非常感谢任何帮助!
这很典型,我总是在发布问题后不久就弄明白了。我的错误是我没有处理我在调用 DrawFloatingItem 事件之前创建的 Graphics 对象。
更改为以下解决了问题:
using( Graphics g = Graphics.FromHdc( nmlvcd.nmcd.hdc ) )
{
if ( DrawFloatingItem != null )
{
PaintEventArgs pe = new PaintEventArgs( g, nmlvcd.nmcd.rc );
DrawFloatingItem( this, pe );
}
}