是这样的,我的界面都是用自绘的,如果用Invalidate(),刷新时感觉整个界面都闪动一次,用InvalidateRect(),只刷新CListCtrl区域,我查了一下资料,据说用,InvalidateRect()后马上调用UpdateWindow()
我试过了,也没用!

解决方案 »

  1.   

    对话框中InvalidateRect()。不行的
    要m_list。InvalidateRect(),有没有UpdateWindow()无所谓。
    也可以:
    m_List.RedrawWindow
      

  2.   

    void CMy3dvstarDlg::OnBnClickedDelete()
    {
    // TODO: 在此添加控件通知处理程序代码
    CRect rect;
    m_list.GetClientRect(&rect);

    //InvalidateRect(NULL,false);
    int total = m_list.GetItemCount();
    for(int i=total-1;i>=0;i--)//删除所选中的项,如果循环从小到大,那么后面的小标会发生改变,删除一个后,后面的不会删除,直到下一次点击delete
    {
    if(m_list.m_bItemCheckState[i])
    {
    m_list.DeleteItem(i);
    m_list.m_bItemCheckState[i]=false;//更新状态
    InvalidateRect(&rect,false);
    }
    total=m_list.GetItemCount();
    }
    //UpdateWindow();
    //Invalidate();
    InvalidateRect(&rect,true);
    UpdateWindow();
    //InvalidateRect(NULL,true);
    }
    这是我的删除CListCtrl的记录的函数
      

  3.   

    RedrawWindow后面两个参数什么意思啊m_list.RedrawWindow(&rect,,RDW_UPDATENOW);
      

  4.   

    如果是报表模式 推荐看看 Codeproject 上的 MFC Grid Ctrl
      

  5.   

    用双缓冲应该可以的,我也是用双缓冲自绘的,不难 你试试。//缓存dc背景
    CDC m_dcMem;
    CBitmap m_bmpMem;m_pDC = GetDC();
    m_dcMem.CreateCompatibleDC(m_pDC);
    m_bmpMem.CreateCompatibleBitmap(m_pDC, rc.Width(), rc.Height());
    CBitmap *poldbmp = m_dcMem.SelectObject(&m_bmpMem);//开始绘制
    Graphics g(m_dcMem.m_hDC);
    g.DrawImage(&pGif,RectF(rc.right,rc.top,100,100),0,0,100,100,UnitPixel); //这里绘制控件背景图//把缓存DC贴出来
    m_pDC->BitBlt(rect.left,rect.top,100,rect.Height(), &m_dcMem, 0, 0, SRCCOPY); //删除资源
    m_dcMem.SelectObject(poldbmp);
    g.ReleaseHDC(m_dcMem.m_hDC);
    ReleaseDC(m_pDC);
    m_dcMem.DeleteDC();
    m_bmpMem.DeleteObject();
    大概这样 你自己根据需要改一改就好了 不难的 呵呵 我也刚学会一点点
      

  6.   

    用双缓冲这样写错了吗?我的怎么没用啊
    void CListCtrlCl::OnPaint() 
    {
    CListCtrl::OnPaint();

    CPaintDC dc(this);//画设备内容

    CRect rect;
    GetClientRect(&rect);
    CDC MemDC;
    MemDC.CreateCompatibleDC(&dc);//创建一个与指定设备兼容的内存设备上下文环境(DC) CBitmap memBmp;
    memBmp.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());//创建与指定的设备环境相关的设备兼容的位图
    //成功返回位图句柄
    CBitmap* pOldMemBmp=MemDC.SelectObject(&memBmp);
    //画背景图片到内存中
    //CBitmap* pnewbmp=dc.SelectObject(&m_Bmp);
    MemDC.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);//保存图片
    dc.SelectObject(pOldMemBmp);
    //dc.SelectObject(pnewbmp);//选择一对象到指定的设备上下文环境中

    rect.top=0;
    rect.left=0;
    rect.right=rect.Width();
    rect.bottom=rect.top+rect.Height();//GetItemHeight(0);
    int size=GetHeaderCtrl()->GetItemCount();//GetCount();
    for(int i=0;i<size&&rect.top<rect.Height();i++)
    {
    rect.OffsetRect(0,20);
    }
    dc.BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);//绘图
    MemDC.SelectObject(pOldMemBmp);
    }
      

  7.   

    把你的DrawItem贴出来看下 呵呵 一起探讨下
      

  8.   

    void CListCtrlCl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    { /*绘制背景图片*/
    CDC* dc=GetDC();
    CRect rect;
    GetClientRect(&rect);
    int Width=rect.Width();
    int Height=rect.Height();
    CDC MemDC;
    MemDC.CreateCompatibleDC(dc);//创建一个与指定设备兼容的内存设备上下文环境(DC) CBitmap memBmp;
    memBmp.CreateCompatibleBitmap(dc,Width,Height);//创建与指定的设备环境相关的设备兼容的位图
    //成功返回位图句柄
    CBitmap* pOldMemBmp=MemDC.SelectObject(&memBmp);
    //画背景图片到内存中
    CBitmap* pnewbmp=dc->SelectObject(&m_Bmp);
    MemDC.BitBlt(0,0,Width,Height,dc,0,0,SRCCOPY);//保存图片
    dc->SelectObject(pnewbmp);//选择一对象到指定的设备上下文环境中
    rect.top=0;
    rect.left=0;
    rect.right=Width;
    rect.bottom=rect.top+Height;//GetItemHeight(0);
    int size=GetHeaderCtrl()->GetItemCount();//GetCount();
    for(int i=0;i<size&&rect.top<Height;i++)
    {
    //DrawItem(MemDC,i,rect,i);
    rect.OffsetRect(0,20);
    }
    dc->BitBlt(0,0,Width,Height,&MemDC,0,0,SRCCOPY);//绘图
    MemDC.SelectObject(pOldMemBmp);
    int total=GetItemCount();//设置复选框的状态,界面未刷新
    if(m_Header.bFlag==false)
    {
    for(int i=0;i<total;i++)
    {
    m_bItemCheckState[i] = !m_bItemCheckState[i];
    InvalidateRect(NULL,false);//点击列表头复选框时,不会重绘下面的内容
    }
    }
    m_Header.bFlag=true;
    if (lpDrawItemStruct->CtlType != ODT_LISTVIEW)
    return;
    RECT rectiSubItem = {0};
    RECT rectCheckBox = {0};
    CDC* pDC;
    pDC = CDC::FromHandle(lpDrawItemStruct->hDC); WCHAR szBuffer[256] = {0};
    int nTotalColumn = 0; CHeaderCtrl* pListHeader = NULL;
    LV_ITEM lvi; pListHeader = (CHeaderCtrl*)GetDlgItem(0);
    nTotalColumn = pListHeader->GetItemCount(); //第一列是要显示复选框的一列
    pListHeader->GetItemRect(0,&rectCheckBox);
    //循环地绘制列表控件各个子项
    LV_COLUMN lvc;//, lvcprev ;
    ::ZeroMemory(&lvc, sizeof(lvc));
    lvc.mask = LVCF_WIDTH | LVCF_FMT;
    for(int iColumn=0;GetColumn(iColumn,&lvc);iColumn++)
    {
    CDC* pDC;
    pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect rtClient;
    GetClientRect(&rtClient);
    if ( iColumn >0 ) 
    {
    GetColumn(iColumn-1, &lvc) ;
    lpDrawItemStruct->rcItem.left+= lvc.cx;
    lpDrawItemStruct->rcItem.right += lpDrawItemStruct->rcItem.left; 
    }
    CRect rcItem;   
    if (!GetSubItemRect(lpDrawItemStruct->itemID,iColumn,LVIR_LABEL,rcItem))   
    continue;   ::ZeroMemory(&lvi, sizeof(lvi));
    lvi.iItem = lpDrawItemStruct->itemID;
    lvi.mask = LVIF_TEXT | LVIF_PARAM;
    lvi.iSubItem = iColumn;//0;
    lvi.pszText = szBuffer;
    lvi.cchTextMax = sizeof(szBuffer);
    VERIFY(GetItem(&lvi)); //pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT));
    if (iColumn == 0)
    {
    rectCheckBox.top = lpDrawItemStruct->rcItem.top;
    rectCheckBox.bottom = lpDrawItemStruct->rcItem.bottom;
    m_nRowHeight=lpDrawItemStruct->rcItem.bottom-lpDrawItemStruct->rcItem.top;
    DrawFrameControl(lpDrawItemStruct->hDC,&rectCheckBox,DFC_BUTTON,DFCS_CHECKED);
    //绘制复选框
    if (m_bItemCheckState[lpDrawItemStruct->itemID])
    {
    m_bItemCheckState[lpDrawItemStruct->itemID]=true;
    DrawFrameControl(lpDrawItemStruct->hDC,&rectCheckBox,DFC_BUTTON,DFCS_CHECKED);//已选中
    }else
    {
    m_bItemCheckState[lpDrawItemStruct->itemID]=false;
    DrawFrameControl(lpDrawItemStruct->hDC,&rectCheckBox,DFC_BUTTON,DFCS_BUTTONCHECK);//未选中
    }
    }else
    {
    int len=_tcslen(szBuffer);
    CRect tRect;
    GetSubItemRect(lpDrawItemStruct->itemID,iColumn,LVIR_BOUNDS,tRect);//根据lpDrawItemStruct->itemID获取当前单元格的tRect

    CSize pixLen=pDC->GetTextExtent(szBuffer,len);//获得所选字体中指定字符串的高度和宽度
    if(pixLen.cx<tRect.Width())//如果字符串的宽度小于单元格的宽度
    pDC->DrawText(szBuffer,len,&lpDrawItemStruct->rcItem,DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS|DT_LEFT);//画文字
    else
    pDC->DrawText(szBuffer,tRect.Width(),&tRect,DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS|DT_LEFT);//画文字,tRect当前单元格矩形框的大小,tRect.Width()单元格宽度
    pDC->DrawEdge(&lpDrawItemStruct->rcItem,EDGE_RAISED,BF_BOTTOM);//下划线
    }
    UINT uFormat=DT_CENTER ;
    if (m_Header.m_Format[iColumn]=='0')
    {
    uFormat = DT_LEFT;
    }else if (m_Header.m_Format[iColumn]=='1')
    {
    uFormat = DT_CENTER;
    }else if (m_Header.m_Format[iColumn]=='2')
    {
    uFormat = DT_RIGHT;
    }
    }
    }
      

  9.   

    好像不是图片的问题,我现在纳闷的时,我在OnPaint函数中给CListCtrl画横线为什么没效果呢?
      

  10.   

    你要明白整个过程。如果你还是用我给你的结构。(即 使用DefWindowProc)那么。
    已经给了一个MemDC了,DefWindowProc(WM_PAINT,MemDC.m_hDC)
    你的自绘将画在这个MemDC上。
    而:
    [color=#FF0000]CDC* dc=GetDC();
    这句把原来给的DC破坏了。[/color]即使不用我给你的结构,也不能要这句,因为:
    LPDRAWITEMSTRUCT lpDrawItemStruct
    里有DC。
      

  11.   

    我后面把他改成CDC* dc=CDC::FromHandle(lpDrawItemStruct->hDC);如果函数里面有DC我不能重新定义一个吗?
      

  12.   

    "如果函数里面有DC我不能重新定义一个吗?"
    为什么重新定义一个?
    如果给你的是一个MemDC,
    你再 dc=GetDC();
    那么 你画的东西就会到窗口DC(GetDC()的结果)上,
    另外 DrawItem会调用 Items 次,每次给你的DC 有上次 绘制内容。
    总之 重新定义一个 是错误的。
      

  13.   

    正如我贴出来的DrawItem函数我在画完CListCtrl的文本后画线
    pDC->DrawEdge(&lpDrawItemStruct->rcItem,EDGE_RAISED,BF_BOTTOM);//下划线
    没添加一行都会画一行,
    然后在OnNMCustomdraw函数中画剩余部分的线,我想知道这样写是不是每次添加一行下面的都会重绘,这样会不会造成闪???
    void CListCtrlCl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LPNMLVCUSTOMDRAW lpnmcd = (LPNMLVCUSTOMDRAW) pNMHDR;  
    if (lpnmcd ->nmcd.dwDrawStage == CDDS_PREPAINT)  
    {  
    *pResult =  CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT;  
    return;  
    }  
    else if (lpnmcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)  
    {
    *pResult =  CDRF_NOTIFYSUBITEMDRAW;  
    return;
    }
    else if (lpnmcd ->nmcd.dwDrawStage == (CDDS_SUBITEM|CDDS_ITEMPREPAINT))  
    {  
    int iItem = lpnmcd->nmcd.dwItemSpec;  
    int iSubItem = lpnmcd->iSubItem;  
    if(iItem >= 0 && iSubItem >= 0)  
    {  
    CRect rSubItem;  
    HDC hDC = lpnmcd->nmcd.hdc;  
    GetSubItemRect(iItem, iSubItem, LVIR_LABEL,rSubItem);  
    if (iSubItem == 0)  
    {  
    rSubItem.left = 0;  
    }
    rSubItem.NormalizeRect();  
    CDC dc;  
    dc.Attach(lpnmcd->nmcd.hdc);  
    //DrawSubItem(&dc,iItem,iSubItem,rSubItem,bSelected,bFocus);
    dc.SetBkMode(TRANSPARENT);
    CString strText;
    strText=GetItemText(iItem,iSubItem);
    dc.DrawText(strText,strText.GetLength(),rSubItem,DT_SINGLELINE |  DT_VCENTER | DT_END_ELLIPSIS|DT_LEFT);
    dc.Detach();  
    *pResult =  CDRF_SKIPDEFAULT;  
    return;  
    }
    }
    else if (lpnmcd ->nmcd.dwDrawStage == CDDS_POSTPAINT)  
    {  
    DrawRemainSpace(lpnmcd);  
    *pResult =  CDRF_SKIPDEFAULT;  
    return;  
    }
    *pResult = 0;
    }
      

  14.   

    那我应该怎样自绘ClistCtrl的横线(网格线我不要竖线,只要横线)呢?而且只画一次让他不清除???
      

  15.   

    通常部分自绘用OnNMCustomdraw
    全部自绘就不要再OnNMCustomdraw了
      

  16.   


    那我应该放在哪里才会自绘一次呢?或者说要怎样写才只会画一次,放在OnNMCustomdraw中如果上面有记录的就不会重新画线,但是没有的部分就会重画一次,看上去有点闪
      

  17.   

    DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    是每个item被调用一次,
    所以一个item的内容要全部画完就行了。
      

  18.   

    你调:
    int total=GetItemCount();//设置复选框的状态,界面未刷新
    干什么?
    每个item被调用一次
    所以一个item的内容要全部画完就行了。
      

  19.   


    调用一次DrawItem可以将插入的一行记录画完,这个我知道,画完一条记录我就在该记录的下面用pDC->DrawEdge(&lpDrawItemStruct->rcItem,EDGE_RAISED,BF_BOTTOM);绘制一条线,但是如果只画有记录的,下面没有内容的看上去就很丑,所以我也要画下面的,现在的问题是,我每添加一条记录,剩余部分的都会画线,而你在画CListCtrl第一条记录时,剩余部分的线已经被画出来了,再次添加的时候线还是会被画,所以界面就会有闪的感觉
      

  20.   


    你说的item是单个的单元格还是每一行?int total=GetItemCount();//设置复选框的状态,界面未刷新
    if(m_Header.bFlag==false)
    {
    for(int i=0;i<total;i++)
    {
    m_bItemCheckState[i] = !m_bItemCheckState[i];
    InvalidateRect(NULL,false);//点击列表头复选框时,不会重绘下面的内容
    }
    }
    m_Header.bFlag=true;我自绘了CHeaderCtrl继承类,在列头添加了一个复选框,添加上面的代码的目的是,当点击列头复选框时CListCtrl的第一列的复选框进行反选。这个与我绘制横线没关系
      

  21.   

    vc60安装盘Samples里有一个ROWLIST例子,很好的ListCtrl自绘。
    你把它的DrawItem好好看看,复制过来,改改就能用。
      

  22.   

    我在列头添加一个复选框,点击列头复选框,我怎么让CListCtrl的记录的第一列复选框进行刷新呢?我之前用的是在Dlg中用定时器刷新,有没有更好的办法
      

  23.   

    已经上传到我的资源。
    ‘ROWLIST.rar’
    //
    // offsets for first and other columns
    #define OFFSET_FIRST    2
    #define OFFSET_OTHER    6void CListViewEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
    CListCtrl& ListCtrl=GetListCtrl();
    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect rcItem(lpDrawItemStruct->rcItem);
    UINT uiFlags = ILD_TRANSPARENT;
    CImageList* pImageList;
    int nItem = lpDrawItemStruct->itemID;
    BOOL bFocus = (GetFocus() == this);
    COLORREF clrTextSave, clrBkSave;
    COLORREF clrImage = m_clrBkgnd;
    static _TCHAR szBuff[MAX_PATH];
    LPCTSTR pszText;// get item data LV_ITEM lvi;
    lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
    lvi.iItem = nItem;
    lvi.iSubItem = 0;
    lvi.pszText = szBuff;
    lvi.cchTextMax = sizeof(szBuff);
    lvi.stateMask = 0xFFFF;     // get all state flags
    ListCtrl.GetItem(&lvi); BOOL bSelected = (bFocus || (GetStyle() & LVS_SHOWSELALWAYS)) && lvi.state & LVIS_SELECTED;
    bSelected = bSelected || (lvi.state & LVIS_DROPHILITED);// set colors if item is selected CRect rcAllLabels;
    ListCtrl.GetItemRect(nItem, rcAllLabels, LVIR_BOUNDS); CRect rcLabel;
    ListCtrl.GetItemRect(nItem, rcLabel, LVIR_LABEL); rcAllLabels.left = rcLabel.left;
    if (m_bClientWidthSel && rcAllLabels.right<m_cxClient)
    rcAllLabels.right = m_cxClient; if (bSelected)
    {
    clrTextSave = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
    clrBkSave = pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT)); pDC->FillRect(rcAllLabels, &CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
    }
    else
    pDC->FillRect(rcAllLabels, &CBrush(m_clrTextBk));// set color and mask for the icon if (lvi.state & LVIS_CUT)
    {
    clrImage = m_clrBkgnd;
    uiFlags |= ILD_BLEND50;
    }
    else if (bSelected)
    {
    clrImage = ::GetSysColor(COLOR_HIGHLIGHT);
    uiFlags |= ILD_BLEND50;
    }// draw state icon UINT nStateImageMask = lvi.state & LVIS_STATEIMAGEMASK;
    if (nStateImageMask)
    {
    int nImage = (nStateImageMask>>12) - 1;
    pImageList = ListCtrl.GetImageList(LVSIL_STATE);
    if (pImageList)
    {
    pImageList->Draw(pDC, nImage,
    CPoint(rcItem.left, rcItem.top), ILD_TRANSPARENT);
    }
    }// draw normal and overlay icon CRect rcIcon;
    ListCtrl.GetItemRect(nItem, rcIcon, LVIR_ICON); pImageList = ListCtrl.GetImageList(LVSIL_SMALL);
    if (pImageList)
    {
    UINT nOvlImageMask=lvi.state & LVIS_OVERLAYMASK;
    if (rcItem.left<rcItem.right-1)
    {
    ImageList_DrawEx(pImageList->m_hImageList, lvi.iImage,
    pDC->m_hDC,rcIcon.left,rcIcon.top, 16, 16,
    m_clrBkgnd, clrImage, uiFlags | nOvlImageMask);
    }
    }// draw item label ListCtrl.GetItemRect(nItem, rcItem, LVIR_LABEL);
    rcItem.right -= m_cxStateImageOffset; pszText = MakeShortString(pDC, szBuff,
    rcItem.right-rcItem.left, 2*OFFSET_FIRST); rcLabel = rcItem;
    rcLabel.left += OFFSET_FIRST;
    rcLabel.right -= OFFSET_FIRST; pDC->DrawText(pszText,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);// draw labels for extra columns LV_COLUMN lvc;
    lvc.mask = LVCF_FMT | LVCF_WIDTH; for(int nColumn = 1; ListCtrl.GetColumn(nColumn, &lvc); nColumn++)
    {
    rcItem.left = rcItem.right;
    rcItem.right += lvc.cx; int nRetLen = ListCtrl.GetItemText(nItem, nColumn,
    szBuff, sizeof(szBuff));
    if (nRetLen == 0)
    continue; pszText = MakeShortString(pDC, szBuff,
    rcItem.right - rcItem.left, 2*OFFSET_OTHER); UINT nJustify = DT_LEFT; if(pszText == szBuff)
    {
    switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
    {
    case LVCFMT_RIGHT:
    nJustify = DT_RIGHT;
    break;
    case LVCFMT_CENTER:
    nJustify = DT_CENTER;
    break;
    default:
    break;
    }
    } rcLabel = rcItem;
    rcLabel.left += OFFSET_OTHER;
    rcLabel.right -= OFFSET_OTHER; pDC->DrawText(pszText, -1, rcLabel,
    nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
    }// draw focus rectangle if item has focus if (lvi.state & LVIS_FOCUSED && bFocus)
    pDC->DrawFocusRect(rcAllLabels);// set original colors if item was selected if (bSelected)
    {
    pDC->SetTextColor(clrTextSave);
    pDC->SetBkColor(clrBkSave);
    }
    }
    //复制到 CMyListCtrl 后:
    删除:CListCtrl& ListCtrl=GetListCtrl();// 父类 CListView
    和 ListCtrl。
      

  24.   

    ‘ROWLIST.rar’ 0 分
    http://download.csdn.net/detail/schlafenhamster/4384517
      

  25.   

    //复制到 CMyListCtrl 后:
    删除:CListCtrl& ListCtrl=GetListCtrl();// 父类 CListView
    和 ListCtrl。这句在哪里,我的CListCtrl继承类中没有这一句啊
      

  26.   

    void CListViewEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
    CListCtrl& ListCtrl=GetListCtrl();
    因为他是CListView所以要这句取List你从list派生就不要这句了。
    下面所有ListCtrl.都去掉
      

  27.   

    幸好我把关键代码贴出来了。
    void CListViewEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    你改改。
    不要头文件的,缺什么变量你定义一个就行。
      

  28.   

    MakeShortString函数主要干嘛的?
      

  29.   

    MakeShortString函数就是解决你以前说的列宽不够 text写到下一列的问题。
      

  30.   

    我之前把与ListCtrl变量相关的全删了,当我添加一条记录时,不会画横线啊,当我点击的时候才会有横线,而且没有文字的部分就没有横线,我的目的是想让CListCtrl自绘横线,但是不要每次添加一条记录时没有文字的部分都重新画一次?但是好像不行
      

  31.   

    CListCtrl自绘横线
    就是TextOut后,再LineTo
      

  32.   

    没有记录的地方呢?也用LineTo也行,但是我在动态的增加一条记录,就是把以前的覆盖重画一次吗?
    但是那样看上去感觉有记录的地方没有闪动,没有记录的地方就闪动,因为他重画了?有没有什么办法只让没有记录的地方画一次呢?
      

  33.   

    CListCtrl不是有很多行吗?有的行填了数据,有的没有填,用LineTo画了?你是说插入一条数据就画一条横线?还是一次画CListCtrl可视区域的所有的横线?
      

  34.   

    是这样的,我知道CListCtrl中的行是用insert插入的,但是有的情况是没有完全插满啊?比如说,我只插入三条记录即三行,而当前CListCtrl窗口的大小可以看到十行,如果我只在插入一条记录后才画一条横线(自绘横线,而不是ClistCtrl的网格),那么下面还有七行的横线不就没有画了吗?
      

  35.   

    '而当前CListCtrl窗口的大小可以看到十行'
    你是说窗口大小是十行,你没插入不用管吧
    另外:LPCTSTR CListViewEx::MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset)
    {
    static const _TCHAR szThreeDots[] = _T("..."); int nStringLen = lstrlen(lpszLong); if(nStringLen == 0 ||
    (pDC->GetTextExtent(lpszLong, nStringLen).cx + nOffset) <= nColumnLen)
    {
    return(lpszLong);
    } static _TCHAR szShort[MAX_PATH]; lstrcpy(szShort,lpszLong);
    int nAddLen = pDC->GetTextExtent(szThreeDots,sizeof(szThreeDots)).cx; for(int i = nStringLen-1; i > 0; i--)
    {
    szShort[i] = 0;
    if((pDC->GetTextExtent(szShort, i).cx + nOffset + nAddLen)
    <= nColumnLen)
    {
    break;
    }
    } lstrcat(szShort, szThreeDots);
    return(szShort);
    }
      

  36.   

    '那样看上去不是很怪吗'
    ListCtrl就是这样,
    Grid控件可以无数据有Grid
      

  37.   

    唉,我就是在OnNMCustomdraw中画剩余部分的横线,但是画线的位置控制不好,好像每次画的都会有点偏移,看上去有点怪,但是他又会把之前的重画一次,所以就感觉上像闪,但又不是
      

  38.   

    void CListCtrlCl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    CRect listRect;
    GetClientRect(&listRect);
    InvalidateRect(&listRect);
    CListCtrl::OnVScroll(nSBCode,nPos,pScrollBar);
    }
    背景图片不动,但是文字重叠,这怎么解决啊
      

  39.   

    //CRect listRect;
    //GetClientRect(&listRect);
    //InvalidateRect(&listRect); 
    CListCtrl::OnVScroll(nSBCode,nPos,pScrollBar);
    最后一句会调paint
      

  40.   

    既然会调OnPaint函数为什么还是文字重叠呢?
      

  41.   

    OnPaint中要加入与滚动条位置有关的代码。
      

  42.   

    list背景是固定的还是随滚动条滚动的?
    背景是固定的:
    CListCtrl::OnVScroll(nSBCode,nPos,pScrollBar);
    InvalidateRect(&amp;listRect);//固定后在重绘,闪烁! 
    是随滚动条滚动的:
    1,背景要大于list
    2.擦背景时把滚动条位置加上。(scrollinfo)
      

  43.   

    背景是固定的:
    CListCtrl::OnVScroll(nSBCode,nPos,pScrollBar);
    InvalidateRect(&amp;listRect);//固定后在重绘,闪烁!  没明白
      

  44.   

    InvalidateRect(0);//滚动后再重绘,可能闪烁! 
      

  45.   

    列头要响应click, 就是Invalidte
    、、
    再说一遍‘背景是固定的’,任何动作都要 Invalidate。
    所以闪烁比较厉害。
      

  46.   


    在列头点击事件中调用Invalidate吗?有没有办法解决闪的问题?
      

  47.   

    在列头点击事件中调用Invalidate吗?
      

  48.   

    "有没有办法解决闪的问题?"
    使用双缓冲要好一些。
    这时要用到3个MemDC。
    一个memDC放背景(就是说背景要放在MemDC中,这样OnEraseBackGrnd就直接返回 TRUE)
    一个memDC要放LictCtrl的图(即DefWindowProc)
    一个memDC把他们2个and起来。
    最后把这个memDC的内容bitblt到dc(CPaintDC dc) 中。dc图形变化一次
    这样搞是因为看到的闪烁是dc上图形变化的结果,让这个变化过程缩短就可以减小闪烁(但不会一点没有)。
      

  49.   

    听上去好像有点道理,但是我没做过,我做的就用一个memDC,1.一个memDC放背景(就是说背景要放在MemDC中,这样OnEraseBackGrnd就直接返回 TRUE)
    这个好像就是我们平时那样截图。
    2.一个memDC要放LictCtrl的图(即DefWindowProc)
    我怎么将DefWindowProc的图片放入memDC中呢?3.一个memDC把他们2个and起来。???
      

  50.   


    void CHeaderCtrlCl::OnHdnItemclickList2(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
    MessageBox(_T("click"));
    Invalidate();
    // TODO: 在此添加控件通知处理程序代码
    *pResult = 0;
    }
    没有进来
      

  51.   

    http://topic.csdn.net/t/20030326/18/1580461.html为什么我只看到了OnNotifyFormat函数?
      

  52.   

    这个HD有点问题。
    ON_NOTIFY(HD_CLICKEDA,OnHeadClicked);
    ON_NOTIFY(HD_CLICKEDW,OnHeadClicked);
    其实是W的那个会进来。
    还有:
    HD_ENDTRACK也是要这样。
      

  53.   

    我怎么将DefWindowProc的图片放入memDC中呢?
    我不是给你代码了吗:
    DefWindowProc(WM_PAINT,memdc.m_hdc)
    不用这个也可以,把你的自绘放这里。“一个memDC把他们2个and起来。”
    就是 一个是 SRCCOPY
    另一个是 SRCAND我的代码你没看懂?
      

  54.   

    改正:
    ON_NOTIFY(HDN_ITEMCLICKA,0,OnHeadItemClick);
    ON_NOTIFY(HDN_ITEMCLICKW,0,OnHeadItemClick);
    0是Header ID
      

  55.   


    CHeaderCtrl有ON_NOTIFY(HD_CLICKEDW,OnHeadClicked);吗?为什么我的继承类变成只读了,消息都不能添加好奇怪啊
      

  56.   

    在派生的List中,不是派生的header。
    Notify是给父类的。
      

  57.   

    把你的ON_NOTIFY给我看看。(全部有关的)
      

  58.   

    afx_msg void OnHdnItemclick(NMHDR *pNMHDR, LRESULT *pResult);ON_NOTIFY(HDN_ITEMCLICKA, 0, &CListCtrlCl::OnHdnItemclick)
    ON_NOTIFY(HDN_ITEMCLICKW, 0, &CListCtrlCl::OnHdnItemclick)void CListCtrlCl::OnHdnItemclick(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
    // TODO: 在此添加控件通知处理程序代码
    Invalidate();
    *pResult = 0;
    }
      

  59.   

    还有一个header宽度调整结束时的 HDN_ENDTRACK。
    也试试。
    Invalidate();
      

  60.   

    CDC* dc=GetDC();
    CRect rect;
    GetClientRect(&rect);
    int Width=rect.Width();
    int Height=rect.Height();
    CDC MemDC;
    MemDC.CreateCompatibleDC(dc);//创建一个与指定设备兼容的内存设备上下文环境(DC) CBitmap memBmp;
    memBmp.CreateCompatibleBitmap(dc,Width,Height);//创建与指定的设备环境相关的设备兼容的位图
    //成功返回位图句柄
    CBitmap* pOldMemBmp=MemDC.SelectObject(&memBmp);
    //画背景图片到内存中
    MemDC.BitBlt(0,0,Width,Height,dc,0,0,SRCCOPY);//保存图片
    rect.top=0;
    rect.left=0;
    rect.right=Width;
    rect.bottom=rect.top+Height;
    int size=GetHeaderCtrl()->GetItemCount();
    for(int i=0;i<size&&rect.top<Height;i++)
    {
    rect.OffsetRect(0,20);
    } dc->BitBlt(0,0,Width,Height,&MemDC,0,0,SRCCOPY);//绘图
    MemDC.SelectObject(pOldMemBmp);请教一个问题,我在MemDC.SelectObject(pOldMemBmp);之前可不可以在memBmp上画横线?并且将图片保存,每次刷新后都显示的是这张图片呢????