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 ); UpdateData( FALSE );
}
void CListBoxMoveItem::OnBnClickedButton21() {
Func_1::ListBox_DownItem( &m_cListBox ); UpdateData( FALSE );
}
The code is in a separate function file Function_1D
:
namespace Func_1
{
BOOL ListBox_UpItem( CListBox* pListBox ); BOOL ListBox_DownItem( CListBox* pListBox ); }
BOOL Func_1::ListBox_UpItem( CListBox* pListBox ) {
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();
if ( nSelCount == LB_ERR )
{
int iPos = pListBox->GetCurSel();
if ( iPos != 0 )
{
iLigne1 = iPos - 1;
iLigne2= iPos;
pListBox->GetText(iLigne1, sItems1);
pListBox->GetText(iLigne2, sItems2);
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne2 + 1);
}
else
{
iLigne1 = 0;
iLigne2= nCount - 1;
pListBox->GetText(iLigne2, sItems2);
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne1 + 1);
pListBox->InsertString(iLigne2, sItemsM);
pListBox->DeleteString(iLigne2 + 1);
}
return TRUE;
}
CArray<int,int> aryListBoxSel;
aryListBoxSel.SetSize(nSelCount);
pListBox->GetSelItems(nSelCount, aryListBoxSel.GetData());
AFXDUMP(aryListBoxSel);
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);
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne2 + 1);
if ( iPos == (iLigne0 + 1 ) )
{
iLigne0++;
}
}
else
{
iLigne0 = 0;
pListBox->GetText(iLigne0, sItemsM);
}
}
if ( iLigne0 != -1)
{
iLigne1 = iLigne0;
iLigne2= nCount - 1;
pListBox->GetText(iLigne2, sItems2);
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne1 + 1);
pListBox->InsertString(iLigne2, sItemsM);
pListBox->DeleteString(iLigne2 + 1);
}
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);
}
}
return TRUE;
}
BOOL Func_1::ListBox_DownItem( CListBox* pListBox ) {
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();
if ( nSelCount == LB_ERR )
{
int iPos = pListBox->GetCurSel();
if ( iPos != (nCount - 1) )
{
iLigne1 = iPos;
iLigne2= iPos + 1;
pListBox->GetText(iLigne1, sItems1);
pListBox->GetText(iLigne2, sItems2);
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne2 + 1);
}
else
{
iLigne1 = 0;
iLigne2= nCount - 1;
pListBox->GetText(iLigne2, sItems2);
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne1 + 1);
pListBox->InsertString(iLigne2, sItemsM);
pListBox->DeleteString(iLigne2 + 1);
}
return TRUE;
}
CArray<int,int> aryListBoxSel;
aryListBoxSel.SetSize(nSelCount);
pListBox->GetSelItems(nSelCount, aryListBoxSel.GetData());
AFXDUMP(aryListBoxSel);
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);
pListBox->InsertString(iLigne1, sItems2);
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);
pListBox->InsertString(iLigne1, sItems2);
pListBox->DeleteString(iLigne1 + 1);
pListBox->InsertString(iLigne2, sItemsM);
pListBox->DeleteString(iLigne2 + 1);
}
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);
}
}
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.