如下图的实现效果:

定义的主要变量如下:
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;
}