Прокрутка во время drag'n'dropКогда мы перетаскиваем элемент вполне возможна
ситуация, когда цель перетаскивания не видна.
Иногда пользователь разворачивает ветви так, что
без прокрутки не обойдешся. "Умные"
приложения обходят этот барьер. protected: UINT m_nTimerID; UINT m_timerticks;
Шаг 2: Установка таймера в обработчике TVN_BEGINDRAG
// Устанавливаем таймер m_nTimerID = SetTimer(1, 75, NULL);
Шаг 3: Установка обработчика WM_TIMER
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: Удаляем таймер, когда операция закончена
Источник: ProtoSphere
|