Шаг 197 - Перемещение элемента в списке

Итак, задача будет связана с перемещением элемента в списке с помощью мышки. Можно будет схватить текст и мышкой его переместить в нужную позицию. Создаем приложение на базе диалогового окна. Пусть имя его будет TestList. Помещаем на него элемент управления ListBox. Вызываем ClassWizard и делаем его членом класса диалогового окна с типом Control.

class CTestListDlg : public CDialog
{
// Construction
public:
	CTestListDlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	//{{AFX_DATA(CTestListDlg)
	enum { IDD = IDD_TESTLIST_DIALOG };
	CListBox	m_List;
	//}}AFX_DATA
......

Теперь в функции OnInitDialog() заполним список элементами.

BOOL CTestListDlg::OnInitDialog()
{
	......
	// TODO: Add extra initialization here
	m_List.AddString("1935"); 
	m_List.AddString("1936"); 
	m_List.AddString("1937"); 
	m_List.AddString("1938"); 
	m_List.AddString("1939"); 
	return TRUE;  // return TRUE  unless you set the focus to a control
}

Ну и что дальше ??? А дальше ничего :-) Вы не сможете ничего сделать пока. Нам нужно перехватить нажатие и отпускание левой кнопки мыши на списке. Вы можете полазить по всем мастерам, но ничего похожего не найдете, а выход есть. Для того, чтобы подобные действия можно было производить нам нужно создать свой класс используя new Class как потомок от CListBox и жизнь точно покажется лучше. Добавляйте класс с именем CMyList и у Вас появится класс с таким описанием:

class CMyList : public CListBox
{
......

Давайте подменим его в классе диалога Вот так.

......
#endif // _MSC_VER > 1000

#include "MyList.h"

////////////////////////////////////////
// CTestListDlg dialog

class CTestListDlg : public CDialog
{
// Construction
public:
	CTestListDlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	//{{AFX_DATA(CTestListDlg)
	enum { IDD = IDD_TESTLIST_DIALOG };
	CMyList	m_List;
......

Все это хорошо и на данную минуту работает. Теперь мы можем спокойно править класс CMyList. Первое, что мы сделаем это перегрузим события нажатия и отпускания кнопки мыши, с помощью ClassWizard конечно. Теперь он пригодится точно.

/////////////////////////////
// CMyList message handlers

void CMyList::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CListBox::OnLButtonDown(nFlags, point);
}

void CMyList::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CListBox::OnLButtonUp(nFlags, point);
}

Вот работать будет все так. Нажимается кнопка, запоминается позиция и текст. Отпускается кнопка, старая позиция удаляется, а в место новой вставляется старый текст и этот элемент выделяется. Значит нам нужно завести как минимум две переменные членов класса для того, чтобы хранить позицию и текст. Заведем.

class CMyList : public CListBox
{
......
// Generated message map functions
protected:
	CString csOldText;
	int intOldSel;
	//{{AFX_MSG(CMyList)
......

Ну что, запоминаем по нажатию текст и позицию ???

void CMyList::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CListBox::OnLButtonDown(nFlags, point);
	intOldSel=GetCurSel();
	GetText(intOldSel,csOldText);
}

И по отпусканию мыши теперь это надо вставить и удалить.

void CMyList::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CListBox::OnLButtonUp(nFlags, point);
	int intOnUpSel=GetCurSel();
	DeleteString(intOldSel);
	InsertString(intOnUpSel,csOldText);
	SetCurSel(intOnUpSel);
}

Вот и все :-)


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 28.06.2000