Інтерфейс перенесення Drag-and-Drop
Інтерфейс перенесення і прийому компонентів з'явився досить давно. Він забезпечує взаємодію двох елементів управління під час виконання програми. При цьому можуть виконуватися будь-які необхідні операції. Незважаючи на простоту реалізації і давність розробки, багато програмістів (особливо новачки) вважають цей механізм малозрозумілим і екзотичним. Проте використання Drag-and-Drop може виявитися дуже корисним і простим в реалізації. Зараз ми в цьому переконаємося.
Для того щоб механізм запрацював, потрібно налаштувати відповідним чином два елементи управління. Один повинен бути джерелом (Source), другий - приймачем (Target). При цьому джерело нікуди не переміщається, а тільки реєструється в цій іпостасі в механізмі.
Примітка:
Один елемент управління може бути одночасно джерелом і приймачем.
Користувач поміщає покажчик миші на потрібний елемент управління, натискає ліву кнопку миші і, не відпускаючи її, починає переміщати курсор до другого елементу. При досягненні цього елемента користувач відпускає кнопку миші. У цей момент виконуються передбачені розробником дії. При цьому перший елемент управління є джерелом, а другий - приймачем.
Як бачите, можна придумати безліч областей застосування механізму Drag-and-Drop. Його універсальність пояснюється тим, що це всього лише засіб скріплення двох компонентів за допомогою покажчика миші. А конкретне наповнення залежить тільки від фантазії програміста і поставлених завдань.
Весь механізм Drag-and-Drop реалізований в базовому класі TControl, який є предком всіх елементів управління. Розглянемо суть механізму.
Будь-який елемент управління з Палітри компонентів Delphi є джерелом в механізмі Drag-and-Drop. Його поведінка на початковому етапі перенесення залежить від значення властивості
Значення dmAutomatic забезпечує автоматичну реакцію компонента на натискання лівої кнопки миші і початок перетягування - при цьому механізм включається самостійно.
Значення dmManual (встановлено за умовчанням) вимагає від розробника забезпечити включення механізму вручну. Цей режим використовується в тому випадку, якщо компонент повинен реагувати на натискання лівої кнопки миші якось інакше. Для ініціалізації перенесення використовується метод
Параметр immediate = True забезпечує негайний старт механізму. При значенні False механізм включається тільки при переміщенні курсора на відстань, визначену параметром Threshold.
Про включення механізму сигналізує покажчик миші - він змінюється на курсор, визначений у властивості
Ще раз нагадаємо, що джерело при переміщенні курсора не змінює свого положення, і тільки в разі успішного завершення перенесення зможе взаємодіяти з приймачем.
Приймачем може стати будь-який компонент, в якому створено метод-обробник
Він викликається при переміщенні курсору в режимі Drag-and-Drop над цим компонентом. У методі-обробнику можна передбачити селекцію джерел перенесення по потрібним атрибутам.
Якщо параметр Accept отримує значення True, то даний компонент стає приймачем. Джерело перенесення визначається параметром source. Через цей параметр розробник отримує доступ до властивостей і методів джерела. Поточне положення курсора задають параметри X і Y. Параметр state повертає інформацію про характер руху миші:
dsDragEnter - покажчик з'явився над компонентом; dsDragLeave - покажчик покинув компонент; dsDragMove - покажчик переміщається по компоненту.
Приймач повинен передбачати виконання деяких дій в разі, якщо джерело завершить перенесення саме на ньому. Для цього використовується метод-обробник
який викликається при відпуску лівої кнопки миші на компоненті-приймачі. Доступ до джерела і приймача забезпечують параметри Source і Sender відповідно. Координати миші повертають параметри X і Y.
При завершенні перенесення елемент управління - джерело - отримує відповідне повідомлення, яке обробляється методом
Джерело і приймач визначаються параметрами Sender і Target відповідно. Координати миші визначаються параметрами X і Y.
Для програмної зупинки перенесення можна використовувати метод EndDrag джерела (при звичайному завершенні операції користувачем він не використовується):
Параметр Drop = True завершує перенесення. Значення False перериває перенесення.
Лістинг 27.1. Секція implementation модуля головної форми проекту DemoDragDrop
і включається механізм перенесення. Так як властивість DragMode для Edit1 має значення dmManual, то компонент без проблем забезпечує отримання фокусу і редагування тексту.
Метод EditiEndDrag забезпечує відображення інформації про виконання перенесення в джерелі.
Для компонента Edit2 визначені методи-обробники приймача. Метод Edit2DragOver перевіряє клас джерела і дозволяє або забороняє прийом.
Метод Edit2DragDrop здійснює перенесення тексту з джерела в приймач.
Зверніть увагу, що обидва компонента TEdit одночасно є джерелами і приймачами. Для цього кожен з них використовує методи-обробники іншого. А вихідний код методів налаштований на обробку власника як екземпляра класу TEdit.
Форма, як приймач Drag-and-Drop, забезпечує переміщення панелі Panel2, яка виступає в ролі джерела. Метод FormDragOver забороняє прийом будь-яких компонентів, крім панелей. Метод FormDragDrop здійснює переміщення компонента.
Панель не має своїх методів-обробників, т. К. Працює в режимі dmAutomatic і не потребує додаткової обробки завершення перенесення.