Moving Listbox Items Up and Down
For single or multiple selection CListBox
Introduction
After some search without success about doing up / down of CListbox
items (with multiple selection), here is my solution.
The code below is doing roll up/down: First item goes to last position on UP; last item goes to first position on DOWN.
Using the Code
Insert the 2 files in your project:
Function_1D.h and Function_1D.cpp
Example of use:
//----------------------------------------------------------------------------
void CListBoxMoveItem::OnBnClickedButton20() //^
{
Func_1::ListBox_UpItem( &m_cListBox ); //Up selected items
UpdateData( FALSE );
}
//----------------------------------------------------------------------------
void CListBoxMoveItem::OnBnClickedButton21() //v
{
Func_1::ListBox_DownItem( &m_cListBox ); //down selected items
UpdateData( FALSE );
}
The code is in a separate function file Function_1D
:
//Function_1D.h
namespace Func_1
{
BOOL ListBox_UpItem( CListBox* pListBox ); //Up selected items
BOOL ListBox_DownItem( CListBox* pListBox ); //down selected items
}
//Function_1D.cpp
//-----------------------------------------------------------------------
BOOL Func_1::ListBox_UpItem( CListBox* pListBox ) //Up selected items
{
int iPos = 0;
int iLigne0 = -1;
int iLigne1 = 0;
int iLigne2 = 0;
CString sItemsM = "";
CString sItems1 = "";
CString sItems2 = "";
int nCount = pListBox->GetCount();
int nSelCount = pListBox->GetSelCount();
//http://msdn.microsoft.com/en-us/library/fycfcb17%28v=vs.90%29.aspx
//DEBUT Simple sélection
if ( nSelCount == LB_ERR )
//If the list box is a single-selection list box, the return value is LB_ERR (-1).
{
int iPos = pListBox->GetCurSel();
if ( iPos != 0 )
{
iLigne1 = iPos - 1;
iLigne2= iPos;
pListBox->GetText(iLigne1, sItems1);
pListBox->GetText(iLigne2, sItems2);
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne2 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
}
else
{
iLigne1 = 0;
iLigne2= nCount - 1;
pListBox->GetText(iLigne2, sItems2);
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne1 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne2, sItemsM);
pListBox->DeleteString(iLigne2 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
}
return TRUE;
}
//FIN Simple sélection
//DEBUT Get the indexes of all the selected items in aryListBoxSel
CArray<int,int> aryListBoxSel;
aryListBoxSel.SetSize(nSelCount);
pListBox->GetSelItems(nSelCount, aryListBoxSel.GetData());
AFXDUMP(aryListBoxSel); // Dump the selection array.
//FIN Get the indexes of all the selected items in aryListBoxSel
//DEBUT Multi-Sélection
for(int i = 0; i < nSelCount; i++)
{
iPos = aryListBoxSel.GetAt(i);
if ( iPos != 0 )
{
iLigne1 = iPos - 1;
iLigne2= iPos;
pListBox->GetText(iLigne1, sItems1);
pListBox->GetText(iLigne2, sItems2);
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne2 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
if ( iPos == (iLigne0 + 1 ) )
{
iLigne0++;
}
}
else
{
iLigne0 = 0;
pListBox->GetText(iLigne0, sItemsM);
}
}
if ( iLigne0 != -1)
{
iLigne1 = iLigne0;
iLigne2= nCount - 1;
pListBox->GetText(iLigne2, sItems2);
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne1 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne2, sItemsM);
pListBox->DeleteString(iLigne2 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
}
//FIN Multi-Sélection
//DEBUT Re-Sélection des items
for(int i = 0; i < nCount; i++)
{
pListBox->SetSel( i, FALSE);
}
for(int i = 0; i < nSelCount; i++)
{
iPos = aryListBoxSel.GetAt(i);
if ( iPos != 0 )
{
pListBox->SetSel( iPos -1, TRUE);
}
else
{
pListBox->SetSel( nCount-1, TRUE);
}
}
//FIN Re-Sélection des items
return TRUE;
}
//-----------------------------------------------------------------------
BOOL Func_1::ListBox_DownItem( CListBox* pListBox ) //down selected items
{
int iPos = 0;
int iLigne0 = -1;
int iLigne1 = 0;
int iLigne2 = 0;
CString sItemsM = "";
CString sItems1 = "";
CString sItems2 = "";
int nCount = pListBox->GetCount();
int nSelCount = pListBox->GetSelCount();
//http://msdn.microsoft.com/en-us/library/fycfcb17%28v=vs.90%29.aspx
//DEBUT Simple sélection
if ( nSelCount == LB_ERR )
//If the list box is a single-selection list box, the return value is LB_ERR (-1).
{
int iPos = pListBox->GetCurSel();
if ( iPos != (nCount - 1) )
{
iLigne1 = iPos;
iLigne2= iPos + 1;
pListBox->GetText(iLigne1, sItems1);
pListBox->GetText(iLigne2, sItems2);
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne2 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
}
else
{
iLigne1 = 0;
iLigne2= nCount - 1;
pListBox->GetText(iLigne2, sItems2);
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne1 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne2, sItemsM);
pListBox->DeleteString(iLigne2 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
}
return TRUE;
}
//FIN Simple sélection
//DEBUT Get the indexes of all the selected items in aryListBoxSel
CArray<int,int> aryListBoxSel;
aryListBoxSel.SetSize(nSelCount);
pListBox->GetSelItems(nSelCount, aryListBoxSel.GetData());
AFXDUMP(aryListBoxSel); // Dump the selection array.
//FIN Get the indexes of all the selected items in aryListBoxSel
//DEBUT Multi-Sélection
for(int i = (nSelCount-1); i >=0; i--)
{
iPos = aryListBoxSel.GetAt(i);
if ( iPos != (nCount - 1) )
{
iLigne1 = iPos;
iLigne2= iPos + 1;
pListBox->GetText(iLigne1, sItems1);
pListBox->GetText(iLigne2, sItems2);
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne1, sItems2);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
pListBox->DeleteString(iLigne2 + 1);
if ( iPos == (iLigne0 - 1) )
{
iLigne0--;
}
}
else
{
iLigne0 = nCount - 1;
pListBox->GetText(iLigne0, sItemsM);
}
}
if ( iLigne0 != -1)
{
iLigne1 = iLigne0;
iLigne2 = 0;
pListBox->GetText(iLigne2, sItems2);
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne1 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
//InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
pListBox->InsertString(iLigne2, sItemsM);
pListBox->DeleteString(iLigne2 + 1);
//DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
}
//FIN Multi-Sélection
//DEBUT Re-Sélection des items
for(int i = 0; i < nCount; i++)
{
pListBox->SetSel( i, FALSE);
}
for(int i = (nSelCount-1); i >=0; i--)
{
iPos = aryListBoxSel.GetAt(i);
if ( iPos != (nCount - 1) )
{
pListBox->SetSel( iPos + 1, TRUE);
}
else
{
pListBox->SetSel( 0, TRUE);
}
}
//FIN Re-Sélection des items
return TRUE;
}
//
Demo
The demo shows an example to select items from 1 Listbox
to a 2nd one. The up / down enables to sort items on the 2nd Listbox
.
The demo includes a modified version of WndResizer
from Mizan Rahman's http://www.codeproject.com/KB/dialog/WndResizer.aspx (The original can be used, modification is for hiding/showing controls.)
Points of Interest
Remark: I tested multiple selection parts but not the single selection part.