可编辑子项的ListCtrl
来源:互联网 发布:Win找mac共享文件 编辑:程序博客网 时间:2024/04/27 22:46
MFC提供的ListCtrl控件本身是不具备编辑子项功能的。
本文实现可以在ListCtrl中双击项Item出现编辑框和下拉列表框的编辑功能。
如下图所示:
源代码下载
示例程序下载
源代码中包含六个以下文件:
1. EditableListCtrl.h
2. EditableListCtrl.cpp
3. ListCtrlEdit.h
4. ListCtrlEdit.cpp
5. ListCtrlCombo.h
6. ListCtrlCombo.cpp
使用时,直接#include “EditableListCtrl.h”即可。
直接贴上源码:
[EditableListCtrl.h]
#pragma once#include "ListCtrlEdit.h"#include "ListCtrlCombo.h"#include <string>#include <list>#include <map>using std::string;using std::list;using std::map;// CEditableListCtrlenum ColumnCtrlType{ CCT_NONE = 0, CCT_COMBOBOX, CCT_EDITBOX};class CEditableListCtrl;typedef void (*EditableListCtrlItemValueUpdateAftFunc)( CWnd* pParent, CEditableListCtrl *pEditableListCtrl, int iItem, int iSubItem);class CEditableListCtrl : public CListCtrl{ DECLARE_DYNAMIC(CEditableListCtrl)public: CEditableListCtrl(); virtual ~CEditableListCtrl();protected: DECLARE_MESSAGE_MAP() 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); afx_msg void VScroll(UINT nSBCode, UINT nPos); afx_msg LRESULT OnEditEnd(WPARAM wParam,LPARAM lParam); afx_msg LRESULT OnComboEnd(WPARAM wParam,LPARAM lParam); void ShowEdit(bool bShow, int nItem, int nSubItem, CRect rcCtrl); void ShowCombo(bool bShow, int nItem, int nSubItem, CRect rcCtrl);public: // 设置列控件的类型 void SetColumnCtrlType(int nColumn, ColumnCtrlType ctrlType); // 设置列控件Combox的值 void SetColumnComboValue(int nColumn, list<string>& lstValue); // 设置项更新后回调函数 void SetItemUpdateAftCallBackFunc(EditableListCtrlItemValueUpdateAftFunc func);private: CListCtrlEdit m_edit; CListCtrlCombo m_combo; int nItem; // 当前点击项 int nSubItem; // 当前点击子项 bool m_bEditVisible; // Edit是否可见 bool m_bComboVisible; // ComboBox是否可见 map<int, ColumnCtrlType> m_Col2CtrlType; map<int, list<string> > m_Col2ComboValue; EditableListCtrlItemValueUpdateAftFunc m_ItemValueUpdateAftFunc;};
[EditableListCtrl.cpp]
// EditableListCtrl.cpp : implementation file//#include "stdafx.h"#include "EditableListCtrl.h"// CEditableListCtrlIMPLEMENT_DYNAMIC(CEditableListCtrl, CListCtrl)CEditableListCtrl::CEditableListCtrl() : m_bEditVisible(false), m_bComboVisible(false), nItem(-1), nSubItem(-1), m_ItemValueUpdateAftFunc(NULL){}CEditableListCtrl::~CEditableListCtrl(){}void CEditableListCtrl::SetColumnCtrlType(int nColumn, ColumnCtrlType ctrlType){ m_Col2CtrlType[nColumn] = ctrlType;}void CEditableListCtrl::SetColumnComboValue(int nColumn, list<string>& lstValue){ m_Col2ComboValue[nColumn].clear(); list<string>::iterator iterValue = lstValue.begin(); for (; iterValue != lstValue.end(); ++iterValue) { m_Col2ComboValue[nColumn].push_back(*iterValue); }}void CEditableListCtrl::SetItemUpdateAftCallBackFunc(EditableListCtrlItemValueUpdateAftFunc func){ m_ItemValueUpdateAftFunc = func;}void CEditableListCtrl::ShowEdit(bool bShow, int nItem, int nSubItem, CRect rcCtrl){ 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); m_bEditVisible = false; m_edit.SetFont(this->GetFont()); } if (bShow == TRUE) { CString cstrItem = GetItemText(nItem, nSubItem); m_edit.MoveWindow(&rcCtrl); m_edit.ShowWindow(SW_SHOW); m_bEditVisible = true; m_edit.SetWindowText(cstrItem); m_edit.SetFocus(); m_edit.SetSel(-1); } else { m_edit.ShowWindow(SW_HIDE); m_bEditVisible = false; }}void CEditableListCtrl::ShowCombo(bool bShow, int nItem, int nSubItem, CRect rcCtrl){ 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); m_bComboVisible = false; m_combo.SetFont(this->GetFont()); } if (bShow == TRUE && !m_Col2ComboValue[nSubItem].empty()) { CString cstrItem = GetItemText(nItem, nSubItem); rcCtrl.bottom += 100; m_combo.MoveWindow(&rcCtrl); m_combo.ShowWindow(SW_SHOW); m_bComboVisible = true; m_combo.SetWindowText(cstrItem); m_combo.SetFocus(); m_combo.ResetContent(); list<string>::iterator iterValue = m_Col2ComboValue[nSubItem].begin(); for (; iterValue != m_Col2ComboValue[nSubItem].end(); ++iterValue) { m_combo.AddString(iterValue->c_str()); } m_combo.SetCurSel(-1); 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; } } } else { m_combo.ShowWindow(SW_HIDE); m_bComboVisible = false; }}BEGIN_MESSAGE_MAP(CEditableListCtrl, CListCtrl) ON_WM_LBUTTONDBLCLK() ON_NOTIFY(HDN_BEGINTRACKA, 0, &CEditableListCtrl::OnHdnBegintrack) ON_NOTIFY(HDN_BEGINTRACKW, 0, &CEditableListCtrl::OnHdnBegintrack) ON_WM_HSCROLL() ON_WM_VSCROLL() ON_MESSAGE(WM_USER_EDIT_END, OnEditEnd) ON_MESSAGE(WM_USER_COMBO_END, OnComboEnd)END_MESSAGE_MAP()// CEditableListCtrl message handlersLRESULT CEditableListCtrl::OnEditEnd(WPARAM wParam, LPARAM lParam){ CString strText; m_edit.GetWindowText(strText); SetItemText(nItem,nSubItem,strText); if (m_ItemValueUpdateAftFunc != NULL) { (*m_ItemValueUpdateAftFunc)(this->GetParent(), this, nItem, nSubItem); } ShowEdit(false, -1, -1, CRect()); return 0;}LRESULT CEditableListCtrl::OnComboEnd(WPARAM wParam, LPARAM lParam){ int nSel = m_combo.GetCurSel(); if (nSel != -1) { CString cstrTextSel; m_combo.GetLBText(nSel, cstrTextSel); SetItemText(nItem, nSubItem, cstrTextSel); if (m_ItemValueUpdateAftFunc != NULL) { (*m_ItemValueUpdateAftFunc)(this->GetParent(), this, nItem, nSubItem); } } ShowCombo(false, -1, -1, CRect()); return 0;}void CEditableListCtrl::OnLButtonDblClk(UINT nFlags, CPoint point){ // TODO: Add your message handler code here and/or call default LVHITTESTINFO lvhti; lvhti.pt = point; nItem = SubItemHitTest(&lvhti); if (nItem == -1) { return; } nSubItem = lvhti.iSubItem; ColumnCtrlType colCtrlType = CCT_NONE; if (m_Col2CtrlType.find(nSubItem) == m_Col2CtrlType.end()) { return; } else { colCtrlType = m_Col2CtrlType[nSubItem]; } CRect rcCtrl; GetSubItemRect(nItem, nSubItem, LVIR_LABEL, rcCtrl); switch (colCtrlType) { case CCT_NONE: break; case CCT_EDITBOX: ShowEdit(TRUE, nItem, nSubItem, rcCtrl); break; case CCT_COMBOBOX: ShowCombo(TRUE, nItem, nSubItem, rcCtrl); break; default: break; } CListCtrl::OnLButtonDblClk(nFlags, point);}void CEditableListCtrl::OnHdnBegintrack(NMHDR *pNMHDR, LRESULT *pResult){ LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR); // TODO: Add your control notification handler code here if (m_edit.m_hWnd != NULL && m_bEditVisible) OnEditEnd(0, 0); if (m_combo.m_hWnd != NULL && m_bComboVisible) OnComboEnd(0, 0); *pResult = 0;}void CEditableListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar){ // TODO: Add your message handler code here and/or call default if (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 default if (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);}
[ListCtrlEdit.h]
#pragma once#define WM_USER_EDIT_END WM_USER+101// CListCtrlEditclass CListCtrlEdit : public CEdit{ DECLARE_DYNAMIC(CListCtrlEdit)public: CListCtrlEdit(); virtual ~CListCtrlEdit();protected: DECLARE_MESSAGE_MAP()public: afx_msg void OnKillFocus(CWnd* pNewWnd); afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);};
[ListCtrlEdit.cpp]
// ListCtrlEdit.cpp : implementation file//#include "stdafx.h"#include "ListCtrlEdit.h"// CListCtrlEditIMPLEMENT_DYNAMIC(CListCtrlEdit, CEdit)CListCtrlEdit::CListCtrlEdit(){}CListCtrlEdit::~CListCtrlEdit(){}BEGIN_MESSAGE_MAP(CListCtrlEdit, CEdit) ON_WM_KILLFOCUS() ON_WM_MOUSEWHEEL()END_MESSAGE_MAP()// CListCtrlEdit message handlersvoid CListCtrlEdit::OnKillFocus(CWnd* pNewWnd){ CEdit::OnKillFocus(pNewWnd); // TODO: Add your message handler code here CWnd *pParent = this->GetParent(); ::PostMessage(pParent->GetSafeHwnd(), WM_USER_EDIT_END, 0, 0);}BOOL CListCtrlEdit::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt){ CWnd *pParent = this->GetParent(); ::PostMessage(pParent->GetSafeHwnd(), WM_USER_EDIT_END, 0, 0); return CWnd::OnMouseWheel(nFlags, zDelta, pt);}
[ListCtrlCombo.h]
#pragma once#define WM_USER_COMBO_END WM_USER+102// CListCtrlComboclass CListCtrlCombo : public CComboBox{ DECLARE_DYNAMIC(CListCtrlCombo)public: CListCtrlCombo(); virtual ~CListCtrlCombo();protected: DECLARE_MESSAGE_MAP()public: afx_msg void OnKillFocus(CWnd* pNewWnd);};
[ListCtrlCombo.cpp]
// ListCtrlCombo.cpp : implementation file//#include "stdafx.h"#include "ListCtrlCombo.h"// CListCtrlComboIMPLEMENT_DYNAMIC(CListCtrlCombo, CComboBox)CListCtrlCombo::CListCtrlCombo(){}CListCtrlCombo::~CListCtrlCombo(){}BEGIN_MESSAGE_MAP(CListCtrlCombo, CComboBox) ON_WM_KILLFOCUS()END_MESSAGE_MAP()// CListCtrlCombo message handlersvoid CListCtrlCombo::OnKillFocus(CWnd* pNewWnd){ CComboBox::OnKillFocus(pNewWnd); // TODO: Add your message handler code here CWnd *pParent = this->GetParent(); ::PostMessage(pParent->GetSafeHwnd(), WM_USER_COMBO_END, 0, 0);}
0 0
- 可编辑子项的ListCtrl
- 可编辑子项的ListCtrl<二>
- 可编辑子项ListCtrl控件的完整实现
- win32快速实现listctrl控件的可编辑子项
- 可编辑的 ListCtrl 封装整合
- 使ListCtrl可编辑
- 使ListCtrl可编辑
- 可编辑子项的CListCtrl类
- 可编辑子项的CListCtrl类
- 可编辑子项的CListCtrl类
- 可编辑子项的CListCtrl类
- 可编辑子项的CListCtrl类
- 可编辑子项的CListCtrl类
- 可编辑子项的CListCtrl类
- 可编辑子项的CListCtrl类
- MFC-ListCtrl 可编辑重写
- MFC-ListCtrl 可编辑重写
- MFC-ListCtrl 可编辑重写
- 【Android】【开发环境】Android Studio 安装及使用
- List的操作,交差并
- cstring 查找字符串 expression incorrect format specifier,0解决办法
- Android的Notification研究
- OpenCV学习笔记(14):形态学滤波对图像进行边缘及角点检测
- 可编辑子项的ListCtrl
- Linux下Ctrl+D、Ctrl+C和Ctrl+Z的联系及区别
- Fragment基础使用
- libsvm交叉验证与网格搜索(参数选择)
- 领域模型、贫血模型
- mahout spectral聚类1
- 项目0:是春哥啊
- 职业规划
- java object之clone