网上有关clistctrl举不胜举,包括按钮控件的绘制也很多,但我用的时候找了好久没发现适合我用的。在这里我想介绍一种很简洁的+、-号按钮绘制的方法,实现后类似于tree中的+、-号收缩功能。以便同行以后有需要可以直接搬走使用。
依附点:clistctrl用的最多的setitemdata,setitemtext,可以记录一些信息,但这里通过setitemstate来记录与修改图标的状态,从而实现+、-号的按钮。
问题:你可能说为什么不绘制一个+号按钮呢?红色部分代码是绘制了一个+号按钮,但很难看,另外你单击时候还要改变成-号,这可能也许能实现,但我想其中你做的这些工作的时间足够你用这种方法做了好几遍了。
1.说是按钮,其实这里采用了图标的方式,你可以用vc自带的工具,也可以用ARTICONS工具,首先绘制两个图标,+、-号.INDEXTOSTATEIMAGEMASK这个宏来把你图标的索引号 进行转变。
2.在inidlg函数中创建图表,并保存+、-号图标。贴代码
BOOL CTest_listcheckDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CWinApp *pApp = AfxGetApp();
m_pImageLarge = new CImageList();
ASSERT(m_pImageLarge != NULL); // serious allocation failure checking
m_pImageLarge->Create(24, 24, TRUE, 100, 4);
//m_pImageLarge->Create(32, 32, TRUE, 100, 4);
//+图标
m_pImageLarge->Add(pApp->LoadIcon(IDI_ICON5));//+号
m_pImageLarge->Add(pApp->LoadIcon(IDI_ICON4));//-号
m_list.SetImageList(m_pImageLarge, LVSIL_SMALL);
// TODO: Add extra initialization here
m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_SORTASCENDING|LVS_TYPEMASK);
m_list.InsertColumn(0,"关注类型",LVCFMT_CENTER, 90);
m_list.InsertColumn(1,"名称",LVCFMT_CENTER, 90);
int i=0;
int index=m_list.InsertItem(i++,"1",0);
// int index=m_list.InsertItem(LVIF_TEXT|LVIF_IMAGE,i++, "1",0, 0, i,NULL);
m_list.SetItemData(index,i);
m_list.SetItemState(index,INDEXTOSTATEIMAGEMASK(0),TVIS_STATEIMAGEMASK);
// CRect rect;
// m_list.GetSubItemRect( index, 0, LVIR_ICON, rect );
// m_btn.Create("+", BS_LEFTTEXT|WS_CHILD , rect, FromHandle(m_list.m_hWnd), 1);
// m_btn.MoveWindow(rect,1);
// m_btn.ShowWindow(TRUE);
index=m_list.InsertItem(i++,"2",0);
m_list.SetItemData(index,i);
m_list.SetItemState(index,INDEXTOSTATEIMAGEMASK(0),TVIS_STATEIMAGEMASK);
index=m_list.InsertItem(i++,"3",0);
m_list.SetItemData(index,i);
m_list.SetItemState(index,INDEXTOSTATEIMAGEMASK(0),TVIS_STATEIMAGEMASK);
index=m_list.InsertItem(i++,"4",0);
m_list.SetItemData(index,i);
m_list.SetItemState(index,INDEXTOSTATEIMAGEMASK(0),TVIS_STATEIMAGEMASK);
index=m_list.InsertItem(i++,"5",-1);
m_list.SetItemData(index,i);
m_list.SetItemState(index,INDEXTOSTATEIMAGEMASK(-1),TVIS_STATEIMAGEMASK);
return TRUE; // return TRUE unless you set the focus to a control
}
3.单击+、-号的分别处理消息,单击+号则插入你需要的记录,单击-号则删除下面的记录,贴代码:
void CTest_listcheckDlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
UINT flags(0);
CPoint pt;
GetCursorPos(&pt);
m_list.ScreenToClient(&pt);
int index=m_list.HitTest(pt,&flags);
if (-1!=index)
{
CRect rect;
m_list.GetSubItemRect(index,0,LVIR_ICON,rect);
if(rect.PtInRect(pt))
{
//if 是+号,1.更换图标为-号。2.根据index的data查询数据库,在本index下面插入查询结果。
//if 是-号,1.更换图标为+号。2.判断下一行是否有图表,将无图标的都删除掉。直到有图表的列为止。
//AfxMessageBox("您点击了图标,请更换");
int result= m_list.GetItemState(index,TVIS_STATEIMAGEMASK);
int stateindex=result>>12;
if (0==stateindex)//是+号
{
stateindex=1;
m_list.SetItem( index, 0, LVIF_IMAGE, NULL, stateindex, 0, 0, 0 );
m_list.SetItemState(index,INDEXTOSTATEIMAGEMASK(stateindex),TVIS_STATEIMAGEMASK);
for (int i=0;i<3;i++)
{
CString str;
str.Format("test %d",i);
int dd=m_list.InsertItem(index+1,str,-1);
m_list.SetItemData(dd,-1);
m_list.SetItemState(dd,INDEXTOSTATEIMAGEMASK(-1),TVIS_STATEIMAGEMASK);
}
}
else if (1==stateindex)//是-号.
{
stateindex=0;
m_list.SetItem( index, 0, LVIF_IMAGE, NULL, stateindex, 0, 0,0);
m_list.SetItemState(index,INDEXTOSTATEIMAGEMASK(stateindex),TVIS_STATEIMAGEMASK);
int dd=m_list.GetNextItem(index,LVNI_BELOW );
while (-1!=dd)
{
int result= m_list.GetItemState(dd,TVIS_STATEIMAGEMASK);
int mask=result>>12;
if ((mask!=0 )&&(mask!=1))
m_list.DeleteItem(dd);
else
break;
}
}
//状态的改变以及图标索引的设置.
}
}
*pResult = 0;
}
希望对项目紧又没时间研究的人给予 一定的帮助。![](https://i-blog.csdnimg.cn/blog_migrate/0669e94233c77bd6dac7058d51e3412f.gif)