Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Перетаскивание компонентов в окне приложения




Часто возникает задача перемещения некоторого объекта (одного или нескольких) по форме. Технология перетаскивания (drag and drop – перетащи и оставь) позволяет зацепить мышью визуальный объект на экране и перетащить его в другое место. Решить задачу перемещения можно несколькими способами.

Способ первый. Его суть заключается в том, что свойства Left и Top объекта изменяются на разницу между начальными и конечными координатами (нажатия и отпускания мыши соответственно, рис. 1.3). Этот способ самый простой и надежный, но у него есть один недостаток: Left и Top изменяются по очереди, что приводит к заметному мерцанию.

Рис. 1.3. Положение курсора мыши в координатной системе объекта

Начнем создавать приложение, в котором будем перемещать два объекта Image по форме.

Разместим на форме два компонента Image и вставим в них разные картинки (рис. 1.4). Для адекватного отображения картинок свойство Proportional компонентов Image установим в значение true.

Рис. 1.4. Два компонента Image размещены на форме

Для начала необходимо объявить глобальные переменные (они объявляются в разделе Implementation) x0, y0: integer - они будут запоминать координаты начального положения перемещаемой картинки. И еще нам понадобится переменная drag типа boolean, чтобы нам отличать перемещение мыши над картинкой, от попытки ее сдвинуть:

Implementation

{$R *.dfm}

Var

x0, y0: integer; //начальные координаты картинки

drag: boolean = false;//определяет режим буксировки

//она будет устанавливаться в True

//вначале и в False в конце

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

О том, что на Image щелкнули мышью, можно узнать, например, обрабатывая событие OnMouseDown, возникающее при опускании вниз кнопки мыши. Для этого в инспекторе объектов компоненты Image1 откроем вкладку Events и два раза щелкаем мышью в пустом поле OnMouseDown. Появится шаблон процедуры:

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

Begin

 

end;

Рассмотрим входные параметры этой процедуры. Объект, на котором была нажата клавиша мыши, представлен параметром Sender. Это имя предлагает Delphi, сгенерировав заготовку процедуры. Sender[2] – объект, пославший системе сообщение, что на нем щелкнули мышью (в нашем случае Image1). Параметры Shift и Button служат соответственно для контроля нажатия управляющих клавиш клавиатуры Ctrl, Alt, Shift, и левой, правой, средней (колесика) клавиш мыши. Список входных параметров процедуры завершают координаты X и Y курсора мыши внутри компоненты Sender. На рис. 1.3 показано положение курсора мыши в координатной системе фигуры.

В появившемся обработчике необходимо разрешить перемещение, если была нажата левая кнопка мыши, а также запомнить первоначальные координаты курсора мыши:

if Button=mbLeft

then begin //если нажата левая кнопка мыши

x0:=x; //запоминаем первоначальные

y0:=y; //координаты курсора

drag:=true; //перемещение началось

//методом BringToFront выдвигаем компонент

//в котором произошло событие не передний план

(Sender as TImage).BringToFront;

End

else //если нажата не левая кнопка мыши

drag:=false; //нет перемещения

В обработчике проверяется, нажата ли именно левая кнопка мыши, затем запоминаются координаты мыши именно в этот момент. Задается режим буксировки – переменная drag:=true. Инструкция (Sender as TImage).BringToFront выдвигает методом BringToFront компонент, в котором произошло событие, на передний план. Это позволит ему в дальнейшем перемещаться поверх других аналогичных компонентов.

Используемый здесь знак операции Sender as TImage называется приведением объекта Sender к типу TImage. Ее можно записать по-другому: TImage(Sender). Если в этом обработчике использовать вместо Sender вполне конкретный компонент Image1 (поскольку создаваемая процедура обрабатывает нажатие мыши на Image1), то ее нельзя будет использовать для обработки нажатия клавиши мыши, когда курсор расположен над Image2. Но при нажатии мыши на обоих компонентах (Image1 и Image2) должно произойти одно и то же, поэтому используем обобщенный описатель Sender, представляющий объект, на котором щелкнули мышью.

После создания процедуры TForm1.Image1MouseDown необходимо настроить на нее обработчик нажатия клавиши мыши для компонента Image2. Для этого в инспекторе объектов компоненты Image2 откроем вкладку Events и из раскрывающегося списка напротив события OnMouseDown выбираем созданный обработчик Image1MouseDown.

Во время перетаскивания компонента над формой (или над другим компонентом), а также при отпускании кнопки, у формы (или другого компонента) возникает событие: OnDragOver, в котором мы должны указать форме (или другому компоненту), принимать ли нет компонент, находящийся над ней (в нашем случае Image).

Создадим для формы обработчик событий OnDragOver и в нем разрешим принимать только компонент Image, написав такую строку:

//разрешаем принимать только компонент Image

Accept:=Source is TImage;

При буксировке объекта удобно наблюдать его перемещение вслед за курсором мыши. Для реализации изменения положения компонента Image1 при каждом изменении положения курсора воспользуемся обработчиком события перемещения мыши onMouseMove.

В инспекторе объектов компоненты Image1 откроем вкладку Events и два раза щелкаем мышью в пустом поле onMouseMove. Появившийся шаблон процедуры заполним следующим образом:

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

Begin

if drag

Then

with TImage(Sender) do

Begin

Left:=Left+x-x0;

Top:=Top+y-y0

End

end;

Вместо двух инструкций Left:=Left+x-x0; Top:=Top+y-y0 можно было обойтись одно командой: SetBounds(Left + X - X0, Top + Y - Y0, Width, Height). Метод SetBounds изменяет координаты левого верхнего угла на величину сдвига курсора мыши (X - X0 для координаты X и Y - Y0 для координаты Y). Тем самым поддерживается постоянное расположение точки курсора в системе координат компонента, т.е. компонент перемещается вслед за курсором. Ширина Width и высота Height компонента остаются неизменными.

После создания процедуры TForm1.Image1MouseMove необходимо настроить на нее обработчик перемещения мыши над компонентом Image2. Для этого в инспекторе объектов компоненты Image2 откроем вкладку Events и из раскрывающегося списка напротив события OnMouseMove выбираем созданный обработчик Image1MouseMove.

По окончании буксировки, когда пользователь отпустит кнопку мыши, наступит событие, обработчик которого onMouseUp должен содержать всего один оператор:

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin drag:=false; end;

Этот оператор указывает приложению на конец буксировки. Тогда при последующих событиях onMouseMove их обработчик перестанет изменять координаты компонента.

После создания процедуры TForm1.Image1MouseUp необходимо настроить на нее обработчик отцепления мыши над компонентом Image2.

 

Пример 2. Создадим приложение, в котором перед появлением главного окна возникает заставка, состоящая из логотипа (картинки) и индикатора процесса загрузки.

Создадим новый проект командой меню File/New/Application, и присвоим главной форме имя fmMain. Разместим на ней компонент Timer категории System. Добавим в проект еще одну форму (это окно и будет заставкой) и присвоим ее свойствам значения согласно табл. 1.1.

Таблица 1.1. Свойства проектируемой splash- формы

Свойство Установленное значение Назначение изменения
Name fmSplash Новое имя формы
BorderStyle bsNone Форма без заголовка и границы
FormStyle fsStayOnTop Форма всегда размещается поверх других окон
ClientHeight 320 Клиентская высота формы
Position poDesktopCenter Форма размещается по центру экрана
ClientWidth 300 Клиентская ширина формы

Сохраним модуль формы fmMain под именем Main_un.pas, модуль формы fmSplash— под именем Splash_un.pas, а сам проект — под именем Main. В каталог с проектом поместим файл Логотип.jpg с изображением, которое будет являться логотипом программы, размером 300x300.

Теперь разместим на форме fmSplash компонент ProgressBar категории Win32 (используется для отображения процесса) и присвоим его свойству Name значение pbSplash, свойству Align — значение alBottom, а свойству Мах — значение 5.

Разместим на форме fmSplash компонент Image категории Additional, присвоим его свойству Align значение alClient (заполняет всю форму), свойству Proportional — значение true, свойству Align — значение alBottom, свойству Center — значение true, в свойстве Picture укажем в качестве отображаемого файла файл Логотип.jpg.

Далее внесем изменения в содержимое файла-проекта. Для этого выполним команду меню Project/View Soursce и внесем туда немного изменений, так чтобы код стал следующим:


[1] В качестве идентификатора области можно было использовать тип HRGN

[2] Send по-английски означает «посылать»

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...