zoukankan      html  css  js  c++  java
  • CListCtrl自绘checkBox

    本人资质愚钝,这个问题的时间跨度差不多半年时间,终于算是完全解决。那么开始吧,自绘CListCtrl必然是

    在DrawItem里面了,所以派生一个CListCtrlEx是必然了。那个自绘的风格改成true.

    //标记每个checkBox的状态,这个结构体保存了每个item的状态,所有的item会保存在一个vector里
    struct ITEM_CHECK
    {
     int item;                 //第几行
     int flag;                 //falg 0是空,1是被选中,-1是变灰
    };

    //简单写下,千万别复制拷贝。
    class CListCtrlEx : public CListCtrl
    {
             vector<ITEM_CHECK>      m_itemVector;    //保存所有item状态 
    }

    //重写InsertItem,每插入一个m_itemVector添加一个。
    int CListCtrlCl::InsertItem(int nItem,LPCTSTR lpszItem)
    {
     CListCtrl::InsertItem(nItem,lpszItem);

     LVCOLUMN   lvColumn;  
     TCHAR strChar[256];
     lvColumn.pszText=strChar;  
     lvColumn.cchTextMax=256 ;
     lvColumn.mask   = LVCF_TEXT;
     GetColumn(0, &lvColumn);
     if(CString(lvColumn.pszText)!=_T(""))   //如果首列有字,那么就不再绘制checkbox
     {
      return -1;
     }

     m_itemCheck.item=nItem;
     m_itemCheck.flag=0;
     m_itemVector.push_back(m_itemCheck);
                       return;
    }
    //自绘的DrawItem函数
    void CListCtrlEx::DrawItem(LPDRAWITEMSTRUCT lpDIS)
    {
                    CDC* pDC = CDC::FromHandle(lpDIS->hDC);
                    LVITEM lvi = {0};
                      lvi.mask = LVIF_STATE;//|LVIF_IMAGE;
                      lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED ;
                      lvi.iItem = lpDIS->itemID;
             if(!m_bIsCheckBox)                                                //ClistCtrl是否含有checkBox的开关。关系到列表的风格
     {
      return -1;
     }

     m_itemCount=GetItemCount();
     int Top=GetTopIndex();
     //int Total=GetItemCount();
     int Total=m_itemVector.size();                                    //modify,2010,9,10

     if(m_itemVector.empty()||nItem>Total-1)
     {
      return -1;
     }
     CRect rt;                                                     //得到rt的范围,在此范围内创建CheckBox
     GetItemRect(nItem,&rt,LVIR_LABEL);
     rt.top+=2;
     rt.bottom-=2;
     rt.right-=3;

     if(m_itemVector.at(nItem).flag==0)             
     {
      pDC->DrawFrameControl(&rt,DFC_BUTTON,DFCS_BUTTONCHECK);

     }else if(m_itemVector.at(nItem).flag==1)
     {
      pDC->DrawFrameControl(&rt,DFC_BUTTON,DFCS_CHECKED);
     }else
     {
      pDC->DrawFrameControl(&rt,DFC_BUTTON,DFCS_INACTIVE);
     }
    }
    //很简单就是用了CDC::DrawFrameControl画出CheckBox的三种不同状态。

    //单击选中通过修改m_itemVector的item状态,来改变绘制的不同状态。
    void CListCtrlEx:OnLButtonDown(UINT nFlags,CPoint point)
    {
     //CBrush  bush(RGB(2,143,54));
     if(m_itemVector.empty())
     {
      return;
     }
     CRect  tempRect;                                          //list矩形
     CRect  headerRect;                                        //headerCtrl矩形
     int height=point.y;
     int itemHeight = 0;
     int iItem = 0;

     GetItemRect(0, tempRect, LVIR_BOUNDS);
     itemHeight= tempRect.Height();
     m_Header.GetItemRect(0, headerRect);
     iItem = (height - headerRect.Height())/itemHeight;    //减去表头的高度,得到点击的是第几个item

     GetSubItemRect(iItem, 0, LVIR_LABEL, tempRect);
     tempRect.left += 1;
     tempRect.top += 1;
     tempRect.right -= 1;
     tempRect.bottom -= 1;
     if(tempRect.PtInRect(point))
     {
      ITEM_CHECK  &itemCheck = m_itemVector.at(iItem);
      if(itemCheck.flag == 1)
      {
       itemCheck.flag = 0;
      }else if(itemCheck.flag == 0)
      {
       itemCheck.flag = 1;
      }
      InvalidateRect(tempRect, 0);
     
     }
     
     //int coloum=height/15;
     //   SetItemColor(1, 1, RGB(2,143,54));
    }

    //重要的一点在双击消息里响应单击消息,不这样的做的话,当用户点的快了成了双击,checkbox
    //就会没反应,让用户觉得这个checkbox有时反应迟钝,这是很恼人的一件事。所以在双击消息里也弄好。
    void CListCtrlEx::OnLButtonDblClk(UINT nFlags,CPoint point)
    {
                   OnLButtonDown( nFlags, point) ; //调用单击
    }

  • 相关阅读:
    移动端兼容
    三点优化
    面向对象(一)
    BootCDN和npm
    分页逻辑
    多物体运动框架
    兼容样式
    省略
    行内元素在水平和垂直排列的时候会有间距
    [Swift]LeetCode1053.交换一次的先前排列 | Previous Permutation With One Swap
  • 原文地址:https://www.cnblogs.com/yuzhould/p/4454985.html
Copyright © 2011-2022 走看看