wtl中提供了一个很好用的控件CCheckListViewCtrl,这个控件在listviewctrl的report模式的每一行的前面增加了一个CheckBox,注意这个控件只用于listviewctrl的report模式,至于为什么,我们后面会讲到这个问题。下面我们将一下这个控件的用法。

1、像其他控件一样,首先,你需要在dlg里面声明一个CCheckListViewCtrl的对象。

CCheckListViewCtrl m_listCtrl

2、跟控件进行关联及插入数据:

m_lst.SubclassWindow(GetDlgItem(IDC_LIST1).m_hWnd); m_lst.InsertColumn(0, _T("test1"), LVCFMT_LEFT, 100); m_lst.InsertItem(0, _T("item1")); m_lst.InsertItem(0, _T("item2")); m_lst.SetItemText(0, 0, _T("1")); m_lst.SetItemText(1, 0, _T("2"));

运行看看,是不是已经看到效果啦^^

3、处理点击消息,这个消息共用了LVN_ITEMCHANGED消息,我们需要加入消息处理:

NOTIFY_HANDLER(IDC_LIST1, LVN_ITEMCHANGED, OnLvnItemchangedList1)

再加入消息处理的函数(这段是从网上找来的):

LRESULT CMainDlg::OnLvnItemchangedList1(int /*idCtrl*/, LPNMHDR pNMHDR, BOOL& /*bHandled*/) { LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if (pNMListView-> uOldState == 0 && pNMListView-> uNewState == 0) return 0; // No change // Old check box state BOOL bPrevState = (BOOL)(((pNMListView-> uOldState & LVIS_STATEIMAGEMASK)>> 12)-1); if (bPrevState < 0) // On startup there 's no previous state bPrevState = 0; // so assign as false (unchecked) // New check box state BOOL bChecked = (BOOL)(((pNMListView-> uNewState & LVIS_STATEIMAGEMASK)>> 12)-1); if (bChecked < 0) // On non-checkbox notifications assume false bChecked = 0; if (bPrevState == bChecked) // No change in check box return 0; else { MessageBox(_T(""), _T("")); } return 0; }

再试试,看到效果了吧,下面我们讲解一下这个类的实际构成,这里直接摘抄了wtl的源码,加上注释而来

template <DWORD t_dwStyle, DWORD t_dwExStyle, DWORD t_dwExListViewStyle> class CCheckListViewCtrlImplTraits { public: static DWORD GetWndStyle(DWORD dwStyle) { return (dwStyle == 0) ? t_dwStyle : dwStyle; } static DWORD GetWndExStyle(DWORD dwExStyle) { return (dwExStyle == 0) ? t_dwExStyle : dwExStyle; } static DWORD GetExtendedLVStyle() { return t_dwExListViewStyle; } }; /* 这里定义了这个控件的属性,里面已经加入了LVS_REPORT,LVS_EX_CHECKBOXES属性指定了该类有一个checkBox,在SubClass的时候会对控件的属性进行修改,另外动态创建的时候会用到该属性,所以说这个类只用于报表模式 */ typedef CCheckListViewCtrlImplTraits<WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT> CCheckListViewCtrlTraits; /*下面是该类具体实现*/ template <class T, class TBase = CListViewCtrl, class TWinTraits = CCheckListViewCtrlTraits> class ATL_NO_VTABLE CCheckListViewCtrlImpl : public ATL::CWindowImpl<T, TBase, TWinTraits> { public: DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) // Attributes static DWORD GetExtendedLVStyle() { return TWinTraits::GetExtendedLVStyle(); } // Operations BOOL SubclassWindow(HWND hWnd) { #if (_MSC_VER >= 1300) BOOL bRet = ATL::CWindowImplBaseT< TBase, TWinTraits>::SubclassWindow(hWnd); #else // !(_MSC_VER >= 1300) typedef ATL::CWindowImplBaseT< TBase, TWinTraits> _baseClass; BOOL bRet = _baseClass::SubclassWindow(hWnd); #endif // !(_MSC_VER >= 1300) //这里对控件的属性进行修改 if(bRet) { T* pT = static_cast<T*>(this); pT; ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0); SetExtendedListViewStyle(pT->GetExtendedLVStyle()); } return bRet; } void CheckSelectedItems(int nCurrItem) { // first check if this item is selected LVITEM lvi = { 0 }; lvi.iItem = nCurrItem; lvi.iSubItem = 0; lvi.mask = LVIF_STATE; lvi.stateMask = LVIS_SELECTED; GetItem(&lvi); // if item is not selected, don't do anything if(!(lvi.state & LVIS_SELECTED)) return; // new check state will be reverse of the current state, BOOL bCheck = !GetCheckState(nCurrItem); int nItem = -1; int nOldItem = -1; while((nItem = GetNextItem(nOldItem, LVNI_SELECTED)) != -1) { if(nItem != nCurrItem) SetCheckState(nItem, bCheck); nOldItem = nItem; } } // Implementation BEGIN_MSG_MAP(CCheckListViewCtrlImpl) MESSAGE_HANDLER(WM_CREATE, OnCreate) MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDown) MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) END_MSG_MAP() LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) { // first let list view control initialize everything LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); T* pT = static_cast<T*>(this); pT; ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0); SetExtendedListViewStyle(pT->GetExtendedLVStyle()); return lRet; } /*这里两个函数都判断是否ctrl按下,对多选进行处理。*/ LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) { POINT ptMsg = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; LVHITTESTINFO lvh = { 0 }; lvh.pt = ptMsg; if(HitTest(&lvh) != -1 && lvh.flags == LVHT_ONITEMSTATEICON && ::GetKeyState(VK_CONTROL) >= 0) { T* pT = static_cast<T*>(this); pT->CheckSelectedItems(lvh.iItem); } bHandled = FALSE; return 1; } LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) { if(wParam == VK_SPACE) { int nCurrItem = GetNextItem(-1, LVNI_FOCUSED); if(nCurrItem != -1 && ::GetKeyState(VK_CONTROL) >= 0) { T* pT = static_cast<T*>(this); pT->CheckSelectedItems(nCurrItem); } } bHandled = FALSE; return 1; } }; class CCheckListViewCtrl : public CCheckListViewCtrlImpl<CCheckListViewCtrl> { public: DECLARE_WND_SUPERCLASS(_T("WTL_CheckListView"), GetWndClassName()) };

WTL CCheckListViewCtrl详解及示例相关推荐

  1. 百度PaddleOCR及云平台OCR API详解及示例

    百度PaddleOCR及云平台OCR API详解及示例 目录 百度PaddleOCR及云平台OCR API详解及示例 使用百度开源的PaddleOCR 多个开源代码库比较

  2. Oracle创建表语句(Create table)语法详解及示例

    Oracle创建表语句(Create table)语法详解及示例   创建表(Create table)语法详解 1. ORACLE常用的字段类型ORACLE常用的字段类型有 VARCHAR2 (si ...

  3. Math 的 ceil、floor、round方法详解及示例

    Math 的 ceil.floor.round方法详解及示例 大家好,我是酷酷的韩~ 一.Math.ceil() ceil的英文意义是天花板,该方法就表示向上取整(取大),Math.ceil(9.1) ...

  4. 31.进程管理之进程概览,及ps命令详解,ps -ef,ps aux,ps -le,ps -l输出详解和示例

    本小章讲解进程管理中的进程概览和作用,及ps命令详解,ps -ef,ps aux,ps -le,ps -l的输出详解和示例 文章目录 进程概览 什么是进程和程序 进程管理的作用 进程启动方式 僵尸进程 ...

  5. MySQL隔离级别--未提交读,提交读,可重复读,序列化--详解(有示例)

    原文网址:MySQL隔离级别--未提交读,提交读,可重复读,序列化--详解(有示例)_IT利刃出鞘的博客-CSDN博客 简介          本文介绍MySQL的事务隔离级别的含义,并用示例说明各个 ...

  6. lammps输出MSD(均方根位移)详解及示例教程

    [lammps第十五讲]lammps输出MSD(均方根位移)详解及示例教程 原创 一直陪着你的 LAMMPS交流站 2021-10-23 11:45 收录于话题 #lammps21个内容 #lammp ...

  7. Ehcache 中ehcache.xml 配置详解和示例

    EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. Ehcache是一种广泛使用的开源Java分布式缓存.主要面向通用缓存 ...

  8. BMP180气压传感器详解与示例(STM32 附带源码)

    BMP180气压传感器详解与示例(STM32 附带源码) 简介 工作模式 校准数值 测试流程 第一步:微处理器读取校准数值 第二步:读取温度.气压初始值 第三步:计算温度.气压 第四步:计算海拔高度 ...

  9. waitpid函数详解+应用示例

    来源:微信公众号「编程学习基地」 文章目录 waitpid函数的使用 waitpid()函数定义 参数详解 使用示例 waitpid函数的使用 当用fork启动一个新的子进程的时候,子进程就有了新的生 ...

最新文章

  1. Java IO 字节流与字符流 (三)
  2. JS字符串 window.open() window.opener window.name window对象总结
  3. mysql seq 重置_需要在Oracle中重置序列的值
  4. Eclipse安装 Activiti Designer插件
  5. Repeater嵌套绑定Repeater
  6. python双划线_Python中单下划线(_)和双下划线(__)的特殊用法
  7. python 标量_python:将标量视为一个元素列表
  8. 网站制作---asp操作数据库的一个小例子
  9. HTML标签悬浮到最下方,HTML – 如何在兄弟姐妹的悬停上显示元素?
  10. springcloud 图片和数据一起提交_SpringCloud网上商城系统(附源码及教程)
  11. 知乎高赞:985计算机视觉毕业后找不到工作怎么办?怒刷leetcode,还是另寻他路?...
  12. eclipse java machine_打开Eclipse弹出“No java virtual machine was found...的解决方法
  13. matlab:高斯函数对图像的空域滤波和频域滤波
  14. 中小型企业网络规划设计方案_实战:企业网络系统规划与设计与事项
  15. SREng日志全分析(一)
  16. 一些医学影像的成像原理
  17. xlsx文件 wps 可以打开 excel 打不开
  18. less 使用入门教程
  19. 人工智能——归结演绎推理
  20. HTML5 新的 Input 类型

热门文章

  1. phpcms默认模板目录解析
  2. postgresql 学习笔记
  3. 大数据培训技术 Cube和Cuboid
  4. Manjaro重启出现failed to start pkgfile database update
  5. JS截取URL中最后一个斜杆前(后)的内容
  6. 手机root后安装xposed框架后,如何启动云闪付?
  7. 第10课:利用Headers 的 cookie,实现爬取需要登录的网站信息
  8. nubia,无IMEI码(串号丢失)解救【转】
  9. 2020年这些正则应该被收藏(64条)
  10. 图像上色 (Image-Colorization) 项目