【C++】把链表的单选变成多选,并取得选中项;
这C++MFC的树类型CtreeCtrl把链表的单选变成多选,并取得选中项实操
函数定义参考
参考:Clist的使用参考:https://blog.csdn.net/zengweicdut/article/details/8699402
MFC的树类型CtreeCtrl函数参考:http://www.360doc.com/content/16/0223/11/7023119_536640312.shtml
CTreeCtrl类的主要成员函数
CImageList* SetImageList(CImageList * pImageList,int nImageListType);
如果树节点需要显示图标时,则必须先创建一个CImageList类的对象,并为其添加多个图像组成一个图像序列,然后调用SetImageList函数为树形控件设置图像序列,在用InsertItem插入节点时传入所需图像在图像序列中的索引即可。后面的例子中会演示。参数pImageList为指向图像序列类CImageList的对象的指针,若为NULL则删除树形控件的所有图像。参数nImageListType指定图像序列的类型,可以是TVSIL_NORMAL(普通图像序列)或TVSIL_STATE(状态图像序列,用图像表示节点的状态)。
UINT GetCount( ) const;
获取树形控件中节点的数量。
DWORD_PTR GetItemData(HTREEITEM hItem) const;
获取树形控件中某个指定节点的附加32位数据。参数hItem为指定的树节点的句柄。
BOOL SetItemData(HTREEITEM hItem,DWORD_PTR dwData);
为树形控件中某个指定节点设置附加的32位数据。参数hItem同上,dwData为要设置的32位数据。
CString GetItemText(HTREEITEM hItem) const;
获取树形控件中某个指定节点的标签文本。参数hItem同上。返回值是包含标签文本的字符串。
BOOL SetItemText(HTREEITEM hItem,LPCTSTR lpszItem);
为树形控件中某个指定节点设置标签文本。参数hItem同上,lpszItem为包含标签文本的字符串的指针。
HTREEITEM GetNextSiblingItem(HTREEITEM hItem) const;
获取树形控件中某个指定节点的下一个兄弟节点。参数hItem同上。返回值是下一个兄弟节点的句柄。
HTREEITEM GetPrevSiblingItem(HTREEITEM hItem) const;
获取树形控件中某个指定节点的上一个兄弟节点。参数hItem同上。返回值是上一个兄弟节点的句柄。
HTREEITEM GetParentItem(HTREEITEM hItem) const;
获取树形控件中某个指定节点的父节点。参数hItem同上。返回值是父节点的句柄。
HTREEITEM GetRootItem( ) const;
获取树形控件根节点的句柄。
HTREEITEM GetSelectedItem( ) const;
获取树形控件当前选中节点的句柄。
BOOL DeleteAllItems( );
删除树形控件中的所有节点。删除成功则返回TRUE,否则返回FALSE。
BOOL DeleteItem(HTREEITEM hItem);
删除树形控件中的某个节点。参数hItem为要删除的节点的句柄。删除成功则返回TRUE,否则返回FALSE。
HTREEITEM InsertItem(LPCTSTR lpszItem,int nImage,int nSelectedImage,HTREEITEM hParent = TVI_ROOT,HTREEITEM hInsertAfter = TVI_LAST);
在树形控件中插入一个新节点。参数lpszItem为新节点的标签文本字符串的指针,参数nImage为新节点的图标在树形控件图像序列中的索引,参数nSelectedImage为新节点被选中时的图标在图像序列中的索引,参数hParent为插入节点的父节点的句柄,参数hInsertAfter为新节点的前一个节点的句柄,即新节点将被插入到hInsertAfter节点之后。
BOOL SelectItem(HTREEITEM hItem);
选中指定的树节点。参数hItem为要选择的节点的句柄。若成功则返回TRUE,否则返回FALSE。
操作思路
(看懂前辈的代码,找到实际控制的地方,先做备份然后对症修改)
- 设置多选
- 提取到多选的值,做一个链表放置
- 保存
- 调用
- 修改原来函数的逻辑问题
- 修改bug
(确定所有用到该函数的逻辑都没问题)
保存代码:
typedef CList<CSysUnit*,CSysUnit*&> CCSysUnitList;
LRESULT CSignalUnitPage::OnWizardNext()
{
// TODO: Add your specialized code here and/or call the base class
/*HTREEITEM hRootItem=m_TreeCtrl.GetRootItem();//获取树形控件根节点的句柄。
while(hRootItem)
{
hRootItem=m_TreeCtrl.GetNextSiblingItem(hRootItem); // 获取树形控件中某个指定节点的下一个兄弟节点。参数hItem同上。返回值是下一个兄弟节点的句柄。
}
*/
HTREEITEM hItem=m_TreeCtrl.GetSelectedItem();//获取树形控件当前选中节点的句柄
HTREEITEM hchildItem = m_TreeCtrl.GetChildItem(hItem);//取得首子项的句柄
for(int i=1;i<m_TreeCtrl.GetCount();i++)//获取树的数量
{
if(TRUE == m_TreeCtrl.GetCheck(hchildItem))//是否选中
{
int nIndex=m_TreeCtrl.GetItemData(hchildItem);//nIndex为该ID
CSysUnit* pSysUnit=m_pMainDoc->m_pUnitCfg->GetSysUnitFromIndex(nIndex);
ASSERT(pSysUnit);
CSignalSheet* pSheet=(CSignalSheet*)GetParent();
pSheet->m_pSysUnit=pSysUnit;
pSheet->m_pSysUnitlist.AddTail(pSysUnit);
}
hchildItem=m_TreeCtrl.GetNextSiblingItem(hchildItem); //下一个
}
曾经遇到的问题
- 问题:获取不到选中函数的值,每次循环一次就结束
解决:因为没有获取子项的句柄,直接对首项提取选中的值,会提取不到,需要先获取子项句柄,当然如果是多子项的递归获取话,在外面加一个循环就差不多了; - 问题:会一直报错winctrl2.cpp,
解决:循环用的i习惯性从零开始,但改为i=1就不会报错了,从结果看是循环多了一次; - 为做到完全兼用原类型CSysUnit*;所做的链表设置为了CList<CSysUnit*,CSysUnit*&>
调用代码:
POSITION posSysUnit = m_pSysUnitlist->GetHeadPosition();
while(posSysUnit)
{
//m_pSysUnit = m_pMainDoc->m_pSysUnitList.GetNext(posSysUnit);
m_pSysUnit = m_pSysUnitlist->GetNext(posSysUnit);
/*
……
*/
}
到调用的时候就简单很多了,简单的clist类型,拿出来替代掉原来的函数值,现在看来实在不太难,但写的时候各种内存错误,找不到适合用的函数等等。
插入一张图片,也是在这个地方设置多选

更多推荐
所有评论(0)