C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 Прокрутка во время drag-n-drop / TreeCtrl, TreeView / Элементы управления

Прокрутка во время drag'n'drop

Когда мы перетаскиваем элемент вполне возможна ситуация, когда цель перетаскивания не видна. Иногда пользователь разворачивает ветви так, что без прокрутки не обойдешся. "Умные" приложения обходят этот барьер.

Шаг 1: Добавление членов-переменных в класс
Мы объявляем две переменные. Одна описывает таймер, другая счетчик тиков для таймера


protected:
	UINT    m_nTimerID;
	UINT    m_timerticks;

 

Шаг 2: Установка таймера в обработчике TVN_BEGINDRAG
Поместите следующий код в конец Вашего обработчика (обычно это OnBeginDrag() ):


	// Устанавливаем таймер
	m_nTimerID = SetTimer(1, 75, NULL);

 

Шаг 3: Установка обработчика WM_TIMER
По умолчанию имя функции OnTimer(). Наперво убедимся, что обрабатываем правильное сообщение таймера. Затем обновляем расположение перетаскиваемого изображения. И тогда определяем нужна ли прокрутка. Если курсор cверху / снизу края или близко к краю, то вычиляем скорость прокрутки. Она изменяется в зависимости от удалености курсора от края элемента управления и делится на 6 уровней.


void CTreeCtrlX::OnTimer(UINT nIDEvent) 
{
	if( nIDEvent != m_nTimerID )
	{
		CTreeCtrl::OnTimer(nIDEvent);
		return;
	}

	// Не имеет значения то, что мы не инициализировали m_timerticks
	m_timerticks++;

	POINT pt;
	GetCursorPos( &pt );
	RECT rect;
	GetClientRect( &rect );
	ClientToScreen( &rect );

	// Внимание: Экранные координаты используются потому что
	// DragEnter использует окно Рабочего Стола
	CImageList::DragMove(pt);

	HTREEITEM hitem = GetFirstVisibleItem();

	if( pt.y < rect.top + 10 )
	{
		// Мы должны прокручивать
		// Делаем это медленно, если курсор около границы
		int slowscroll = 6 - (rect.top + 10 - pt.y) / 20;
		if( 0 == ( m_timerticks % (slowscroll > 0? slowscroll : 1) ) )
		{
			CImageList::DragShowNolock(FALSE);
			SendMessage( WM_VSCROLL, SB_LINEUP);
			SelectDropTarget(hitem);
			m_hitemDrop = hitem;
			CImageList::DragShowNolock(TRUE);
		}
	}
	else if( pt.y > rect.bottom - 10 )
	{
		int slowscroll = 6 - (pt.y - rect.bottom + 10 ) / 20;
		if( 0 == ( m_timerticks % (slowscroll >0? slowscroll : 1) ) )
		{
			CImageList::DragShowNolock(FALSE);
			SendMessage( WM_VSCROLL, SB_LINEDOWN);
			int nCount = GetVisibleCount();
		for ( int i=0; i<nCount; ++i)
		hitem = GetNextVisibleItem(hitem);
		if( hitem )			
              	SelectDropTarget(hitem);
		m_hitemDrop = hitem;
            	CImageList::DragShowNolock(TRUE);
		}
	}
}

 

Шаг 4: Удаляем таймер, когда операция закончена
Вызовите KillTimer( m_nTimerID ), когда операция будет закончена. Потребуется включить этот код в PreTranslateMessage(), если Вы отменяете перетаскивание с помощью клавиши Esc.


 

Источник: ProtoSphere