Главная » C++, C++ Builder » Списки с drag-and-drop, часть вторая C++ Builder

0

Одна вещь действительно озадачила меня в программе перетаскивания после того, как я ее написал. Это та же проблема, которой я был озадачен и тогда, после начальной версии проекта с drag-and-drop, о котором я говорил в начале этого примера. Проблема в том, что перетаскиваемые элементы попадают в конец того списка, в который их притащили. Это раздражает пользователя, который аккуратно переместил мышь к элементу, после которого хочет добавить перетаскиваемые, а получает их в конце списка.

Во второй версии программы перетаскивания в списках мы решим эту проблему.

Замечание

Исходный код для второго примера программы перетаскивания в списках находится на сопроводительном компакт-диске в каталоге Chapter4\DragDropList2.

Используя код, написанный нами для предыдущего примера, исправьте метод OnDragDrop, чтобы он выглядел так:

void __fastcall TForm1::OnDragDrop(TObject *Sender, TObject *Source, int X, int Y)

{

TListBox *pList1 = (TListBox *)Source; TListBox *pList2 = (TListBox *)Sender;

// Какой элемент находится под перетаскиваемыми? POINT p;

p.x = X;

p.y = Y;

int nItemIndex = pList2->ItemAtPos( p, false );

String s = "Роняем на элемент: " + String(nItemIndex); Label1->Caption = s;

// Копируем то, что выбрано

for ( int i=0; i<pList1->Items->Count; ++i ) if ( pList1->Selected[ i ] )

{

// Добавить во второй список

pList2->Items->Insert(  nItemIndex,

pList1->Items->Strings[ i ] );

// И удалить из первого

pList1->Items->Delete( i );

}

}

Сделав это, вы, во-первых, помещаете элемент в корректную позицию в новом  списке,  а  во- вторых, реализуете список, позволяющий перетасовывать элементы, перетаскивая их внутри списка.

Заметьте, что мы добавили кусочек  кода, отмечающий место, куда  элемент попадает. Причина этого проста. Попробуйте перетащить элемент ниже последнего элемента в списке. Вы можете предположить, что метод ItemAtPos сойдет  с ума, пытаясь определить, что  за элемент лежит в позиции, не принадлежащей ни одному элементу. Конечно, я тоже этого ожидал, когда писал этот пример, но метод с ума не сошел. На самом деле, он работает именно так, как я  бы  хотел, возвращая номер на один больше, чем число элементов в списке. Это замечательно работает с методом Insert (вставить) свойства Items (элементы),  принадлежащего классу TListBox (список), который, получив этот номер, радостно добавит элемент к концу списка. Хм. Похоже, кто-то уже действительно думал над этой проблемой.

У CBuilder такие примеры встречаются всюду в библиотеке VCL. Вы увидите, что редко нужно заглядывать в обширную документацию, так как в основном все работает так, как вы и ожидали. Иногда где-то что-то будет отличаться, но обычно в таких случаях вы увидите, что ваша позиция основана на вашем предыдущем опыте. Вместо сложной методики для реализации чего-либо в CBuilder обычно использованы простейшие подходы. Простейшие с точки зрения программиста.

Итак, вы теперь знаете намного больше о процедуре drag-and-drop, чем раньше, может  даже больше, чем вам хотелось.

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

  • Комментарии