带有复选框的CListCtrl/CListView 的对checkbox的操作

设置ListView控件的Check Boxes状态

aawolf按:最近在项目里用到了ListView的这个属性,尽管这篇文章在MSDN里的评价并不是很高,但对于需要这种属性的工程还是比较好的指导材料。所以拿来和大家一同分享,希望大家继续关注我的专栏:http://www.csdn.net/develop/author/netauthor/aawolf/

What You Need

·                     Microsoft eMbedded Visual Tools 3.0

·                     Goodworking knowledge of Microsoft eMbedded Visual C++

Background

 

在设计一个用户界面时,你经常需要对一系列的选择给出一个可见的提示。这可以用不同的图标表示,或者使用一个Check Box控件。Pocket PC ListView控件提供内建的CheckBox功能(见图)。


Figure: Check boxes allow intuitive selection of ListView items.

在Pocket PC SDK中你会发现ListView中ListView_GetCheckState宏允许检查一个List Item的Check box状态。不幸的是,相应的ListView_SetCheckState宏没有被包含到Microsoft Visual C++的头文件中去,比如Pocket PC 2000 SDK和Pocket PC 2002 SDK当前的Beta版本。这个宏被包含到了平台SDK和MSDN的文档中。它将被添加到Pocket PC 2002 SDK的最终版本中。

如果你看一ListView_GetCheckState  commctrl.h中的定义,你将看到CheckBox状态被保存在12bit的Item data中。

 

#define ListView_GetCheckState(hwndLV, i) \

  ((((UINT)(SNDMSG((hwndLV), LVM_GETITEMSTATE, (WPARAM)i, LVIS_STATEIMAGEMASK)))>> 12) -1)

Adding the Missing Pieces

通过ListView_GetCheckState的逻辑,设置或者清空这个字将直接影响Check Box的状态,设置或者取消Check标志。因此,ListView_SetCheckState命令可以被跟踪实现。拷贝并粘贴这个宏到你的代码中,就可以使它工作。(aawolf:在Pocket PC 2002以上的SDK中已经包含了这个宏,直接使用就可以了)

 f为BOOL型

#ifndef ListView_SetCheckState

#define ListView_SetCheckState(h, i, f) \

        ListView_SetItemState(h, i,INDEXTOSTATEIMAGEMASK((f) + 1), LVIS_STATEIMAGEMASK)

#endif

注意INDEXTOSTATEIMAGEMASK将值移动12位。

#define INDEXTOSTATEIMAGEMASK(i) ((i) << 12)

Using the Checkboxes

为了使用ListView的Check Box,你需要设置LVS_EX_CHECKBOXES风格:

ListView_SetExtendedListViewStyle(hWndList, LVS_EX_CHECKBOXES);

该风格在List的第一列中留出足够的空间,并且在文字的前面画出Check Box。当你想设置Check Box时,你需要调用ListView_SetCheckState控制句柄、Item索引和期望的状态。

ListView_SetCheckState(hWndList,dwIndex, (bState ? 1 : 0));

同样,你可以通过调用ListView_GetCheckState来得到Check Box的状态:

ListView_GetCheckState(hWndList, dwIndex);

Conclusion

该功能的完整执行在最终的Pocket PC SDK中是有效的,这可以让你的程序通过很简单的方式得到视觉效果上的优势。


转载:http://www.moon-soft.com/doc/13766.htm



在MFC(Microsoft Foundation Classes)中,如果你自定义了`CListCtrl`的`DrawItem`函数来重绘列表控件项,可能会遇到第一列的复选框消失的问题。这通常是因为在自定义绘制过程中,没有正确处理复选框的绘制。 要解决这个问题,你需要在自定义的`DrawItem`函数中,对列表控件的每项进行绘制时,包含对复选框的绘制。这可以通过调用`DrawFrameControl`函数实现,该函数用于绘制复选框或其他类型的框架控件。 通常,复选框位于列表项的第一个子项(subitem),因此你需要在处理第一列时调用`DrawFrameControl`,设置适当的参数来绘制复选框。确保使用与`CListCtrl`的`SetItem`函数中相同的`itemID`和`subItem`参数。 示例代码片段如下: ```cpp void CYourListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // 检查绘制类型是否为ODT_LISTBOX,因为CListCtrl是基于CListBox的 if(lpDrawItemStruct->itemAction & ODA_DRAWENTIRE) { CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect rectItem; GetClientRect(&rectItem); // 设置背景颜色等 // ... // 设置第一列的复选框是否选中的状态 int itemState = GetItemState(lpDrawItemStruct->itemID, LVIS_SELECTED); if(itemState & LVIS_SELECTED) { // 绘制复选框 pDC->DrawFrameControl(&lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT); } else { // 绘制非选中的复选框或其他状态 pDC->DrawFrameControl(&lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONCHECK); } } // 绘制其他内容 // ... } ``` 确保在绘制复选框后,继续处理其他子项的绘制,并且正确使用`rectItem`和`lpDrawItemStruct->rcItem`矩形区域。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值