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

📄 listviewctrlex.cpp

📁 与LCD1602配套的上位机程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    reinterpret_cast<ITEM_DATA*>(
                      lvItem.lParam)->m_apLVItem[nColumn];

                  pLVItem->iItem    = nItem;
                  pLVItem->iSubItem = nColumn;
                  m_pListCtrl->SetItem(pLVItem);
                }
              }
          }

          m_pListCtrl->SetColumnWidth(nColumn,
                                      m_aColumnData[nColumn]->m_nWidth);
        }
      }
    }
    else
      if (m_aColumnData[nColumn]->m_bVisible)
      {
        // hide column
        int nPhysicalColumn = GetPhysicalIndex(nColumn);

        m_aColumnData[nColumn]->m_nWidth =
          m_pListCtrl->GetColumnWidth(nColumn);
        m_pListCtrl->DefWindowProc(LVM_DELETECOLUMN, nPhysicalColumn, 0);
        m_aColumnData[nColumn]->m_bVisible = false;
      }
}

/*** Private member functions ************************************************/

/*** Compare function for sorting of list view control ***********************/
int CALLBACK CListBase::CompareFunc(LPARAM lParam1, LPARAM lParam2,
                                    LPARAM lParamSort)
{
  CListBase* pThis = reinterpret_cast<CListBase*>(lParamSort);

  return pThis->m_pfnLVCompare(reinterpret_cast<ITEM_DATA*>(lParam1)->m_lParam,
                               reinterpret_cast<ITEM_DATA*>(lParam2)->m_lParam,
                               pThis->m_lParamSort);                 
}

/*** Create image list with sort icons ***************************************/
void CListBase::CreateSortIcons()
{
  if (!m_imglstSortIcons.m_hImageList)
  {
    COLORMAP cm = {RGB(0, 0, 0), GetSysColor(COLOR_GRAYTEXT)};

    m_imglstSortIcons.Create   (9, 5, ILC_COLOR24 | ILC_MASK, 2, 0);
    m_bmpUpArrow.LoadMappedBitmap(IDB_HDRUP, 0, &cm, 1);
    m_nUpArrow = m_imglstSortIcons.Add(&m_bmpUpArrow, RGB(255, 255, 255));
    m_bmpDownArrow.LoadMappedBitmap(IDB_HDRDOWN, 0, &cm, 1);
    m_nDownArrow = m_imglstSortIcons.Add(&m_bmpDownArrow, RGB(255, 255, 255));
  }
}

/*** Draw the entire item (called if window has style LVS_OWNERDRAWFIXED) ****/
void CListBase::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
  ASSERT(m_pListCtrl);

  LVITEM* pItem = GetLVITEM(lpDrawItemStruct->itemID);

  DWORD dwStyle          = m_pListCtrl->GetStyle();
  bool  bAlwaysSelected  = pItem->state & LVIS_SELECTED &&
                           (dwStyle & LVS_SHOWSELALWAYS) != 0;
  bool  bLVHasFocus      = m_pListCtrl->GetFocus() == m_pListCtrl;
  bool  bItemHasFocus    = pItem->state & LVIS_FOCUSED  && bLVHasFocus;
	bool  bSelected        = (pItem->state & LVIS_SELECTED) != 0;
	bool  bReallySelected  = bSelected && bLVHasFocus;
  bool  bFullRowSelected = (m_dwExtendedStyle & LVS_EX_FULLROWSELECT) != 0;

  CRect rcItem;                   // rectangle bounding complete item
  m_pListCtrl->GetItemRect(pItem->iItem, rcItem, LVIR_BOUNDS);

  CRect rcSubItem0;               // rectangle bounding subitem 0
  GetRealSubItemRect(pItem->iItem, 0, LVIR_BOUNDS, rcSubItem0);

  CRect rcLabel;                  // rectangle bounding item label
  GetRealSubItemRect(pItem->iItem, 0, LVIR_LABEL, rcLabel);

	CRect rcSelection;              // rectangle bounding selection
  if (bFullRowSelected)
  {
	  rcSelection = rcItem;
    if (IndexToOrder(0) == 0 || m_bKeepLabelLeft)
    {
      rcSelection.left = rcLabel.left;
      int nWidthOfCol0 =
        static_cast<int>(
          m_pListCtrl->DefWindowProc(LVM_GETCOLUMNWIDTH, OrderToIndex(0), 0));
      if (rcSelection.left > nWidthOfCol0) rcSelection.left = nWidthOfCol0;
    }
  }

	CDC*   pDC          = CDC::FromHandle(lpDrawItemStruct->hDC);
  CBrush brushHiLite;
  DWORD  dwNormalText = GetSysColor(COLOR_WINDOWTEXT);
  DWORD  dwHiLiteBk   = 0;

	if (bReallySelected)
	{
    dwHiLiteBk =
      pItem->iItem == m_nHotItem ? m_dwHotLite : GetSysColor(COLOR_HIGHLIGHT);
    brushHiLite.CreateSolidBrush(dwHiLiteBk);
	}
	else if (bAlwaysSelected)
  {
    dwHiLiteBk = GetSysColor(COLOR_3DFACE);
    brushHiLite.CreateSolidBrush(dwHiLiteBk);
  }

  CFont* pfontPrev          = 0;
  CFont* pfontHotUnderlined = 0;
  bool   bHotUnderlining    = false;
  if (m_dwExtendedStyle & LVS_EX_TWOCLICKACTIVATE                           &&
      (bSelected || bAlwaysSelected)                                        ||
      (m_dwExtendedStyle & (LVS_EX_UNDERLINEHOT | LVS_EX_ONECLICKACTIVATE)) ==
      (LVS_EX_UNDERLINEHOT | LVS_EX_ONECLICKACTIVATE)                       &&
      pItem->iItem == m_nHotItem)
  {
    CFont*  pFont = m_pListCtrl->GetFont();
    LOGFONT logFont;

    if (pFont->GetLogFont(&logFont))
    {
      logFont.lfUnderline = TRUE;
      pfontHotUnderlined  = new CFont;
      pfontHotUnderlined->CreateFontIndirect(&logFont);
      pfontPrev           = pDC->SelectObject(pfontHotUnderlined);
      bHotUnderlining     = true;
    }
  }

  LVCOLUMN lvc;
	lvc.mask = LVCF_FMT | LVCF_WIDTH;

  // display all subitems
  int nIndex;
	for (int nColumn = 0;
       m_pListCtrl->DefWindowProc(LVM_GETCOLUMN,
                                  nIndex = OrderToIndex(nColumn),
                                  reinterpret_cast<LPARAM>(&lvc));
       nColumn++)
  {
    LVITEM* pSubItem  = nIndex > 0 ? GetLVITEM(pItem->iItem, nIndex) : pItem;
    CRect   rcSubItem;                  // rectangle bounding subitem
	  CRect   rcText;                     // output rectangle
    int     nAbsSortColumn = abs(m_nSortColumn) - 1;

    // background color of current column
    DWORD  dwBkColor = m_bColorSortColumn                        &&
                       m_nSortColumn != 0                        &&
                       m_aColumnData[nAbsSortColumn]->m_bVisible &&
                       nIndex == GetPhysicalIndex(nAbsSortColumn) ?
                       m_dwColSortColor : m_pListCtrl->GetBkColor();
    CBrush brushBk(dwBkColor);

    // consider column margins
    if (nColumn > 0)
    {
      // move output rectangle over next column
      rcSubItem.left   = rcSubItem.right;
      rcSubItem.right += lvc.cx;
    }
    else
    {
      rcSubItem       = rcItem;
      rcSubItem.right = rcSubItem.left + lvc.cx;
    }

    if (nIndex == 0 && !m_bKeepLabelLeft || nColumn == 0 && m_bKeepLabelLeft)
    {
      rcText        = rcLabel;
      rcText.left  += m_nFirstColXOff;
      rcText.right -= nIndex > 0 ? m_nNextColXOff : m_nFirstColXOff;
    }
    else
    {
      rcText        = rcSubItem;
      rcText.left  += m_nNextColXOff;
      rcText.right -= m_nNextColXOff;

      // take subitem image into consideration
      if (!m_bKeepLabelLeft                        &&
          nIndex > 0                               &&
          m_dwExtendedStyle & LVS_EX_SUBITEMIMAGES &&
          pSubItem->iImage)
      {
        CRect rcIcon;

        if (m_pListCtrl->GetSubItemRect(pItem->iItem, nIndex, LVIR_ICON,
                                        rcIcon)) rcText.left += rcIcon.Width();
      }
    }

    int  nLabelWidth = GetLabelWidth(pDC, pSubItem, rcText.Width());
    bool bHiLite     = false;

    if (bReallySelected ||
        bAlwaysSelected ||
        bItemHasFocus && !bFullRowSelected)
      if (nIndex == 0 && nColumn != 0 && !m_bKeepLabelLeft && !bFullRowSelected
          ||
          nColumn == 0 && (m_bKeepLabelLeft || nIndex == 0))
      {
        // calculate selection area
        CRect rcSubItemSelection(rcLabel);

        if (!bFullRowSelected)
        {
          int nFormat = nIndex == 0 && nColumn == 0 || !m_bKeepLabelLeft ?
                        m_nFormatOfSubItem0 : lvc.fmt & LVCFMT_JUSTIFYMASK;

          switch (nFormat)
          {
            case LVCFMT_LEFT:
              rcSubItemSelection.right =
                rcSubItemSelection.left +
                  m_nFirstColXOff + nLabelWidth + m_nNextColXOff;
              break;

            case LVCFMT_RIGHT:
              rcSubItemSelection.left =
                rcSubItemSelection.right -
                  m_nFirstColXOff - nLabelWidth - m_nNextColXOff;
              break;

            case LVCFMT_CENTER:
            {
              int nSelectionWidth =
                m_nNextColXOff + nLabelWidth + m_nNextColXOff;
              rcSubItemSelection.left  =
                rcLabel.left + (rcLabel.Width() - nSelectionWidth) / 2;
              rcSubItemSelection.right =
                rcSubItemSelection.left + nSelectionWidth;
              break;
            }

            default:
              ASSERT(false);
              break;
          }
          if (rcSubItemSelection.left < rcLabel.left)
            rcSubItemSelection.left = rcLabel.left;
          if (rcSubItemSelection.right > rcLabel.right)
            rcSubItemSelection.right = rcLabel.right;

          rcSelection = rcSubItemSelection;
        }

        if (bReallySelected || bAlwaysSelected)
        {
          if (rcSubItemSelection.left > rcSubItem.left)
          {
            // fill area left from selection with background color
            CRect rc(rcSubItem);
            rc.right = rcSubItemSelection.left-1;
            CBrush brush(dwBkColor);
            pDC->FillRect(rc, &brushBk);
          }

          // fill selection area with highlight color
          pDC->FillRect(rcSubItemSelection, &brushHiLite);

          // fill area right from selection with background color
          if (rcSubItemSelection.right < rcSubItem.right)
          {
            CRect rc(rcSubItem);
            rc.left = rcSubItemSelection.right+1;
            CBrush brush(dwBkColor);
            pDC->FillRect(rc, &brushBk);
          }

          pDC->SetBkColor  (dwHiLiteBk);
          pDC->SetTextColor(
            bReallySelected ? GetSysColor(COLOR_HIGHLIGHTTEXT) :
            bHotUnderlining ? m_dwHotLite                      :
            dwNormalText);
          bHiLite = true;
        }
      }
      else
        if (bFullRowSelected)
        {
          pDC->FillRect    (rcSubItem, &brushHiLite);
          pDC->SetBkColor  (dwHiLiteBk);
          pDC->SetTextColor(
            bReallySelected ? GetSysColor(COLOR_HIGHLIGHTTEXT) :
            bHotUnderlining ? m_dwHotLite                      :
            dwNormalText);
          bHiLite = true;
        }

    if (!bHiLite)
    {
      pDC->FillRect    (rcSubItem, &brushBk);
      pDC->SetBkColor  (dwBkColor);
      pDC->SetTextColor(bHotUnderlining ? m_dwHotLite : dwNormalText);
    }

    if (!m_bKeepLabelLeft && nIndex  == 0 ||
         m_bKeepLabelLeft && nColumn == 0)
    {
      CRect rcIcon;

      if (GetStateIconRect(pItem->iItem, rcIcon))
        DrawStateIcon(pDC, pItem, rcIcon);
    }

    if (!m_bKeepLabelLeft &&
        (nIndex  == 0 ||
         m_dwExtendedStyle & LVS_EX_SUBITEMIMAGES && pSubItem->iImage > 0) ||
        m_bKeepLabelLeft && nColumn == 0)
    {
      CRect rcIcon;

      if (GetRealSubItemRect(pItem->iItem, m_bKeepLabelLeft ? 0 : nIndex,
                             LVIR_ICON, rcIcon))
      {
        LVITEM*      pLogicalItem;
        NMLVDISPINFO lvDispInfo;

        if (dwStyle & LVS_OWNERDATA)
        {
          lvDispInfo.hdr.hwndFrom   = m_pListCtrl->m_hWnd;
          lvDispInfo.hdr.idFrom     = m_pListCtrl->GetDlgCtrlID();
          lvDispInfo.hdr.code       = LVN_GETDISPINFO;
          lvDispInfo.item.mask      = LVIF_IMAGE;
          lvDispInfo.item.iItem     = pItem->iItem;
          lvDispInfo.item.iSubItem  = 0;
          OnGetdispinfo(&lvDispInfo.hdr);
          pLogicalItem = &lvDispInfo.item;
        }
        else
          pLogicalItem =
            reinterpret_cast<ITEM_DATA*>(pItem->lParam)->m_apLVItem[0];

        // take state of the physical item!
        pLogicalItem->state     = pItem->state;
        pLogicalItem->stateMask = pItem->stateMask;

        DrawSmallIcon(pDC, pLogicalItem, rcIcon);

        pLogicalItem->state     = 0;
        pLogicalItem->stateMask = 0;
      }
    }

    pSubItem->iSubItem = GetLogicalIndex(pSubItem->iSubItem);
    lvc.iSubItem       = pSubItem->iSubItem;
    DrawSubItemText(pDC, pSubItem, &lvc, rcText);

    if (nIndex > 0)
    {
      delete[] pSubItem->pszText;
      delete pSubItem;
    }
  }

  if (bHotUnderlining)
  {
    pDC->SelectObject(pfontPrev);
    delete pfontHotUnderlined;
  }
  delete[] pItem->pszText;
  delete pItem;

  // If item has focus draw focus rectangle
	if (bItemHasFocus)
  {
    pDC->SetTextColor (dwNormalText);
    pDC->DrawFocusRect(rcSelection);
  }
}

/*** Calculate width of item or subitem label ********************************/
int CListBase::GetLabelWidth(CDC* pDC, LVITEM* pItem, int nMaxWidth) const
{
  if (nMaxWidth > 0 && *pItem->pszText)
    return
      __min(pDC->GetTextExtent(pItem->pszText,
                               static_cast<int>(_tcslen(pItem->pszText))).cx,
                               nMaxWidth);
  else
    return 0;
}

/*** Retrieve for a given physical column number the logical column number ***/
int CListBase::GetLogicalIndex(int nPhysicalIndex) const
{
  INT_PTR nColumnCount = m_aColumnData.GetSize();

  for (int i = 0; i < nColumnCount; i++)
    if (m_aColumnData[i]->m_bVisible)
    {
      if (i == nPhysicalIndex) return nPhysicalIndex;
    }
    else
      nPhysicalIndex++;

  ASSERT(false);
  return -1;
}

/*** Retrieve for a given physical column order the logical column order *****/
int CListBase::GetLogicalOrder(int nPhysicalOrder) const
{
  for (int i = 0; i <= nPhysicalOrder; i++)
    for (INT_PTR j = m_aColumnData.GetUpperBound(); j >= 0; j--)
      if (m_aColumnData[j]->m_nOrder == i)
      {
        if (m_aColumnData[j]->m_bVisible)
        {
          if (i == nPhysicalOrder) return nPhysicalOrder;

⌨️ 快捷键说明

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