Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 2 августа!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

ПРОГРАММИРОВАНИЕ НА C и С++



Давно заметил, что всё-таки языки С/C++ это не самый лучший вариант программирования под Windows. Сейчас появилась масса более современных и удобных языков, например тот же Python - кроссплатформенный язык, очень легок в изучение. Я его изучил буквально за несколько дней по этому курсу - ссылка. Автор постарался, там видеоуроки на удивление легкие и понятные.

Реализация drag'n'drop в CTreeView -- 2 метод

"Операция при которой пользователь используем мышь или другое указывающее устройство для перемещения данных из одного окна в другое". Именно так звучит определение Drag'n'Drop в MSDN. В данном примере мы рассмотрим метод именно _перемещения_ данных пользователем. Все делается в 5 шагов:

Шаг 1: Убедитесь, что Ваше дерево поддерживает drag'n'drop
Флаг TVS_DISABLEDRAGDROP должен быть отключен. Иначе сообщение TVN_BEGINDRAG не будет послано.

Шаг 2: Объявите переменные-члены


 protected:
    CImageList*	m_pDragImage;	//содержит список изображений используемый  во  время переноса
    BOOL	m_bLDragging;
    HTREEITEM	m_hitemDrag,m_hitemDrop;
 

 

Шаг 3: Добавьте обработчик для TVN_BEGINDRAG
Функция BeginDrag() вызывается с аргументами 0 и координатами точки. Ноль обозначает номер изображения в списке, точка - координаты относительно курсора этого изображения. Затем мы вызываем DragEnter(), чтобы показать изображение. Первый параметр NULL - для того, чтобы изображение было видно за пределами дерева.


 
 void CTreeCtrlX::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult) 
 {
 	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
 	*pResult = 0;
 
 	m_hitemDrag = pNMTreeView->itemNew.hItem;
 	m_hitemDrop = NULL;
 
 	m_pDragImage = CreateDragImage(m_hitemDrag);  // get the image list for dragging
 	// CreateDragImage() возвращает  NULL если нет списка изображаний
 	// связанного с деревом
 	if( !m_pDragImage )
 		return;
 
 	m_bLDragging = TRUE;
 	m_pDragImage->BeginDrag(0, CPoint(-15,-15));
 	POINT pt = pNMTreeView->ptDrag;
 	ClientToScreen( &pt );
 	m_pDragImage->DragEnter(NULL, pt);
 	SetCapture();
 }
 

 

Шаг 4: Добавьте обработчик для WM_MOUSEMOVE - обновление перетаскивамого изображения
В этом обработчике мы обновляем позицию взятого изображения и цель бросания. Функция DragMove() перемещает изображение. Затем мы должны обновить цель, если мышь появляется над деревом. Делаем это с помощью двух вызовов функции DragShowNolock(). Первый: скрывает изображение и позволяет обновить информацию, второй: показывает изображение снова. Можно было бы использовать DragLeave() / DragEnter(), но тут иногда возникают проблемы перерисовки.


 
 void CTreeCtrlX::OnMouseMove(UINT nFlags, CPoint point) 
 {
 	HTREEITEM	hitem;
 	UINT		flags;
 
 	if (m_bLDragging)
 	{
 		POINT pt = point;
 		ClientToScreen( &pt );
 		CImageList::DragMove(pt);
 		if ((hitem = HitTest(point, &flags)) != NULL)
 		{
 			CImageList::DragShowNolock(FALSE);
 			SelectDropTarget(hitem);
 			m_hitemDrop = hitem;
 			CImageList::DragShowNolock(TRUE);
 		}
 	}
 
 	CTreeCtrl::OnMouseMove(nFlags, point);
 }
 

 

Шаг 5: Наконец добавьте обработчик для WM_LBUTTONUP
В обработчике WM_LBUTTONUP мы завершаем drag'n'drop процесс. Сначала мы определяем, что находимся в режиме drag'n'grop. Это хорошее место для того, чтобы удалить список изображений созданный функцией CreateDragImage() в методе OnBeginDrag(). Перед перемещением убедимся, что все действия кооректны. В вызове Expand(), в принципе, нет необходимости, но если мы объявили динамическую загрузку, где элементы загружаются, когда ветвь раскрывается, он необходим.


  void CTreeCtrlX::OnLButtonUp(UINT nFlags, CPoint point) 
 {
 	CTreeCtrl::OnLButtonUp(nFlags, point);
 
 	if (m_bLDragging)
 	{
 		m_bLDragging = FALSE;
 		CImageList::DragLeave(this);
 		CImageList::EndDrag();
 		ReleaseCapture();
 
 		delete m_pDragImage;
 
 		// Удаляем подсветку цели
 		SelectDropTarget(NULL);
 
 		if( m_hitemDrag == m_hitemDrop )
 			return;
 
 		HTREEITEM htiParent = m_hitemDrop;
 		while( (htiParent = GetParentItem( htiParent )) != NULL )
 		{
 			if( htiParent == m_hitemDrag ) return;
 		}
 
 		Expand( m_hitemDrop, TVE_EXPAND ) ;
 
 		HTREEITEM htiNew = CopyBranch( m_hitemDrag, m_hitemDrop, TVI_LAST );
 		DeleteItem(m_hitemDrag);
 		SelectItem( htiNew );
 	}
 
 }
 

 

Источник: ProtoSphere



<< ВЕРНУТЬСЯ В ПОДРАЗДЕЛ

<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ




Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS