可編輯子項ListCtrl控制項的完整實現

來源:互聯網
上載者:User

源碼下載:http://download.csdn.net/detail/wangyao1052/4604942
     

       MFC提供的ListCtrl控制項本身是不具備編輯子項功能的,我們現在建立一個可編輯子項的ListCtrl控制項用於記錄人員的名字、年齡、性別。其中,雙擊年齡項會出現EditBox讓使用者編輯修改年齡,雙擊性別項會出現ComboBox讓使用者選擇性別。

       實現如下:

       我們需要實現3個類:CEditableListCtrl繼承自CListCtrl,CListCtrlEdit繼承自CEdit,CListCtrlCombo繼承自CComboBox。CListCtrlEdit和CListCtrlCombo是CEditableListCtrl要用到的EditBox和ComboBox控制項的類,這兩個類非常簡單,就是在失去焦點時向父視窗CEditableListCtrl發送訊息通知。

一、CEditableListCtrl

注意新增部分

class CEditableListCtrl : public CListCtrl{DECLARE_DYNAMIC(CEditableListCtrl)public:CEditableListCtrl();virtual ~CEditableListCtrl();protected:DECLARE_MESSAGE_MAP()//-----------------新增部分----------------------public:afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);afx_msg void OnHdnBegintrack(NMHDR *pNMHDR, LRESULT *pResult);afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);public:void ShowEdit(bool bShow, int nItem, int nSubItem, CRect rcCtrl);void ShowCombo(bool bShow, int nItem, int nSubItem, CRect rcCtrl);afx_msg LRESULT OnEditEnd(WPARAM wParam,LPARAM lParam);afx_msg LRESULT OnComboEnd(WPARAM wParam,LPARAM lParam);private:CListCtrlEdit m_edit;CListCtrlCombo m_combo;int nItem;         // 當前點擊項int nSubItem;            // 當前點擊子項bool m_bEditVisible;     // Edit是否可見bool m_bComboVisible;    // ComboBox是否可見};

1、滑鼠雙擊訊息WM_LBUTTONDBLCLK

如果雙擊的是年齡項就顯示EditBox供使用者編輯修改,如果雙擊的是性別項就顯示ComboBox供使用者選擇修改。

void CEditableListCtrl::OnLButtonDblClk(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultCRect rcCtrl;LVHITTESTINFO lvhti;lvhti.pt = point;nItem = SubItemHitTest(&lvhti);if (nItem == -1) return;nSubItem = lvhti.iSubItem;GetSubItemRect(nItem, nSubItem, LVIR_LABEL, rcCtrl);if (lvhti.iSubItem == 1)ShowEdit(TRUE, nItem, nSubItem, rcCtrl);else if (lvhti.iSubItem == 2)ShowCombo(TRUE, nItem, nSubItem, rcCtrl);CListCtrl::OnLButtonDblClk(nFlags, point);}

2、開始拖動表頭訊息HDN_BEGINTRACKA

響應EditBox和ComboBox失去焦點的事件

void CEditableListCtrl::OnHdnBegintrack(NMHDR *pNMHDR, LRESULT *pResult){LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);// TODO: Add your control notification handler code hereif (m_edit.m_hWnd != NULL && m_bEditVisible)OnEditEnd(0, 0);if (m_combo.m_hWnd != NULL && m_bComboVisible)OnComboEnd(0, 0);*pResult = 0;}

3、水平與垂直捲軸拖動事件

響應EditBox和ComboBox失去焦點的事件

void CEditableListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar){// TODO: Add your message handler code here and/or call defaultif (m_edit.m_hWnd != NULL && m_bEditVisible)OnEditEnd(0, 0);if (m_combo.m_hWnd != NULL && m_bComboVisible)OnComboEnd(0, 0);CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);}void CEditableListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar){// TODO: Add your message handler code here and/or call defaultif (m_edit.m_hWnd != NULL && m_bEditVisible)OnEditEnd(0, 0);if (m_combo.m_hWnd != NULL && m_bComboVisible)OnComboEnd(0, 0);CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);}

4、ComboBox與EditBox失去焦點響應

CListCtrlEdit類和CListCtrlCombo類中,在失去焦點時會向父視窗發送自訂訊息,以下訊息處理函數就是用於處理這兩個訊息。

#define WM_USER_EDIT_END  WM_USER+101
#define WM_USER_COMBO_END WM_USER+102

ON_MESSAGE(WM_USER_EDIT_END, OnEditEnd)
ON_MESSAGE(WM_USER_COMBO_END, OnComboEnd)

LRESULT CEditableListCtrl::OnEditEnd(WPARAM wParam, LPARAM lParam){    CString strText;    m_edit.GetWindowText(strText);    SetItemText(nItem,nSubItem,strText);    ShowEdit(false, -1, -1, CRect());     return 0;}LRESULT CEditableListCtrl::OnComboEnd(WPARAM wParam, LPARAM lParam){    int nSel = m_combo.GetCurSel();    CString cstrTextSel;    m_combo.GetLBText(nSel, cstrTextSel);    SetItemText(nItem, nSubItem, cstrTextSel);    ShowCombo(false, -1, -1, CRect());     return 0;}

5、ShowEdit與ShowCombo

void CEditableListCtrl::ShowEdit(bool bShow, int nItem, int nSubItem, CRect rcCtrl){  m_bEditVisible = bShow;  if (m_edit.m_hWnd == NULL)  {  m_edit.Create(ES_AUTOHSCROLL | WS_CHILD | ES_LEFT | ES_WANTRETURN | WS_BORDER,CRect(0,0,0,0), this, 1001);      m_edit.ShowWindow(SW_HIDE);       CFont tpFont;      tpFont.CreateStockObject(DEFAULT_GUI_FONT);      m_edit.SetFont(&tpFont);      tpFont.DeleteObject();  }  if (bShow == TRUE)  {     CString cstrItem = GetItemText(nItem, nSubItem);     m_edit.MoveWindow(&rcCtrl);     m_edit.ShowWindow(SW_SHOW);     m_edit.SetWindowText(cstrItem);     m_edit.SetFocus();     m_edit.SetSel(-1);   }  else      m_edit.ShowWindow(SW_HIDE);}void CEditableListCtrl::ShowCombo(bool bShow, int nItem, int nSubItem, CRect rcCtrl){m_bComboVisible = bShow;if (m_combo.m_hWnd == NULL){m_combo.Create(ES_AUTOHSCROLL | ES_AUTOVSCROLL | WS_CHILD | ES_LEFT | CBS_DROPDOWNLIST,CRect(0,0,0,0), this, 1002);m_combo.ShowWindow(SW_HIDE);CFont tpFont;tpFont.CreateStockObject(DEFAULT_GUI_FONT);m_combo.SetFont(&tpFont);tpFont.DeleteObject();m_combo.AddString(TEXT("Male"));m_combo.AddString(TEXT("Female"));}if (bShow == TRUE){m_combo.SetCurSel(-1);CString cstrItem = GetItemText(nItem, nSubItem);m_combo.MoveWindow(&rcCtrl);m_combo.ShowWindow(SW_SHOW);m_combo.SetWindowText(cstrItem);m_combo.SetFocus();int nItems = m_combo.GetCount();for (int i=0; i<nItems; ++i){CString cstrItemText;m_combo.GetLBText(i, cstrItemText);if (cstrItem == cstrItemText){m_combo.SetCurSel(i);break;}}}elsem_combo.ShowWindow(SW_HIDE);}

二、CListCtrlEdit

class CListCtrlEdit : public CEdit{DECLARE_DYNAMIC(CListCtrlEdit)public:CListCtrlEdit();virtual ~CListCtrlEdit();protected:DECLARE_MESSAGE_MAP()public:afx_msg void OnKillFocus(CWnd* pNewWnd);};

失去焦時間點事件

void CListCtrlEdit::OnKillFocus(CWnd* pNewWnd){CEdit::OnKillFocus(pNewWnd);// TODO: Add your message handler code hereCWnd *pParent = this->GetParent();::PostMessage(pParent->GetSafeHwnd(), WM_USER_EDIT_END, 0, 0);}

三、CListCtrlCombo

class CListCtrlCombo : public CComboBox{DECLARE_DYNAMIC(CListCtrlCombo)public:CListCtrlCombo();virtual ~CListCtrlCombo();protected:DECLARE_MESSAGE_MAP()public:afx_msg void OnKillFocus(CWnd* pNewWnd);};

失去焦時間點事件

void CListCtrlCombo::OnKillFocus(CWnd* pNewWnd){CComboBox::OnKillFocus(pNewWnd);// TODO: Add your message handler code hereCWnd *pParent = this->GetParent();::PostMessage(pParent->GetSafeHwnd(), WM_USER_COMBO_END, 0, 0);}

效果如下

參考文章:

http://blog.csdn.net/lixiaomin_235/article/details/4096885

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.