⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listviewctrlex.cpp

📁 beereader source code
💻 CPP
📖 第 1 页 / 共 4 页
字号:
  {
	   ASSERT( m_pListCtrl );
       if( nItem >= m_pListCtrl->CListCtrl::GetItemCount() || nItem < 0 ) return FALSE;

	   CItemData* pData = reinterpret_cast<CItemData*>( m_pListCtrl->CListCtrl::GetItemData(nItem) );      
	   ASSERT( pData );

	   return pData->GetBold();
  }

   /*** 设置或获取项的重要标记状态 ***/
  void  CListBase::SetRedFlagItem( int nItem, BOOL bRedFlag )
  {
      ASSERT( m_pListCtrl );
      
	  if( nItem >= m_pListCtrl->CListCtrl::GetItemCount() || nItem < 0 ) return ;

	  CItemData* pData = reinterpret_cast<CItemData*>( m_pListCtrl->CListCtrl::GetItemData(nItem) );      
	  ASSERT( pData );
	  if( pData->GetRedFlag() != bRedFlag )
	  {
	      pData->SetRedFlag( bRedFlag );
		  m_pListCtrl->CListCtrl::RedrawItems( nItem,nItem );
	  }
  }

  BOOL  CListBase::GetRedFlagItem( int nItem )
  {
	   ASSERT( m_pListCtrl );
       if( nItem >= m_pListCtrl->CListCtrl::GetItemCount() || nItem < 0 ) return FALSE;

	   CItemData* pData = reinterpret_cast<CItemData*>( m_pListCtrl->CListCtrl::GetItemData(nItem) );      
	   ASSERT( pData );

	   return pData->GetRedFlag();
  }
/*** A column header has been clicked ****************************************/
BOOL CListBase::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = reinterpret_cast<NM_LISTVIEW*>(pNMHDR);
  int          nSortColumn = pNMListView->iSubItem + 1;

  if (nSortColumn == abs(m_nSortColumn))
    m_nSortColumn = -m_nSortColumn;
  else
    m_nSortColumn = nSortColumn;
  SetSortIcon();

	*pResult = 0;
  return FALSE;
}

/*** A list view (sub)item will be drawn *************************************/
void CListBase::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) 
{
  ASSERT(m_pListCtrl);
  ASSERT(m_pListCtrl->GetHeaderCtrl());

  NMLVCUSTOMDRAW* pNMLVCustomDraw = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);

  switch (pNMLVCustomDraw->nmcd.dwDrawStage)
  {
    case CDDS_PREPAINT:
      *pResult = CDRF_NOTIFYITEMDRAW;
      break;

    case CDDS_ITEMPREPAINT:
      *pResult = CDRF_NOTIFYSUBITEMDRAW;
      break;

    case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
      if (m_bColorSortColumn)
      {
        pNMLVCustomDraw->clrTextBk =
          pNMLVCustomDraw->iSubItem + 1 == abs(m_nSortColumn) ?
          m_dwColSortColor : m_pListCtrl->GetBkColor();
        *pResult = CDRF_NEWFONT;
      }
      else
        *pResult = CDRF_DODEFAULT;
      if (pNMLVCustomDraw->iSubItem == 0) *pResult |= CDRF_NOTIFYPOSTPAINT;
      break;

    case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM:
    {
      // special treatment for first column:
      // fill empty area left of text label
      ASSERT(pNMLVCustomDraw->iSubItem == 0);
      CRect rect;
      m_pListCtrl->GetHeaderCtrl()->GetItemRect(0, rect);
      int  nColumnWidth = rect.Width();
      int  nLeftX       = rect.left - m_pListCtrl->GetScrollPos(SB_HORZ);
      bool bFirstColumn = rect.left == 0;
      bool bHasFocus    = m_pListCtrl->GetFocus() == m_pListCtrl;

      m_pListCtrl->GetItemRect(static_cast<int>(
        pNMLVCustomDraw->nmcd.dwItemSpec), rect, LVIR_LABEL);

      CDC*   pDC = CDC::FromHandle(pNMLVCustomDraw->nmcd.hdc);
      CBrush brushColColor;
      int    nSortColumn    = abs(m_nSortColumn);
      DWORD  dwExStyle      = m_pListCtrl->GetExtendedStyle();
      bool   bFullRowSelect = (dwExStyle & LVS_EX_FULLROWSELECT) != 0;

      LVITEM item;
      item.mask      = LVIF_IMAGE | LVIF_STATE;
      item.iItem     = static_cast<int>(pNMLVCustomDraw->nmcd.dwItemSpec);
      item.iSubItem  = 0;
      item.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK;
      m_pListCtrl->GetItem(&item);
      
      if (!bFirstColumn              &&
          bFullRowSelect             &&
          item.state & LVIS_SELECTED &&
          bHasFocus)
        // create brush with highlight color
        brushColColor.CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
      else if (!bFirstColumn              &&
               bFullRowSelect             &&
               item.state & LVIS_SELECTED &&
               m_pListCtrl->GetStyle() & LVS_SHOWSELALWAYS)
        // create brush with highlight (nonfocus) color
        brushColColor.CreateSolidBrush(GetSysColor(COLOR_3DFACE));
      else if (m_bColorSortColumn && nSortColumn == 1)
        // create brush with sort color
        brushColColor.CreateSolidBrush(m_dwColSortColor);
      else
        // create brush with normal background color
        brushColColor.CreateSolidBrush(m_pListCtrl->GetBkColor());

      // select new brush and save previous brush
      CBrush* pbrushPrev = pDC->SelectObject(&brushColColor);

      // color area left of text label
      pDC->PatBlt(nLeftX, rect.top, __min(rect.left, rect.right) - nLeftX,
                  rect.Height(), PATCOPY);

      if (nColumnWidth > m_nIconXOff)
      {
        // draw state icon
        CImageList* pimglst = m_pListCtrl->GetImageList(LVSIL_STATE);
        if (pimglst)
        {
          int nImage = (item.state & LVIS_STATEIMAGEMASK) >> 12;
          if (nImage > 0)
          {
            IMAGEINFO imgInfo;
            // image indices are zero-based
            if (pimglst->GetImageInfo(--nImage, &imgInfo) &&
                GetStateIconRect(item.iItem, rect))
              pimglst->DrawIndirect(
                pDC, nImage, rect.TopLeft(),
                CSize(__min(rect.Width(),
                            imgInfo.rcImage.right - imgInfo.rcImage.left),
                      __min(rect.Height(),
                            imgInfo.rcImage.bottom - imgInfo.rcImage.top)),
                CPoint(0, 0),
                item.state & LVIS_SELECTED && bHasFocus ?
                ILD_SELECTED : ILD_NORMAL,
                SRCCOPY, CLR_NONE);
          }
        }

        // draw small icon
        pimglst = m_pListCtrl->GetImageList(LVSIL_SMALL);
        if (pimglst)
          if (item.iImage > 0)
          {
            IMAGEINFO imgInfo;
            if (pimglst->GetImageInfo(item.iImage, &imgInfo) &&
                m_pListCtrl->GetItemRect(item.iItem, rect, LVIR_ICON))
            {
              int nIconOffset = rect.left - nLeftX;
              if (nColumnWidth > nIconOffset)
                pimglst->DrawIndirect(
                  pDC, item.iImage, rect.TopLeft(),
                  CSize(__min(nColumnWidth - nIconOffset,
                              imgInfo.rcImage.right - imgInfo.rcImage.left),
                        __min(rect.Height(),
                              imgInfo.rcImage.bottom - imgInfo.rcImage.top)),
                  CPoint(0, 0),
                  item.state & LVIS_SELECTED && bHasFocus ?
                  ILD_SELECTED : ILD_NORMAL,
                  SRCCOPY, CLR_NONE);
            }
          }
      }

      // restore previous brush
      pDC->SelectObject(pbrushPrev);

      *pResult = CDRF_DODEFAULT;
      break;
    }

    default:
      *pResult = CDRF_DODEFAULT;
      break;
  }
}

/*** The background will be erased *******************************************/
bool CListBase::OnEraseBkgnd(CDC* pDC) 
{
  ASSERT(m_pListCtrl);

  if (m_bColorSortColumn)
  {
    CRect rect;
    if (!m_pListCtrl->GetHeaderCtrl()->GetItemRect(
           abs(m_nSortColumn) - 1, rect)) return false;

    int nXScrlOff = m_pListCtrl->GetScrollPos(SB_HORZ);
    int nLeftX    = rect.left  - nXScrlOff;
    int nRightX   = rect.right - nXScrlOff;

    pDC->GetClipBox(&rect);     // get area to be erased
    if (nLeftX < rect.right && nRightX > rect.left)
    {
      CBrush  brushNormalColor(m_pListCtrl->GetBkColor());
      CBrush  brushSortColor(m_dwColSortColor);
      CBrush* pbrushPrev = 0;

      if (nLeftX > rect.left)
      {
        // select brush with normal background color and save default brush
        pbrushPrev = pDC->SelectObject(&brushNormalColor);

        // erase area left from sort column with normal background color
        pDC->PatBlt(rect.left, rect.top, nLeftX - rect.left, rect.Height(),
                    PATCOPY);
      }
    
      // select brush with sort color and save default brush
      if (pbrushPrev)
        pDC->SelectObject(&brushSortColor);
      else
        pbrushPrev = pDC->SelectObject(&brushSortColor);

      // erase area inside sort column with sort color
      if (nLeftX < rect.left)
        if (nRightX < rect.right)
          pDC->PatBlt(rect.left, rect.top, nRightX - rect.left,
                      rect.Height(), PATCOPY);
        else
          pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),
                      PATCOPY);
      else
        if (nRightX < rect.right)
          pDC->PatBlt(nLeftX, rect.top, nRightX - nLeftX, rect.Height(),
                      PATCOPY);
        else
          pDC->PatBlt(nLeftX, rect.top, rect.right - nLeftX, rect.Height(),
                      PATCOPY);

      if (nRightX < rect.right)
      {
        // select brush with normal background color
        pDC->SelectObject(&brushNormalColor);

        // color area right from sort column
        pDC->PatBlt(nRightX, rect.top, rect.right - nRightX, rect.Height(),
                    PATCOPY);
      }

      // restore previous brush
      pDC->SelectObject(pbrushPrev);

      return true;
    }
    else
      return false;
  }
  else
    return false;
}

/*** A key has been pressed  *************************************************/
bool CListBase::OnKeyDown(UINT nChar) 
{
  ASSERT(m_pListCtrl);

  switch (nChar)
  {
    // Numpad-Plus
    case VK_ADD:
      // Ctrl-Numpad-Plus --> set optimum width for all columns
      if (m_bControl && m_bKeepLabelLeft && IndexToOrder(0) > 0)
      {
        LVCOLUMN lvc;
	      lvc.mask = LVCF_FMT;

        int nIndex;
      	for (int nColumn = 0;
             m_pListCtrl->GetColumn(nIndex = OrderToIndex(nColumn), &lvc);
             nColumn++)
        {
          int nOptWidth;

          if (nIndex == 0 || nColumn == 0)
          {
            // calculate needed column width
            nOptWidth = 0;
            for (int nItem = m_pListCtrl->GetItemCount(); --nItem >= 0;)
            {
              int nWidth =
                m_pListCtrl->GetStringWidth(
                  m_pListCtrl->GetItemText(nItem, nIndex));
              if (nWidth > nOptWidth) nOptWidth = nWidth;
            }

            if (nIndex > 0)
            {
              // add space for state icon and small icon
              CRect rcSubItem;
              if (GetRealSubItemRect(0, nIndex, LVIR_BOUNDS, rcSubItem))
              {
                CRect rcLabel;
                if (GetRealSubItemRect(0, nIndex, LVIR_LABEL, rcLabel))
                  nOptWidth += rcLabel.left - rcSubItem.left;
              }

              // add left offset
              nOptWidth += m_nFirstColXOff;
            }
            else
              // add left offset
              nOptWidth += m_nNextColXOff;

            // add right offset
            nOptWidth += m_nNextColXOff;
          }
          else
            nOptWidth = LVSCW_AUTOSIZE;

          m_pListCtrl->SetColumnWidth(nIndex, nOptWidth);
        }
        return true;
      }
      break;

    // Ctrl
    case VK_CONTROL:
      if (m_bKeepLabelLeft && IndexToOrder(0) > 0) return m_bControl = true;
      break;

    // All other keys
    default:
      break;
  }

	return false;
}

/*** A key has been released *************************************************/
void CListBase::OnKeyUp(UINT nChar) 
{
	if (nChar == VK_CONTROL) m_bControl = false;
}

/*** List control loses input focus ******************************************/
void CListBase::OnKillFocus() 
{
  ASSERT(m_pListCtrl);

	// manually remove focus state so that custom drawing will function properly
  int nItem = m_pListCtrl->GetNextItem(-1, LVNI_SELECTED);
  if (nItem >= 0) m_pListCtrl->SetItemState(nItem, 0, LVIS_FOCUSED);
}

/*** The user double-clicks the left mouse button ****************************/
bool CListBase::OnLButtonDblClk(CPoint point) 
{
  ASSERT(m_pListCtrl);

  if (m_pListCtrl->GetStyle() & LVS_OWNERDRAWFIXED)
  {
    UINT flags;
    int  nItem = HitTest(point, &flags);

    if (nItem                          >= 0                 &&
        m_pListCtrl->GetExtendedStyle() & LVS_EX_CHECKBOXES &&
        flags                          == LVHT_ONITEMSTATEICON)
    {
      m_pListCtrl->SetCheck(nItem, !m_pListCtrl->GetCheck(nItem));
      return true;
    }
    else
      return false;
  }
  else
    return false;
}

/*** The user presses the left mouse button **********************************/
bool CListBase::OnLButtonDown(CPoint point) 
{
  ASSERT(m_pListCtrl);

  if (m_pListCtrl->GetStyle() & LVS_OWNERDRAWFIXED)
  {
    UINT flags;
    int  nItem = HitTest(point, &flags);

    if (nItem                          >= 0                 &&
        m_pListCtrl->GetExtendedStyle() & LVS_EX_CHECKBOXES &&
        flags                          == LVHT_ONITEMSTATEICON)
    {
      m_pListCtrl->SetCheck(nItem, !m_pListCtrl->GetCheck(nItem));
      return true;
    }
    else
      return false;
  }
  else
    return false;
}

/*** Divider in header control has been dragged ******************************/
bool CListBase::OnNotify(LPARAM lParam) 
{
  ASSERT(m_pListCtrl);
  ASSERT(m_pListCtrl->GetHeaderCtrl());

  NMHEADER* pNMHdr = reinterpret_cast<NMHEADER*>(lParam);

  if (pNMHdr->hdr.hwndFrom == m_pListCtrl->GetHeaderCtrl()->m_hWnd)
    switch (pNMHdr->hdr.code)
    {
      case HDN_ENDTRACKW:
      case HDN_ENDTRACKA:
      case HDN_ITEMCHANGEDW:
      case HDN_ITEMCHANGEDA:
        if (m_bColorSortColumn) InvalidateNonItemArea();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -