如下图的实现效果:
定义的主要变量如下:
CString strSelectMoveCaseColumn = "";//当前选择的可移动操作列的名称 SList selectCaseColumnList;//也可以使用系统提供的CList链表实现 CButton* pCheckBoxButton;//动态生成的复选按钮指针 CButton* pRadioButton;//动态生成的单选按钮指针 CString allCaseColumnArr[15];//所有病例列名称数组 CMap<CString, LPCTSTR, int, int> caseColumnWidthDic;//所有的病例列宽度的字典集合 CListCtrlCl m_list_caseSetSelect;//已经扩展的列表控件
其中SList为自定义的链表类,实现选择列的保存、移动、查找等操作。该类下面给出具体实现:
// SList.h: interface for the SList class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_SLIST_H__E5586ECB_C639_4861_8A14_7AFFA8E85DA4__INCLUDED_) #define AFX_SLIST_H__E5586ECB_C639_4861_8A14_7AFFA8E85DA4__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef ALTSTR_H #define ALTSTR_H #include <atlstr.h> #endif // !ALTSTR_H class SList { struct Node { CString data; Node *next; }; Node *head,*tail,*current,*prior; public: SList(); virtual ~SList(); bool Move(long i); void ClearList(); bool SetData(CString e); bool GetData(CString &e); bool GetData(long i, CString &e); long ListLength(); bool IsEmpty(); bool InsList(long i, CString e); bool DelList(long i); bool Locate(CString e); long Search(CString e);//查找字符串e的位置,如果找到了,返回其在链表中的位置值(元素位置的开始值为1),如果没有找到,返回值为-1 bool Move(long pos, int times, bool bMoveHeadDirection);//pos为移动元素的位置;times为移动的次数;bMoveHeadDirection为移动的方向,值为true时表示向链表的头部移动,为false时表示向链表的尾部移动;返回值为true时表示移动成功,值为false时表示移动失败。 bool MoveToHead(long pos);//pos为移动元素的位置,将此元素移动到链表的头部。 bool MoveToTail(long pos);//pos为移动元素的位置,将此元素移动到链表的尾部。 int Print(long i); void AppList(CString e); }; #endif // !defined(AFX_SLIST_H__E5586ECB_C639_4861_8A14_7AFFA8E85DA4__INCLUDED_)
// SList.cpp: implementation of the SList class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "SList.h" #include <stdio.h> #include<iostream> using namespace std; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// SList::SList() { head = tail = current = prior = NULL; } SList::~SList() { ClearList(); } void SList::AppList(CString e)//从链表的尾部插入值为e的结点 { Node *pn; pn = new Node; pn->data = e; pn->next = NULL; if (tail == NULL) //链表为空时 { head = tail = pn; } else { tail->next = pn; //pn为链表尾 tail = pn; } } int SList::Print(long i) //输出第i个结点的值 { Node *p = NULL, *q = NULL; int j = 1; if (IsEmpty() || i <= 0)return false;//链表为空或i不合法 p = head; while (p != NULL&&j < i)//头结点的下一个结点不空 { q = p; p = p->next; j++; //指针依次向后移动直至到达i结点 } if (p != NULL) //i结点的值不空时才输出 { current = p; //更新current结点 prior = q; //更新prior结点 cout << p->data << " "; } else return 1; //不成功返回1 } bool SList::Locate(CString e) //如果链表中有包含数据项e的结点, { //则将当前指针指向该结点,成功返回真 Node *p = NULL, *q = NULL; //定义两个结点 if (IsEmpty()) { return false;//链表为空或i值不合法 } p = head; while (p != NULL&&p->data != e)//while循环,使p移动到数据项为e的结点 { q = p; p = p->next; } if (p != NULL) //p不为空,即找到了数据项为e的结点 { current = p; prior = q; return true; } else { return false; } } //查找字符串e的位置,如果找到了,返回其在链表中的位置值(元素位置的开始值为1),如果没有找到,返回值为-1 long SList::Search(CString e) //如果链表中有包含数据项e的结点, { long retPos = -1; //则将当前指针指向该结点,返回其在链表中的位置值,如果没有找到,返回值为-1 if (IsEmpty()) { retPos = -1; return retPos;//链表为空或i值不合法 } retPos = 1; Node *p = NULL, *q = NULL; //定义两个结点 p = head; while (p != NULL&&p->data != e)//while循环,使p移动到数据项为e的结点 { q = p; p = p->next; retPos++; } if (p != NULL) //p不为空,即找到了数据项为e的结点 { current = p; prior = q; } else { retPos = -1; } p = q = NULL; return retPos; } //pos为移动元素的位置;times为移动的次数;bMoveHeadDirection为移动的方向,值为true时表示向链表的头部移动,为false时表示向链表的尾部移动;返回值为true时表示移动成功,值为false时表示移动失败。 bool SList::Move(long pos, int times, bool bMoveHeadDirection) { bool bMoveResult = false; //则将当前指针指向该结点,返回其在链表中的位置值,如果没有找到,返回值为-1 if (IsEmpty()) { return bMoveResult;//链表为空 } if (Move(pos) == false) //移动到第pos个结点,即移动到pos位置 { return false;//移动到pos位置失败 } Node *p = NULL, *q = NULL; //定义两个结点 if (bMoveHeadDirection) { while (times > 0)//while循环,使p移动到数据项为e的结点 { p = current; if (p != NULL && prior != NULL) { if (pos > 2) { long listLength = ListLength(); q = prior; if (Move(pos - 1) == false) //移动到第pos-1个结点,即移动到pos-1位置 { return false;//移动到pos位置失败 } q->next = p->next; p->next = q; prior->next = p; current = p; if (pos == listLength) { //表示pos处于链表的尾部 q->next = NULL; tail = q; } } else { prior->next = current->next; current->next = prior; head = current; prior = NULL; } } times--; } } else { while (times > 0)//while循环,使p移动到数据项为e的结点 { p = current; long listLength = ListLength(); long posToTail = listLength - pos; if (posToTail > 0) { if (prior == NULL) { q = current->next; p->next = q->next; q->next = p; head = q; } else if (prior != NULL && p->next != NULL) { if (posToTail > 1) { q = current->next; p->next = q->next; q->next = p; prior->next = q; } else { if (posToTail == 1) { q = current->next; prior->next = q; q->next = p; p->next = NULL; tail = p; } } } if (Move(pos + 1) == false) //移动到第pos-1个结点,即移动到pos-1位置 { return false;//移动到pos位置失败 } } else { return false;//移动到pos位置失败 } times--; } } p = q = NULL; return true; } //pos为移动元素的位置,将此元素移动到链表的头部。 bool SList::MoveToHead(long pos) { bool bMoveResult = false; //则将当前指针指向该结点,返回其在链表中的位置值,如果没有找到,返回值为-1 if (IsEmpty()) { return bMoveResult;//链表为空 } if (Move(pos) == false) //移动到第pos个结点,即移动到pos位置 { return false;//移动到pos位置失败 } if (current != NULL && prior != NULL) { if (current->next != NULL) { if (pos > 1) { prior->next = current->next; current->next = head; head = current; prior = NULL; } } else { //表示当前移动的元素位于链表的尾部 prior->next = NULL; current->next = head; head = current; tail = prior; prior = NULL; } } return true; } //pos为移动元素的位置,将此元素移动到链表的尾部。 bool SList::MoveToTail(long pos) { bool bMoveResult = false; //则将当前指针指向该结点,返回其在链表中的位置值,如果没有找到,返回值为-1 if (IsEmpty()) { return bMoveResult;//链表为空 } if (Move(pos) == false) //移动到第pos个结点,即移动到pos位置 { return false;//移动到pos位置失败 } if (current != NULL) { if (prior != NULL) { prior->next = current->next; current->next = NULL; tail->next = current; tail = current; } else { head = current->next; current->next = NULL; tail->next = current; tail = current; } } return true; } bool SList::DelList(long i)//删除第i个结点,成功返回真 { if (Move(i) == false) //移动到第i个结点 { return false; } if (prior != NULL) //不是头结点 { prior->next = current->next; if (current == tail)//在尾结点处 { prior->next = NULL; tail = prior; delete current; } else { delete current; } } else { head = current->next; delete current; } prior = current = NULL; //是头结点时 return true; } bool SList::InsList(long i, CString e)//在第i个结点处插入值为e的新结点,成功返回真 { Node *p; if (Move(i) == false) //移动到第i个结点 { return false; } p = new Node; //建立新结点 p->data = e; if (prior != NULL) //要插入的结点不是头结点 { prior->next = p; p->next = current; } else //要插入的结点是头结点 { head = p; p->next = current; } p = NULL; return true; } bool SList::GetData(CString &e)//获得当前指针指向的值,成功返回真 { if (current == NULL) { return false; } else { e = current->data; return true; } } bool SList::SetData(CString e)//修改当前指针指向结点的值为e,成功返回真 { if (current == NULL) { return false; } else { current->data = e; return true; } } bool SList::IsEmpty()//链表是否为空 { if (head == NULL) { return true; } return false; } long SList::ListLength()//计算表长 { long count = 0; Node *p; p = head; if (p != NULL) { count++; while (p != tail) { p = p->next; count++; } } p = NULL; return count; } bool SList::GetData(long i, CString &e)//获得链表中第i个元素的值,成功返回真 { if (Move(i) == false) { return false; } else { e = current->data; return true; } } void SList::ClearList()//置空表 { Node *p, *q; p = head; while (p != tail) { q = p; p = p->next; delete q; } p = q = NULL; head = tail = current = prior = NULL; } bool SList::Move(long i)//移动当前指针到第i个结点,成功返回真 { bool bMoveResult = false; Node *p = NULL, *q = NULL; int j = 1; if (IsEmpty() || i <= 0) { return bMoveResult; } else { if (i == 1) { current = head; bMoveResult = true; } else { p = head->next; j++;//添加j++,否则当前定位的指针向后面多移动了一个位置 while (p != NULL&&j < i) { q = p; p = p->next; j++; } if (p != NULL) { current = p; if (q == NULL) { prior = head; } else { prior = q; } bMoveResult = true; } else { bMoveResult = false; } } } p = q = NULL; return bMoveResult; }