User ID:
Password:
Remember Me:
Forgot Password?
Not a member?
Click here for more information and to register.

    Simplified Subitem Editing





    Click here for a larger image.

    Environment: VC6 SP5

    This article suggests a way to subclass the listviews edit control, but unlike the article "Editing listview Subitems Using LVM_GETEDITCONTROL," it uses a much simpler and hopefully better method. Give it a try!

    1. Vars
      public:
        CSubEdit m_editWnd;
        int m_item;
        int m_subitem;
      
      CSubeditListView::CSubeditListView()
      {
        m_subitem = 0;
      }
      
    2. Detect subitem mouse clicks
      void CSubeditListView::OnLButtonDown(UINT nFlags, CPoint point)
      {
        LVHITTESTINFO  lvhit;
        lvhit.pt = point;
        int item = GetListCtrl().SubItemHitTest(&lvhit);
      
        //if (over a subitem)
        if (item != -1 && lvhit.iSubItem && (lvhit.flags & 
                          LVHT_ONITEM ))
          {
          //mouse click outside the editbox in an already
          //editing cell cancels editing
          if (m_subitem == lvhit.iSubItem && item == m_item)
            {
            CListView::OnLButtonDown(nFlags, point);
            }
          else
            {
            CListView::OnLButtonDown(nFlags, point);
      
            m_subitem = lvhit.iSubItem;
            m_item = item;
            GetListCtrl().EditLabel(item);
            }
      
          }
        else
          CListView::OnLButtonDown(nFlags, point);
      }
      
    3. Handle OnBeginLabelEdit
      void CSubeditListView::OnBeginLabelEdit(NMHDR* pNMHDR,
          LRESULT* pResult)
      {
        LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
      
        //if (subitem selected for editing)
        if (m_subitem)
          {
          ASSERT(m_item == pDispInfo->item.iItem);
      
          CRect  subrect;
          GetListCtrl().GetSubItemRect( pDispInfo->item.iItem,
                                        m_subitem,
              LVIR_BOUNDS , subrect );
      
          //get edit control and subclass
          HWND hWnd=(HWND)SendMessage(LVM_GETEDITCONTROL);
          ASSERT(hWnd!=NULL);
          VERIFY(m_editWnd.SubclassWindow(hWnd));
      
          //move edit control text 1 pixel to the right of org label,
          //as Windows does it...
          m_editWnd.m_x=subrect.left + 6; 
          m_editWnd.SetWindowText(GetListCtrl().GetItemText
              (pDispInfo->item.iItem,m_subitem));
      
          //hide subitem text so it don't show if we delete some
          //text in the edit control
          //OnPaint handles other issues also regarding this
          CRect  rect;
          GetListCtrl().GetSubItemRect(pDispInfo->item.iItem,m_subitem,
              LVIR_LABEL ,rect);
          CDC* hDc = GetDC();
          hDc->FillRect(rect,&CBrush(::GetSysColor(COLOR_WINDOW)));
          ReleaseDC(hDc);
      
          }
      
        //return: editing permitted
        *pResult = 0;
      
      }
      
    4. Positioning the editcontrol
      void CSubEdit::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
      {
        lpwndpos->x=m_x;
      
        CEdit::OnWindowPosChanging(lpwndpos);
      }
      
    5. Handle painting
      void CSubeditListView::OnPaint()
      {
        //if (subitem editing)
        if (m_subitem)
          {
      
          CRect  rect;
          CRect  editrect;
      
          GetListCtrl().GetSubItemRect(m_item,m_subitem,LVIR_LABEL,
                                       rect);
      
          m_editWnd.GetWindowRect(editrect);
          ScreenToClient(editrect);
      
          //block text redraw of the subitems text (underneath the
          //editcontrol)
          //if we didn't do this and deleted some text in the edit
          //control, the subitems original label would show
          if (editrect.right < rect.right)
            {
            rect.left = editrect.right ;
            ValidateRect(rect);
            }
      
          //block filling redraw of leftmost item (caused by FillRect)
          GetListCtrl().GetItemRect(m_item,rect,LVIR_LABEL );
          ValidateRect(rect);
          }
      
        CListView::OnPaint();
      }
      
    6. Handle resizing
      void CSubeditListView::OnSize(UINT nType, int cx, int cy)
      {
        //stop editing if resizing
        if( GetFocus() != this ) SetFocus();
      
        CListView::OnSize(nType, cx, cy);
      
      }
      
    7. Handle OnEndLabelEdit
      void CSubeditListView::OnEndLabelEdit(NMHDR* pNMHDR,
                                            LRESULT* pResult)
      {
        LV_DISPINFO *plvDispInfo = (LV_DISPINFO *)pNMHDR;
        LV_ITEM  *plvItem = &plvDispInfo->item;
      
        //if (end of sub-editing) do cleanup
        if (m_subitem)
          {
          //plvItem->pszText is NULL if editing canceled
          if (plvItem->pszText != NULL )
            GetListCtrl().SetItemText(plvItem->iItem,m_subitem,
                plvItem->pszText);
      
          VERIFY(m_editWnd.UnsubclassWindow()!=NULL);
      
          m_subitem = 0;
          //always revert to org label (Windows thinks we are editing
          //the leftmost item)
          *pResult = 0;
          }
        else
          //return: update label on leftmost item
          *pResult = 1;
      
      }
      

    Downloads

    Download exe - 10 Kb
    Download source - 40 Kb

    IT Offers


    Top Authors