Реалізація drag-and-drop в списках C + + Builder

CBuilder побудований на таких речах, які потрібні програмісту постійно Система CBuilder не підтримує безпосередньо drag-and-drop між двома списками, але проте в ній є вбудована принципова можливість підтримки drag-and-drop

Тут варто відзначити, що насправді люди мають зважаючи дві речі, коли говорять про drag-and-drop Перша – це система, про яку ми говоримо, переміщення даних між двома компонентами, двома формами або двома обєктами в системі Друга – перетягування файлів у вікно програми Ця форма drag-and-drop, зазвичай перетягування файлів з Windows Explorer в додаток, що працює під Windows 95 або NT, є окремою статтею і буде розглянута в книзі пізніше, коли ми будемо говорити про Windows API

Отже, що саме нам потрібно зробити для того, щоб drag-and-drop працював в CBuilder Не так вже й багато насправді По-перше, давайте створимо форму для демонстрації перетягування елементів між двома списками Форма, використовувана нами в цьому прикладі, показана на рис

48 На ній знаходяться два списки і мітка, яку ми будемо використовувати для відображення стану поточного процесу

Рис 48 Форма прикладу списків з drag-and-drop

Для того, щоб підтримувати drag-and-drop у вашій формі, вам потрібно обробляти дві події для обєктів, в яких ви хочете дозволити перетягування Перше з них – подія OnDragDrop, яке відбувається, коли користувач тягне небудь з вашого обєкта або, знову ж, упускає небудь на ваш обєкт Друга подія, що вам потрібно обробити – OnDragOver Його обробник викликається для перевірки коректності перетягування даних на ваш обєкт Якщо не обробляти цю подію, то курсор миші перетворитися на знак заборони (перекреслений круг), коли він буде над вашим обєктом

Вихідний код для програми «Списки з Drag-And-Drop» знаходиться на супровідному компакт-диску в каталозі Chapter4 \ DragDropList1

У цьому прикладі ми опрацюємо обидві події OnDragOver і OnDragDrop для обох списків

Для початку давайте додамо обробник події OnDragOver для обох списків Виберіть обидва списки на форма і перейдіть на сторінку Events в Object Inspector Навпаки події OnDragOver наберіть в полі імя методу OnDragOver Так ви привласните обробник події відразу для двох обєктів, що трохи заощадить вам час, а також продовжить життя вашої миші і клавіатурі Введіть наступний код в метод OnDragOver для обох списків:

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

TDragState State, bool &ampAccept)

{

Accept = true

}

Цей метод просто повідомляє, що обидва списки здатні сприймати перетягування Ми будемо приймати перетягуються дані, так як нам не дуже важливо, звідки вони взялися (будемо вважати, що з сусіднього списку) Повертаний параметр Accept, який показує, чи буде (true) обєкт дозволяти перетягувати на нього дані чи ні (false) – це єдиний параметр методу, значимий для CBuilder Наступний метод, який нам потрібен – метод DragDrop Цей метод буде викликатися, коли користувач притягне небудь на наш список і відпустить кнопку миші Додайте обробник (для обох списків) події OnDragDrop через Object Inspector Назвіть новий метод OnDragDrop і додайте в нього наступний код (загальний для обох списків):

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

{

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

/ / Потрібно скопіювати те, що виділено for (int i = 0 i Items-> Count + + i) if (plist1-> Selected [i])

{

/ / Додати його у другий список

pList2-&gtItems-&gtAdd( pList1-&gtItems-&gtStrings[ i ] )

/ / І видалити з першого

pList1-&gtItems-&gtDelete( i )

}

}

Є пара речей, на які варто звернути увагу Перше, не важливо з якого списку в якій ви перетягуєте Код обробить обидва випадки Причина цього в тому, що CBuilder передає вам два параметри, вказують звідки йде перетягування і куди Обєкт Sender – обєкт, на який елементи роняю Обєкт Source – обєкт, якому належать перетягуються дані

Може бути, відразу це не зовсім зрозуміло Однак, якщо подумати, аргумент Sender у всіх обробниках подій є завжди обєкт, для якого було згенеровано подія У нашому випадку подія полягає в тому, що на обєкт притягли елементи З аргументом Source (джерело) ясніше це джерело перетягувати інформації Інтерпретувати цю інформацію і вирішувати, що з нею робити, є нашим завданням

Наступна цікава річ у прикладі – підтримка множинного перетягування Якщо ви перетягніть три елементи з лівого списку в правий, то ці три елементи зникнуть з лівого списку і зявляться в правом Це вже, ймовірно, перевищує ваші очікування До речі, щоб це запрацювало, потрібно встановити властивість MultiSelect (множинний вибір) обох списків в true (істина)

Третя і остання цікава річ в прикладі така, що вам, ймовірно, відразу не видна Це приклад спрацює у випадку, коли джерело і одержувач операції drag-and-drop – одне і те ж Якщо ви виберіть елемент в першому списку (з лівого боку) і перетягніть його на той же (лівий) список, то елемент пропаде з поточної позиції і зявиться в кінці списку Чого він не зробить, це він не зявиться там, куди ви перемістили миша Ми розберемося з цим через пару хвилин

Єдиний спосіб протестувати приклад – мати які-небудь дані в списках спочатку Додайте обробник події форми OnCreate Дайте новому оброблювачу імя FormCreate і додайте в метод FormCreate наступний код:

void __fastcall TFOrm1::FormCreate(TObject *Sender)

{

ListBox1-> Items-> Add (Елемент 1) ListBox1-> Items-> Add (Елемент 2) ListBox1-> Items-> Add (Елемент 3) ListBox1-> Items-> Add (Елемент 4 ) ListBox1-> Items-> Add (Елемент 5)

}

Звичайно, тут ми всього лише додаємо трішки елементів в список, щоб можна було трохи з ними пограти

Drag-and-drop рідко буває таким простим, як наведено вище Частенько вам потрібно буде знати, коли починається процес перетягування, щоб ви могли встановити який-небудь прапор або перевірити, коректні Чи дані для копіювання Приклад – список із взаємно несумісними даними Ви захочете заборонити користувачеві вибирати два елементи і додавати їх до списку обраних, якщо ці елементи не можуть працювати разом Вам потрібно буде на початку перетягування даних видаляти з них некоректні

Звичайно, CBuilder надає можливості для цього Стали б ми про це розмовляти, якби це було не так Звичайно, ні У цьому випадку, однак, потрібне обробником є ​​обробник події OnStartDrag Коли ми створювали форму, я попросив вас додати мітку в нижній частині форми Давайте її використовуємо для відображення стану того, що відбувається

Додайте обробник події StartDrag для першого обєкта «список» (list box) у формі Назвіть обробник ListBox1StartDrag Додайте наступний код в метод ListBox1StartDrag:

void __fastcall TForm1::ListBox1StartDrag(TObject *Sender, TDragObject  *&ampDragObject)

{

Label1-> Caption = Початок перетягування ..”;

}

Нічого особливого в цьому обробнику немає Ми всього лише встановлюємо заголовок (або текст, caption) мітки, відображаючи початок перетягування зі списку Точно також ми можемо додати обробник події OnEndDrag, яке відбувається при завершенні операції перетягування Створіть обробник події OnEndDrag для першого списку і назвіть його ListBox1EndDrag Додайте наступний код для форми в метод ListBox1EndDrag:

void __fastcall TForm1::ListBox1EndDrag(TObject *Sender, TObject *Target, int X, int Y)

{

Label1-> Caption = Завершення перетягування ..”;

}

Скомпілюйте і запустіть додаток Вибираючи елементи у списку, стежте за текстом мітки в нижній частині форми Зауважте, що просто вибір елемента і його переміщення починає процес перетягування Процес закінчується, коли кнопка миші де-небудь відпускається Якщо навіть курсор миші знаходиться над тим же списком, викликається подія OnEndDrag

Тепер ви знаєте достатньо про drag-and-drop в системі CBuilder, щоб бути небезпечним Приклад drag-and-drop в списках показав вам, як робити деякі речі, але не до кінця Потрібно зробити ще парочку поліпшень

Джерело: Теллес М – Borland C + + Builder Бібліотека програміста – 1998

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*