4. Технология Drag-and-Drop (Разработка многомодульных интегрированных SDI-приложений)

2015-08-23СтудИзба

Описание файла

Файл "4. Технология Drag-and-Drop" внутри архива находится в папке "Разработка многомодульных интегрированных SDI-приложений". Документ из архива "Разработка многомодульных интегрированных SDI-приложений", который расположен в категории "". Всё это находится в предмете "проектирование программного обеспечения автоматизированных систем" из 9 семестр (1 семестр магистратуры), которые можно найти в файловом архиве НИУ «МЭИ» . Не смотря на прямую связь этого архива с НИУ «МЭИ» , его также можно найти и в других разделах. Архив можно найти в разделе "остальное", в предмете "проектирование по автоматизированных систем" в общих файлах.

Онлайн просмотр документа "4. Технология Drag-and-Drop"

Текст из документа "4. Технология Drag-and-Drop"

Технология Drag-and-Drop

Реализации Drag&Drop в VCL

Drag&Drop («перетащи и положи») – это один из способов обмена данными между приложениями. Этим способом обмена пользуются многие программные приложения. Например, очень часто так перемещаются файлы и папки.

В библиотеке визуальных компонент - VCL реализована собственная версия Drag&Drop – технологии, которая обеспечивает прием и передачу любых управляющих элементов внутри одной и той же формы. При таком внутреннем использовании VCL не обращается к операционной системе, хотя для организации общения различных приложений нужно было бы использовать соответствующие функции API Windows.

Пользователь, нажав на левую кнопку мыши, может перетащить управляющий элемент (объект – источник) на другой элемент (объект-приемник). В моменты перетаскивания и отпускания генерируются события, которые должна обрабатывать программа (получателем событий является элемент, над которым находится курсор мыши). Свойство компонентов DragMode отвечает за их участие в процессе обмена данными.

DragMode = dmAutomatic - события срабатывают автоматически, программист пишет только коды, соответствующих обработчиков событий.

DragMode = dmManual - все вызовы программист должен организовать сам.

События, возникающие при перетаскивании

Событие OnDragOver возникает во время перемещения курсора мыши над объектом-приемником, а также при отпускании кнопки на этом объекте.

Параметры события:

  • Sender - объект-приемник (над ним находится курсор);

  • Source - объект-источник;

  • X,Y - координаты мыши в системе клиентской области объекта Sender;

  • State - состояние (имеет одно из трех значений dsDragEnter – курсор мыши появился над элементом; dsDragMove курсор перемещается над элементом; dsDragLeave – курсор ушел с элемента или над элементом была отпущена кнопка).

  • Accept – логическая переменная. В этой переменной обработчик должен вернуть свое решение принимать или не принимать объект Source.

Например, компонент класса Label (Name=Label1) должен принимать только компоненты класса Shape (геометрические фигуры), тогда его обработчик будет содержать проверку переносимого объекта-источника (Source):

void __fastcall TForm1::Label1DragOver(TObject *Sender, TObject *Source,

int X, int Y, TDragState State, bool &Accept)

{

Accept=Source->ClassNameIs("TShape");

}

Событие OnDragDrop возникает при отпускании левой кнопки мыши над элементом, готовым к приему. Его параметры Sender, Source, X и Y имеют тот же смысл, что и у предыдущего события. Содержимое этого обработчика зависит от того, какие функции программист разрешает выполнять пользователю путем перетаскивания. Это может быть изменение местоположения объектов, обмен информацией и т.д.

В следующем примере не происходит физического перемещения объектов; компонент Label1 получает указатель на перемещенный объект (геометрическая фигура) и считывает значения свойств (Height, Width) для вычисления периметра фигуры. Результат вычислений размещается в Label1 -> Caption.

void __fastcall TForm1::Label1DragDrop(TObject *Sender,

TObject *Source, int X, int Y)

{

float p, pi=3.14; int w, h, r, D;

if (String(Source->ClassName())=="TShape")

{

h=((TShape *)Source)->Height;

w= ((TShape *)Source)->Width ;

D = w; if ( D > h ) D = h;

switch ((( TShape *)Source) -> Shape)

{ case stRectangle:

Label2->Caption ="Прямоугольник";

p= 2*(w + h);

break;

case stSquare:

Label2->Caption = "Квадрат";

p= 4*D;

break;

case stCircle:

Label2->Caption = "Круг";

p= pi*D;

break;

case stEllipse:

Label2->Caption = "Эллипс";

p=pi*(3*(w+h)/4-sqrt(w*h)/2);

break;

case stRoundRect:

Label2->Caption = "Закругленный

прямоугольник";

r=(D-((TShape*)Source)->Pen->

Width +1)/4;

p=2*(w+h)-8*r+2*pi*r;

break;

case stRoundSquare:

Label2->Caption="Закругленный

квадрат";

r=(D-((TShape*)Source)->Pen->

Width+1)/4;

p=4*D-8*r+2*pi*r;

break;

}

p=p/(Form1->PixelsPerInch/2.54);

Label1->Caption = FloatToStr (p);

}

}

При завершении процесса перетаскивания вне зависимости от его результата исходный объект получает событие OnEndDrag. Его параметры:

  • Sender – указатель объекта - источника;

  • Target – указатель объекта - приемника;

  • X, Y – координаты курсора.

В следующем примере переносимый компонент Shape1 узнает имя объекта - приемника (если объект не принят передается NULL):

void __fastcall TForm1::Shape1EndDrag(TObject *Sender, TObject *Target,

int X, int Y)

{

if (Target != NULL)

Label2->Caption =(AnsiString) (( TComponent *) Target)->Name;

}

Идентификация типа объекта

Так как при передаче параметров объекты (Sender, Source, Target) имеют тип Tobject (базовый класс всех компонентов VCL – библиотеки), приходится определять, к какому классу в действительности принадлежит тот или иной компонент. Это можно сделать разными способами.

Приведение типа

Если необходимо рассмотреть свойство или применить к объекту метод, который объявлен в классах-наследниках, то необходимо привести тип указателя к тому классу, где это свойство или метод имеются.

Свойство Name есть у всех компонент библиотеки VCL и объявлено оно в классе TСomponent. Выражение ((TСomponent *)Sender) является приведением типа параметра Sender к типу указателя на объект класса TСomponent. Теперь можно узнать имя компонента:

Label1->Caption = ((TСomponent *)Sender) -> Name;

или

TComponent *Obj;

Obj = ((TСomponent *)Sender);

Теперь переменную Obj можно использовать как указатель на компонент:

Label1->Caption = Obj -> Name;

Часто программисту необходимо узнать является ли класс объекта потомком того класса, методы и свойства которого мы хотим использовать. Это можно проверить с помощью метода InheritsFrom, объявленного в TObject и возвращающего логический результат. Например, можно убедиться, что объект наследует свойства класса TWinControl:

if (Sender -> InheritsFrom(__classid(TWinControl)))

. . . ;

оператор __сlassid(classType) используется компилятором для генерации ссылки на указанный класс, в данном примере на класс TWinControl.

Определение истинного класса объекта

В классе TObject определен метод ClassName(), возвращающий строку, содержащую действительный класс объекта. Имя класса можно, например, увидеть на экране:

Label1 -> Caption = Sender-> ClassName();

Или программно проверить принадлежность к интересующему нас классу:

if (String (Sender -> ClassName()) == “TShape”)

. . . ;

Для такой же проверки можно использовать функцию ClassNameIs, определенную в TObject и возвращающую результат типа bool.

If (Sender -> ClassNameIs(“TShape”) )

. . . ;

Иерархия классов объекта

Метод ClassParent, определенный в TObject позволяет определить класс, являющийся непосредственным предком класса заданного объекта. Если это объект класса TObject, то есть класс не имеет предков, то вернется NULL.

Для восстановления всей иерархии классов некоторого объекта следует использовать данный метод в цикле. На рис. 2.1 представлено главное окно приложения, которое в компоненте TreeView, предназначенном для отображения иерархических данных в виде дерева, отображает иерархию классов указанного объекта. Сами объекты (Edit1, Shape1, Button1 и Image1) также расположены в этом окне, а слева от них указаны имена классов объектов.

В программе использована технология Drag-and-Drop. Пользователь “перетаскивает” объект на компонент TreeView1 и, получив указатель на объект-источник информации, метод TreeView1DragDrop в цикле считывает имена классов объекта.

void __fastcall TForm1::TreeView1DragDrop(TObject *Sender, TObject *Source,

int X, int Y)

{

// Получение ссылки на класс объекта

TClass ClassRef = Source->ClassType();

if (Sender->ClassNameIs("TTreeView"))

{

// Получение указателя на объект TreeView1

TTreeView *pTV = (TTreeView *)Sender;

// Удаление предыдущей информации из TreeView1

while (pTV->GetNodeAt(0,0)!=NULL)

pTV->Items->Delete(pTV->GetNodeAt(0,0));

}

// Имена родительских классов добавляются в первый // узел дерева

while (ClassRef!=NULL)

{

TreeView1->Items->AddFirst(TreeView1->

GetNodeAt(0,0),ClassRef->ClassName());

ClassRef = ClassRef->ClassParent();

}

Label1->Caption ="Источник: " + (AnsiString)

(( TComponent *) Source)->Name;

}

Следующий код обработчика события OnDragOver определяет будет ли принят объект-источник компонентом TreeView1.

void __fastcall TForm1::TreeView1DragOver(TObject *Sender, TObject *Source,

int X, int Y, TDragState State, bool &Accept)

{ if (Source!=Sender)

Accept=true;

else

Accept=false;

}

Обработчик события OnEndDrag исходного объекта проверяет принят ли объект каким-либо целевым объектом..

Void __fastcallTForm1::ObjectEndDrag

(TObject*Sender, TObject *Target,

int X, int Y)

{

if (Target==NULL)

Label2->Caption="Нет целевого объекта";

else

Label2->Caption ="Приемник " + (AnsiString)

(( TComponent *) Target)->Name;

}

Технология Drag&Doc

Общие сведения

В VCL библиотеке реализована также технология перетаскивания и встраивания оконных объектов (Drag&Doc).

Приемник, способный принимать переносимые компоненты (клиенты), принято называть контейнером. Если для оконного компонента установить свойство DockSite = true, то он становится контейнером. Свойство приемника UseDockManager = true определяет автоматическое встраивание клиента в приемник. Это не всегда желательно, так как размер и выравнивание компонент в приемнике тоже выбираются автоматически.

Для потенциальных клиентов следует установить свойство DragKind = dkDock. DragMode = dmAutomatic означает, что процесс перетаскивания начинается автоматически.

Для создания тестового примера следует начать новое приложение и разместить на форме один компонент-панель (Panel1) и два компонента класса Image (Image1 и Image2), загрузить в эти компоненты изображения из битовых файлов (свойство Picture). Следующие упражнения помогут разобраться в значениях свойств:

Установить для Form1 и Panel1 свойство DockSite = true; для Image1, Image2 DragKind=dkDock, а DragMode = dmAutomatic. Протестировать приложение.

Дополнительно для Panel1 установить UseDockManager = true. Протестировать приложение.

На рисунке показана картинка в состоянии плавающего окна и размещенная в компоненте Panel1. Перевести размещенный компонент в состояние плавающего окна можно и в процессе выполнения программы. Метод ManualFloat имеет единственный параметр типа TRect, который определяет положение и размещение плавающего окна.

void __fastcall TForm1::Button1Click(TObject *Sender)

{

TRect temp;

temp.Left=Form1->Left+30;

temp.Top=Form1->Top+40;;

temp.Right=temp.Left+200;

temp.Bottom=temp.Top+100;

Image2->ManualFloat(temp);

}

Следующий код плавающий объект размещает на форме:

void __fastcall TForm1::Button2Click(TObject *Sender)

{

TRect temp;

TPoint p;

p=Image2->ClientToScreen(Point(0,0));

temp.Left=p.x;

temp.Top=p.y;

p=Image2->ClientToScreen(Point(160,80));

temp.Right=p.x;

temp.Bottom=p.y;

Image2->ManualFloat(temp);

Image2->ManualDock(Form1,NULL,alLeft);

}

Если при создании формы в обработчике OnCreate разместить следующие операторы, то можно будет свободно перемещать картинки мышью по форме, а за пределами формы, когда картинки будут помещены в самостоятельно плавающие окна, можно будет изменять их размеры.

void __fastcall TForm1::FormCreate(TObject *Sender)

{

TRect temp;

TPoint p;

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5137
Авторов
на СтудИзбе
440
Средний доход
с одного платного файла
Обучение Подробнее