如下图:
我想实现的是,使用下面函数
void CListBoxEx::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if( bCalcValidRects )
{
lpncsp[0].rgrc->top += 24;
} CListBox::OnNcCalcSize(bCalcValidRects, lpncsp);
}
使ListCtrl和ListBox的头部空出来一部分,我好在这个空出来的这部分里写上需要的说明文字,但是出现 图中所示的问题,ListBox和ListCtrl中的内容均是到099结束,从图中可以发现ListBox的数据显示完全了,而ListCtrl的内容显示不完全,只显示到097,098都还没显示完,下面就没显示了,我估计是使用了OnNcCalcSize的处理后导致ListCtrl的内容绘制时没有计算我增加的24这个高度引起的,请大家帮我想想怎么解决这个问题。

解决方案 »

  1.   

    再说明一下,图片中头部的文字是我在OnNcPaint函数里绘制上去的,不是在图片处理时加上去的。ListBox和ListCtrl中的OnNcCalcSize的代码完全一样。
      

  2.   

    不行的,我把HeadCtrl属性去掉,就是没有HeadCtrl一样只能显示到098,内容还是显示不完全 。
      

  3.   

    把右边list 控件拖宽点 或者把第二列宽度设置小点就可以了啊
      

  4.   

    还有滚动条宽度问题。//去水平滚动条要可见容易:
    CListCtrl::EnsureVisible
      

  5.   


    OnInitdialog()中代码如下: for( int i = 0; i < 100; i++ )
    {
    CString str;
    str.Format( _T("%03d 中华人民共和国"),i );
    m_ListCtrl.InsertItem( i,str );
    m_ListCtrl.SetItemText( i,1,_T("中华人民共和国") );
    }
    我直接搞个SetTimer( 1,1000,NULL );
    在定时器中 m_ListCtrl.EnsureVisible( 98,TRUE );
    m_ListCtrl.EnsureVisible( 99,TRUE );
    99依然不可见,EnsureVisible所做的操作是:如果nItem在0 , 1 这样的头几个的项目上,最后98 ,99 项目不可见时,他自动把滚动条向下滚,让98 99 可见, 但在这里仍然解决不了这个问题。
      

  6.   

    代码下载:http://www.wsxsoft.com/software_update/wsxsoft/t1.rar
    VS2008的代码 可以试一下的,就知道了。
      

  7.   

    去掉水平滚动条不合适的,我在想的是在这个函数:void CListBoxEx::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
    {
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        if( bCalcValidRects )
        {
            lpncsp[0].rgrc->top += 24;
        }    CListBox::OnNcCalcSize(bCalcValidRects, lpncsp);
    }里除了上面的设置数值之外,是不是还有什么可以设置的地方,来解决这个问题,我查了MSDN等,也试过很多种,始终解决不了。
      

  8.   

    可用ModifyStyle( WS_HSCROLL , 0 );支掉水平条。
      

  9.   

    我是说左边的listbox!给他加个水平滚动条,左右就一样了。
      

  10.   


    晕,这样还是解决不了问题啊。右边的ListCtrl还是没有解决的。我要菜单的美化类里看到他们有这样的处理:
    //这里他用自己方法重载的OnNcCalcsize函数,没有了第一个参数。
    void CMenuWndHook::OnNcCalcsize(NCCALCSIZE_PARAMS* lpncsp)
    {
     lpncsp->rgrc[0].right -= 4;
     lpncsp->rgrc[0].bottom -= 4;
    }然后在void CMenuWndHook::OnWindowPosChanging(WINDOWPOS *pWindowPos)
    {
    pWindowPos->cx += 4;
    pWindowPos->cy += 4;
    }他这样可以解决菜单的增大非客户区面积,同时客户区面积也不受影响,就是客户区也能完全显示。
    我把这个方法用在ListCtrl里,发现对于ListCtrl还是不行。
      

  11.   

    试试这样子
    void CListBoxEx::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
    {
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        lpncsp[0].rgrc->top += 24;
        CListBox::OnNcCalcSize(bCalcValidRects, lpncsp);
    }
      

  12.   


    lpncsp[0].rgrc->top += 24;还是lpncsp->rgrc[0].top += 24;你是不是还将lpncsp->rgrc[0]的bottom也减小了某个数值?
      

  13.   


    同用的,刚试过,你这里写的是CListBox的类的代码,实际是CListBox类用我说的这种方法处理没有任何问题,只是CListCtrl用同样的方法处理时才会出问题的。
      

  14.   


    你这么一说我才发现我上面写的代码中的确有这个问题,实际上应该是lpncsp->rgrc[0].top += 24;这样才对的,lpncsp[0].rgrc->top += 24;这种写法应该是错误的,可是不知道为什么居然编译也没有问题,效果和前面的一样。lpncsp->rgrc[0]的bottom值减少不减少都解决不了问题,我试过了。很奇怪,我在怀疑MFC内部的CListCtrl处理机制可能和标准控件有差别导致这个现象的。
      

  15.   

    晕死,我现在才明白你的意思,我给左边的ListBox加了水平滚动条了,但ListBox是正常的,如下:
      

  16.   

    这样是可以解决你的问题的,之所以你的没有效果是因为虽然添加了OnWindowPosChanging消息映射,但是没有事件响应.因为OnWindowPosChanging是在窗口位置或者大小改变的时候才触发的,所以在对话框的OnInitDialog事件中添加一句:m_ListCtrl.SetWindowPos(NULL,rcListCtrl.left,0,rcListCtrl.Width(),rcListCtrl.Height(),SWP_FRAMECHANGED);才会触发ListCtrl的OnWindowPosChanging事件,在那里添加lpwndpos->cy+=24;就可以解决最后一行看不见的问题,但是同时横向滚动条也不见了,这个也需要解决
      

  17.   

    其实这个无所谓,因为MSDN中定义如下
    typedef struct tagNCCALCSIZE_PARAMS {
       RECT rgrc[3];
       PWINDOWPOS lppos;
    } NCCALCSIZE_PARAMS;rgrc是结构体的第一个成员变量,lpncsp[0]和lpncsp->rgrc[0]的内存地址是一样的.就像在数据中,Buf[0]和Buf的内存地址是一样的.所以并没有错,如果lppos定义在rgrc的上面就错了
      

  18.   

    不行的,我试过了,void CListCtrlEx::OnWindowPosChanging(WINDOWPOS* lpwndpos)本身可以进去,我再用m_ListCtrl.SetWindowPos(NULL,0,0,0,0,SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE );试也不行,我怀疑这是微软设计时的BUG。同样的别的类型的控件可以,而他就不行。真是悲剧。微软在自绘上也有BUG,很烦人。比如我重载CButton的WM_PAINT消息,完全由我自己来画,这时我在WM_PAINT里不写任何代码,结果鼠标在按钮上移动的时候按钮也显示出来了,这说明微软并不仅仅在WM_PAINT里画了按钮,他在鼠标移动的消息里也做了按钮绘制方面的操作了,这样太不统一了,非常不和谐,我这样说只是举个例子,类似的还有,我也知道按钮我可以添加自绘标志,然后在WM_DRAWITEM里处理,我就是觉得微软为什么不把这统一一下,画界面时就只在绘制的消息里处理,不要搞到别的消息里也去画。很不和谐。
      

  19.   

    少写了一句,在OnNcCalcSize中这样写lpncsp->rgrc[0].top+=24;
    lpncsp[0].rgrc->bottom+=30;
      

  20.   

    这样不太和谐,画到外面去了,这个果酱实际上我也试出来过,他不需要重载OnWindowsPosChanging,也不需要SetWindowPos就可以实现了,别的控件这样做果酱也一样,也会画到外面去。
      

  21.   


    的确画到外面了,你仔细看看就知道了,而且在你的电脑上和我的电脑上有区别,我的电脑上下面出来了很高的一段,就是说画在外面画了很高的一段。不仅水平滚动条有问题,垂直滚动条也被盖住了一部分。我就是奇怪为什么ListBox控件用同样的操作方式就没有问题,而ListCtrl就不行。肯定是ListCtrl在绘制客户区的内容时区域判断和别的不一样,微软这点真是不好。
      

  22.   

    滚动条属于非客户区域,却是在客户区域绘制的,当加上lpncsp[0].rgrc->bottom+=24;之后,相当于客户区高度和原来的高度是一样的,但是因为.top+=24了,所以整体高度向下移了,下移以后超出了非客户区的范围,所以绘制的时候绘制到外面去了,实际上滚动条应该在下图的位置,只是没有画出来。
      

  23.   

    另外我想,最终还是使用OnPaint来解决吧。。