本帖最后由 jaynaviee 于 2013-01-29 14:56:47 编辑

解决方案 »

  1.   

    CWnd 的 滚动条 属于 非客户区
      

  2.   


    强制刷新也没用刷新也没有用
    void CSkinListCtrl::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)
    {
    /*CRect rSubItem, rectClient;
    int nColumnCount = GetHeaderCtrl()->GetItemCount();
    if (nColumnCount>0)
    {
    GetSubItemRect(lpnmcd->nmcd.dwItemSpec,nColumnCount-1, LVIR_LABEL,rSubItem);
    GetClientRect(&rectClient);
    rSubItem.left = rSubItem.right;
    rSubItem.right = rectClient.right;
    rSubItem.NormalizeRect();
    bool bSelected = false;
    if (GetItemState(lpnmcd->nmcd.dwItemSpec, LVIS_SELECTED))
    {
    bSelected = true;
    } bool bFocus = false;
    HWND hWndFocus = ::GetFocus();
    if (::IsChild(m_hWnd,hWndFocus) || m_hWnd == hWndFocus)
    {
    bFocus = true;
    }
    CDC dc;
    dc.Attach(lpnmcd->nmcd.hdc);
    draw_row_bg(&dc, rSubItem, bSelected , bFocus, (int) lpnmcd->nmcd.dwItemSpec);
    dc.Detach();
    }*/ *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;
    }

    bool bSelected = false;
    if (GetItemState(iItem, LVIS_SELECTED))
    {
    bSelected = true;
    } bool bFocus = false;
    CWnd *pWndFocus = GetFocus();
    if (IsChild(pWndFocus) || pWndFocus == this)
    {
    bFocus = true;
    } rSubItem.NormalizeRect();
    CDC dc;
    dc.Attach(lpnmcd->nmcd.hdc);
    DrawSubItem(&dc,iItem,iSubItem,rSubItem,bSelected,bFocus);
    dc.Detach();
    *pResult =  CDRF_SKIPDEFAULT;
    return;
    }
    }
    else if (lpnmcd ->nmcd.dwDrawStage == CDDS_POSTPAINT)
    {
    DrawRemainSpace(lpnmcd);
    *pResult =  CDRF_SKIPDEFAULT;
    return;
    }
     
    *pResult = 0;}// overwrite:
    void CSkinListCtrl::DrawSubItem(CDC *pDC, int nItem, int nSubItem, CRect &rSubItem, bool bSelected, bool bFocus)
    {
    pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(m_colorText/*RGB(0, 0, 0)*/); CFont font;
    font.CreateFont(m_nHeight,   // nHeight
    m_nWidth,                         // nWidth
    0,                         // nEscapement
    0,                         // nOrientation
    FW_NORMAL,                 // nWeight
    FALSE,                     // bItalic
    FALSE,                     // bUnderline
    0,                         // cStrikeOut
    ANSI_CHARSET,              // nCharSet
    OUT_DEFAULT_PRECIS,        // nOutPrecision
    CLIP_DEFAULT_PRECIS,       // nClipPrecision
    DEFAULT_QUALITY,           // nQuality
    DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
    _T("微软雅黑"));
    pDC->SelectObject(&font); CString strText;
    strText = GetItemText(nItem, nSubItem);
    draw_row_bg(pDC, rSubItem, bSelected, bFocus, nItem);
    if ( m_nAlign == 1)
    {// 右对齐
    pDC->DrawText(strText, strText.GetLength(), &rSubItem, DT_SINGLELINE | DT_RIGHT | DT_VCENTER | DT_END_ELLIPSIS);
    }
    else if ( m_nAlign == 2)
    {// 居中
    pDC->DrawText(strText, strText.GetLength(), &rSubItem, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS);
    }
    else
    {// 左对齐
    pDC->DrawText(strText, strText.GetLength(), &rSubItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_END_ELLIPSIS);
    }//   int n = GetHeaderCtrl()->GetItemCount();
    //  
    //   if (GetHeaderCtrl()->GetItemCount() == nItem + 1)
    //   {
    //   CRect rectClient;
    //   GetClientRect(&rectClient);
    //  
    //   CRect  rcSubItem;
    //  
    //   if (rSubItem.right <= rectClient.right)
    //   {
    //   rcSubItem.left=rSubItem.right;
    //   rcSubItem.right=rectClient.right;
    //   rcSubItem.top = rSubItem.top;
    //   rcSubItem.bottom = rSubItem.bottom;
    //   draw_row_bg(pDC, rSubItem, bSelected, bFocus, nItem);
    //   }
    //   }
     
    }// 画剩余部分
    void CSkinListCtrl::DrawRemainSpace(LPNMLVCUSTOMDRAW lpnmcd)
    {
    //  int nTop = lpnmcd->nmcd.rc.top;
    //  int nCount = GetItemCount();
    //  if (nCount > 0)
    //  {
    //  CRect rcItem;
    //  GetItemRect(nCount - 1, &rcItem, LVIR_LABEL);
    //  nTop = rcItem.bottom;
    //  }
    // 
    //  CRect rectClient;
    //  GetClientRect(&rectClient);
    //  if (nTop < lpnmcd->nmcd.rc.bottom) // 有剩余
    //  {
    //  CRect rcRemain = lpnmcd->nmcd.rc;
    //  rcRemain.top = nTop;
    //  rcRemain.right = rectClient.right;
    //  int nRemainItem = rcRemain.Height() / LIST_ITEM_HEIGHT;
    //  if (rcRemain.Height() % LIST_ITEM_HEIGHT)
    //  {
    //  nRemainItem++;
    //  }
    // 
    //  int pos = GetScrollPos(SB_HORZ);
    //  CDC dc;
    //  dc.Attach(lpnmcd->nmcd.hdc);
    //  int nColumnCount = GetHeaderCtrl()->GetItemCount();
    //  CRect  rcSubItem;
    //  CRect rcItem;
    //  for (int i = 0; i < nRemainItem; ++i)
    //  {
    // 
    //  rcItem.top = rcRemain.top + i * LIST_ITEM_HEIGHT;
    //  rcItem.left = rcRemain.left;
    //  rcItem.right = rcRemain.right;
    //  rcItem.bottom = rcItem.top + LIST_ITEM_HEIGHT;
    //  for (int j = 0; j < nColumnCount; ++j)
    //  {
    //  GetHeaderCtrl()->GetItemRect(j, &rcSubItem);
    //  rcSubItem.top = rcItem.top;
    //  rcSubItem.bottom = rcItem.bottom;
    //  rcSubItem.OffsetRect(-pos, 0);
    //  if(rcSubItem.right < rcRemain.left || rcSubItem.left > rcRemain.right)
    //  continue;
    //  draw_row_bg(&dc, rcSubItem, false, false, i + nCount);
    //  }
    // //  if (rcSubItem.right<rectClient.right)
    // //  {
    // //  rcSubItem.left=rcSubItem.right;
    // //  rcSubItem.right=rectClient.right;
    // //                 draw_row_bg(&dc, rcSubItem, false, false, i+nCount);
    // //  }
    // 
    //  }
    // 
    //  dc.Detach();
    //  }
    int nTop = lpnmcd->nmcd.rc.top;
    int nCount = GetItemCount();
    if (nCount > 0)
    {
    CRect rcItem;
    GetItemRect(nCount - 1, &rcItem, LVIR_LABEL);
    nTop = rcItem.bottom;
    }
    CRect rectClient;
    GetClientRect(&rectClient);
    if (nTop < lpnmcd->nmcd.rc.bottom) // 有剩余
    {
    CRect rcRemain = lpnmcd->nmcd.rc;
    rcRemain.top = nTop;
    rcRemain.right = rectClient.right;
    int nRemainItem = rcRemain.Height() / LIST_ITEM_HEIGHT;
    if (rcRemain.Height() % LIST_ITEM_HEIGHT)
    {
    nRemainItem++;
    }
    int pos = GetScrollPos(SB_HORZ);
    CDC dc;
    dc.Attach(lpnmcd->nmcd.hdc);
    for (int i = 0; i < nRemainItem; ++i)
    {
    CRect rcItem;
    rcItem.top = rcRemain.top + i * LIST_ITEM_HEIGHT;
    rcItem.left = rcRemain.left;
    rcItem.right = rcRemain.right;
    rcItem.bottom = rcItem.top + LIST_ITEM_HEIGHT;
    int nColumnCount = GetHeaderCtrl()->GetItemCount();
    CRect  rcSubItem;
    for (int j = 0; j < nColumnCount; ++j)
    {
    GetHeaderCtrl()->GetItemRect(j, &rcSubItem);
    rcSubItem.top = rcItem.top;
    rcSubItem.bottom = rcItem.bottom; //rcSubItem.left = rcItem.left;
    //rcSubItem.right = rcItem.right; rcSubItem.OffsetRect(-pos, 0);
    if(rcSubItem.right < rcRemain.left || rcSubItem.left > rcRemain.right)
    continue;
    draw_row_bg(&dc, rcSubItem, false, false, i + nCount);
    }
    //if (rcSubItem.right <= rectClient.right)
    //{
    // rcSubItem.left=rcSubItem.right;
    // rcSubItem.right=rectClient.right;
       //             draw_row_bg(&dc, rcSubItem, false, false, i+nCount);
    //}
    }
    dc.Detach();
    }
    }void CSkinListCtrl::draw_row_bg(CDC *pDC, RECT rc, bool bSelected, bool bFocus,int nRow)
    {  bool bOdd = (nRow % 2 == 0 ? true : false); CRect rect = rc;
    if (rect.Width() == 0)
    {
    return;
    }
         
    draw_row_bg(pDC, rc, bSelected,bFocus,bOdd);
    }void CSkinListCtrl::draw_row_bg(CDC *pDC, RECT rc, bool bSelected, bool bFocus, bool bOdd)
    {
    CRect rect = rc;
    if (rect.Width() == 0)
    {
    return;
    } int nSave = pDC->SaveDC();
    if (bSelected)
    {
    if (bFocus)
    {
    CBrush selectBrush;
    selectBrush.CreateSolidBrush(RGB(49,106,197));
    pDC->FillRect(&rc, &selectBrush); }
    else
    {
    CBrush selectNoFocusBrush;
    selectNoFocusBrush.CreateSolidBrush(RGB(49,106,197));
    pDC->FillRect(&rc, &selectNoFocusBrush);
    }
    }
    else if (bOdd)
    {
    CBrush oddBrush;
    oddBrush.CreateSolidBrush(m_color1/*RGB(255, 255, 255)*/);
    pDC->FillRect(&rc, &oddBrush); }
    else
    {
    CBrush normalBrush;
    normalBrush.CreateSolidBrush(m_color2/*RGB(243, 243, 243)*/);
    pDC->FillRect(&rc, &normalBrush);
    } // 画竖线
    //  CPen pen;
    //  pen.CreatePen(PS_SOLID, 1, RGB(218, 218, 218));
    // 
    //  pDC->SelectObject(&pen);
    //  pDC->MoveTo(rc.right - 1, rc.top);
    //  pDC->LineTo(rc.right - 1, rc.bottom); // 画选中的底部分割线
    //  if (bSelected)
    //  {
    //  CPen bottomPen;
    //  bottomPen.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
    // 
    //  pDC->SelectObject(&bottomPen);
    //  pDC->MoveTo(rc.left, rc.bottom - 1);
    //  pDC->LineTo(rc.right, rc.bottom - 1);
    //  }
    pDC->RestoreDC(nSave);
    }
    void CSkinListCtrl::Init()
    {
    CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl();
    if (pHeaderCtrl!=NULL)
    {
    m_header.SubclassWindow(pHeaderCtrl->GetSafeHwnd());
    }
    LOGFONT logfont;
    memset(&logfont, 0, sizeof(logfont));
    logfont.lfWeight = FW_NORMAL;
    logfont.lfCharSet = GB2312_CHARSET; logfont.lfHeight = m_nHeight;
    logfont.lfWeight = m_nWidth; _tcscpy_s(logfont.lfFaceName, LF_FACESIZE, _T("微软雅黑"));
    logfont.lfHeight = -(LIST_ITEM_HEIGHT-1);
    CFont font;
    font.CreateFontIndirect(&logfont);
    SetFont(&font);
    font.Detach();
    }void CSkinListCtrl::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
    {
    Invalidate();
    *pResult = 0;
    }void CSkinListCtrl::InvalidateItem(int nItem)
    {
    CRect rcClient;
    GetClientRect(&rcClient); CRect rcItem;
    GetItemRect(nItem, &rcItem, LVIR_BOUNDS); rcItem.left = rcClient.left;
    rcItem.right = rcClient.right;
    InvalidateRect(&rcItem,FALSE);
    }
      

  3.   

    void CSkinListCtrl::PreSubclassWindow()
    {
        Init();
    CListCtrl::PreSubclassWindow();
    }void CSkinListCtrl::DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)
    {}void CSkinListCtrl::OnHdnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
    Default();
    Invalidate();
    *pResult = 0;
    }void CSkinListCtrl::OnLvnEndScroll(NMHDR *pNMHDR, LRESULT *pResult)
    {
    // 此功能要求 Internet Explorer 5.5 或更高版本。
    // 符号 _WIN32_IE 必须是 >= 0x0560。
    LPNMLVSCROLL pStateChanged = reinterpret_cast<LPNMLVSCROLL>(pNMHDR);
    Invalidate();
    *pResult = 0;
    }
    // 设置文字大小
    void CSkinListCtrl::SetTextFontStyle(int nHeight, int nWidth, COLORREF clr)
    {
    m_nHeight = nHeight;
    m_nWidth  = nWidth;
    m_colorText = clr;
    }
    void CSkinListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    Invalidate(); CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
    }void CSkinListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    Invalidate(); CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
    }
    // 设置列表头文字大小和颜色
    void CSkinListCtrl::SetHeadFont(int nHeight, int nWidth,COLORREF clrText, COLORREF clrItem, COLORREF clrBG)
    {
    m_header.m_fontHeight = nHeight;
    m_header.m_fontWith = nWidth;
    m_header.m_clrHead = clrBG;
    m_header.m_clrHeadItem = clrItem;
    m_header.m_clrHeadText = clrText;
    }
    LRESULT CSkinListCtrl::OnSetFont(WPARAM wParam, LPARAM)
    {
    LRESULT res =  Default();
    CRect rc;
    GetWindowRect( &rc );
    WINDOWPOS wp;
    wp.hwnd = m_hWnd;
    wp.cx = rc.Width();
    wp.cy = rc.Height();
    wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
    SendMessage( WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp );
    return res;;
    }
    void CSkinListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
    {
    //  LOGFONT lf;
    //  GetFont()->GetLogFont( &lf );
    //  if( lf.lfHeight < 0 )
    //  {
    //  lpMeasureItemStruct->itemHeight =lf.lfHeight; 
    //  }
    //  else
    //  {
    //  lpMeasureItemStruct->itemHeight = lf.lfHeight; 
    //  }
    CClientDC dc(this); TEXTMETRIC tm;
    dc.SelectObject(GetFont()); dc.GetTextMetrics(&tm); lpMeasureItemStruct->itemHeight = tm.tmHeight + tm.tmExternalLeading;
    }
    // 设置表头高度
    void CSkinListCtrl::SetHeadHeight(float fHeight)
    {
    m_header.m_Height =  fHeight;
    }
    // 设置字体对齐方式0:左对齐;1:右对齐;2;剧中
    void CSkinListCtrl::SetFontAlign(int nAlign)
    {
    m_nAlign = nAlign;
    }
    BOOL CSkinListCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
    {
    Invalidate(); return CListCtrl::OnMouseWheel(nFlags, zDelta, pt);
    }void CSkinListCtrl::OnMouseMove(UINT nFlags, CPoint point)
    {
    //如果开启文本提示 
    if(m_bEnableTips) 

    CString str; 
    LVHITTESTINFO lvhti; // 判断鼠标当前所在的位置(行, 列) 
    lvhti.pt = point;  //如果鼠标移动到另一个单元格内, 则进行处理; 否则, 不做处理 
    SubItemHitTest(&lvhti); 
    if((lvhti.iItem != m_nItem) || (lvhti.iSubItem != m_nSubItem)) 

    // 保存当前鼠标所在的(行,列) 
    m_nItem = lvhti.iItem; 
    // 如果鼠标移动到一个合法的单元格内,则显示新的提示信息 
    m_nSubItem = lvhti.iSubItem;  // 否则, 不显示提示 
    if((m_nItem != -1) && (m_nSubItem != -1)) 

    // @@@@@@@@ 在这里修改要显示的提示信息 
    // 这里仅仅是一个例子---获得当前单元格的文字信息,设置新的提示信息 
    str = GetItemText(m_nItem ,m_nSubItem); 
    m_toolTip.AddTool(this, str); 
    // 显示提示框 
    m_toolTip.Pop(); 

    else 

    m_toolTip.AddTool(this, _T("")); 
    m_toolTip.Pop(); 

    }  if (NULL != m_toolTip.m_hWnd) 

    MSG msg; 
    msg.hwnd= m_hWnd; 
    msg.message= WM_MOUSEMOVE; 
    msg.wParam= (WPARAM)nFlags; 
    msg.lParam= MAKELPARAM(LOWORD(point.x),LOWORD(point.y)); 
    msg.time= 0; 
    msg.pt.x= point.x; 
    msg.pt.y= point.y; 
    m_toolTip.RelayEvent(&msg); 
    }  }  CListCtrl::OnMouseMove(nFlags, point);
    }
    这是代码,请各位给点点下, 谢谢了!!!!
      

  4.   

    WM_NCPAINT 没用?
    CWnd 的 滚动条 属于 非客户区
      

  5.   

    我觉得应该是OnNMCustomdraw的问题.
    你用排除法看下是哪个代码的问题.
    着重查看矩形区域是否超过了滚动的地方.还有,既然有了DrawItem的消息响应.应该没有OnNMCustomdraw的消息进来吧.
      

  6.   

    另外,个人感觉OnNMCustomdraw这个东西不好用.有点缺陷.
    你用drawitem全部自绘,还来得自在些.