Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Private Sub Text3_DragDrop(Source As Control, X As Single, Y As Single)






Координаты мыши X и Y нас сейчас мало интересуют, все равно VB сам определит, перетащили мы объект на Text3 или нет. А вот аргумент Source мы используем. С его помощью и ключевого слова TypeOf мы проведем проверку типа объекта (то что мы перетаскиваем Text в Text, а не Text в Picture) и присобачив к нему свойство .Text изменим содержимое Text3. Это и будет результат перетаскивания.

If TypeOf Source Is TextBox Then
Text3.Text = Source.Text
End If
End Sub

Теперь ты можешь опробовать результат, запустив проект и поперетаскивать в Text3 и Text1 и Text2. Если ты не смог написать эти пятнадцать строк кода самостоятельно, то скачать исходник примера можешь здесь.
Откровенно говоря в данном случае ключевое слово TypeOf притянуто за уши, так как других объектов на форме нет. Однако, проверять, соответствует ли тип данных передатчика типу данных приемника все-таки надо.
Можно вместо этого проверять конкретно каждый элемент и присваивать значение того, которого захотим. Для идентификации элемента есть простенькое свойство Tag. Смысл его в том, что по нему с помощью аргумента Source мы можем однозначно идентифицировать объект-источник. В отличие от других свойств, значение свойства Tag не используется языком Visual Basic, но его можно использовать для идентификации объектов. Этому свойству мы можем присвоить любое имя-идентификатор, главное, чтоб они не были одинаковыми. Для этого в процедуру Form_Load допишем две строчки:

Text1.Tag = " Text один"
Text2.Tag = " 002"

Теперь наша процедура Text3_DragDrop будет выглядеть следующим образом:

Private Sub Text3_DragDrop(Source As Control, X As Single, Y As Single)
If Source.Tag = " Text один" Or Source.Tag = " 002" Then
Text3.Text = Source.Text
End If
End Sub

Опять же, если чего не получилось, скачать эту фигню можно здесь.

Теперь рассмотрим результаты нашей деятельности. Юзер кайфует, радостно перетаскивая текст из одного объекта в другой. Это несомненно хорошо. Потом юзеру надоедает это делать и он с удивлением обнаруживает тот факт, что отредактировать-то текст он не может ни в Text1, ни в Text2. Это несомненно плохо. А дело в том, что инициируемые юзером события мыши или клавиатуры KeyDown, KeyPress, KeyUp, MouseDown, MouseMove и MouseUp распознаваться НЕ БУДУТ!
Видя такое дело, нам целесообразно перейти к более сложному, но и более контролируему делу - ручному перетаскиванию.

Метод Drag - ручное перетаскивание.

Этот метод начинает, завершает или отменяет операцию перетаскивания любого из элементов управления кроме Line, Menu, Shape, Timer и CommonDialog. Он позволит нам не блокировать объект для редактирования, использовать всевозможные иконки, чтоб юзер видел, что творит при перетаскивании и вообще правильный метод.
Еще раз напоминаю очень важную вещь, если ты не понял из предыдущего: результат перетаскивания над перемещаемым объектом (копирование, удаление, вставка и т.д.) определяется в объекте-приемнике в процедуре обработки события DragDrop.
Итак, для того, чтобы начать чего-нибудь перетаскивать, надо перейти в режим перетаскивания. Для этого обычно используется процедура события MouseDown для объекта-источника. В ней мы включаем метод Drag. Для включения-выключения метода и отмены перетаскивания используются следующие константы, их объявлять не надо:

vbCancel =0 'отменяет операцию перетаскивания
vbBeginDrag =1 'включает метод Drop
vbEndDrag =2 'выключает метод Drop

Давай-ка лучше сделаем новый exe-проект и попробуем все на практике. Наш новый проект мало чем отличается от старого по внешнему виду, но не по коду. На форме у нас будут Text1, Text2, Text3 и еще кнопка Command1. Смысл проекта в том, чтобы перетаскивать содержимое Text1 в Text3, а Text2 запрещен для перетаскивания. И для прикола, потаскаем по форме командную кнопку Command1. Итак, начнем.
Объявим переменную Flag как булеву. На фига я ее ввожу? Ну не знаю, чтобы позволить юзеру беспрепятственно редактировать текст в объекте-источнике, т.е в Text1. Т.е. изначально Flag=False и при первом щелчке метод Drag в процедуре Text1_MouseDown не включается. Юзер спокойно может редактировать текст. Но в конце процедуры Flag меняет свое значение на противоположный (Flag = Not Flag) и при повторном нажатии кнопки мыши уже включается метод Drag.

Option Explicit
Dim Flag As Boolean

В процедуре загрузки формы зададим какое-нибудь содержимое TextBox'ам (можем и не задавать и вообще наплевать на нее):

Private Sub Form_Load()
Text1.Text = " Это какой-то текст, записанный в Text1"
Text2.Text = " А я вообще не знаю, что здесь делаю"
Text3.Text = " А это другой текст, записанный в Text3"
End Sub

Далее в событии MouseDown для объекта-источника Text1 включим метод Drag для левой кнопки мыши. И меняем состояние переменной Flag:

Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
'проверяем, если нажата левая кнопка мыши и это повторное нажатие то
If Button = vbLeftButton And Flag = True Then
'включаем метод Drag
Text1.Drag vbBeginDrag
'загружаем общую иконку для курсора в виде молнии. Она будет обозначать,
'что объект готов к перетаскиванию
Text1.DragIcon = LoadPicture(App.Path & " \Move.ico")
End If

'меняем значение флага на противоположное
Flag = Not Flag

End Sub

В объекте-приемнике по событию DragDrop производим результат перетаскивания, т.е. присваиваем значение Text3=Text1. При этом проверяем тип объекта-источника:

Private Sub Text3_DragDrop(Source As Control, X As Single, Y As Single)
'проверяем, соответствует ли тип объекта-источника TextBox'у
If TypeOf Source Is TextBox Then
'если да, то
Text3.Text = Source.Text
'и для солидности передадим фокус в объект-приемник (Text3)
Text3.SetFocus
End If

End Sub

Поскольку наглядность перетаскивания для юзера чрезвычайно важна, загрузим иконки в соответствии с положением мыши для объекта-источника (Text1):

Private Sub Text1_DragOver(Source As Control, X As Single, Y As Single, State As Integer)
'если мышь над объектом-источником грузим обычную иконку (молния)
If State = vbEnter Then
Text1.DragIcon = LoadPicture(App.Path & " \Move.ico")
'если покидает объект, то критический треугольник

ElseIf State = vbLeave Then
Text1.DragIcon = LoadPicture(App.Path & " \No.ico")
End If
End Sub

и для объекта-приемника. Причем, обратите внимание, что в процедуре Text3 объекта-приемника мы определяем иконки для объекта-источника (Text1). В противном случае возникнет путаница.

Private Sub Text3_DragOver(Source As Control, X As Single, Y As Single, State As Integer)
'если мышь над объектом-приемником, то листик с кнопкой - готовность принять объект
If State = vbEnter Then
Text1.DragIcon = LoadPicture(App.Path & " \Yes.ico")
'если вне объекта-приемника - то критический треугольник

ElseIf State = vbLeave Then
Text1.DragIcon = LoadPicture(App.Path & " \No.ico")
End If
End Sub

Вот вобщем-то и все. В заключении я хочу показать, что использование проверки типа объекта-источника важна. На этой же форме включим метод Drag для командной кнопки Command1.

Private Sub Command1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
Command1.Drag vbBeginDrag
End If
End Sub

и напишем процедуру ее таскания по форме

Private Sub Form_DragDrop(Source As Control, X As Single, Y As Single)
If TypeOf Source Is CommandButton Then
Source.Move X, Y
End If
End Sub

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

В этой главе мы разобрали технологию Drag& Drop для перетаскивания в пределах одного нашего приложения. Скачать исходник примера можно вверху страницы.
В следующей главе мы попробуем исследовать эту технологию для обмена данных между разными приложениями.

 

Итак, в прошлой главе мы проанализировали технологию Drag& Drop при перетаскивании под управлением событий. Это хорошо при работе внутри нашего проекта. Если же нам необходимо осуществить перетаскивание из окна совсем другого приложения, то навряд-ли мы дождемся наступления какого-нибудь события для нашей формы (или ее объектов), если будем щелкать по чужому окну. Поэтому сейчас мы проанализируем перетаскивание с помощью OLE технологий. Принцип перетаскивания здесь тот же, что и при перетаскивании с использованием событий - есть объект-приемник и объект-источник. Один и тот же объект может быть и приемником и источником (в случае если он используется и для приема и для передачи).
Как и в прошлой главе, начнем с чего попроще - с автоматического перетаскивания.

Автоматическое перетаскивание.

Очень простая и удобная технология. С его помощью мы просто перемещаем содержимое одного объекта в другой объект. Для включения автоматического перетаскивания мы имеем два свойства:

.OLEDropMode - активизирует объект в качестве приемника
  может принимать значения:
  0 (vbOLEDropNone) - Нет
  1 (vbOLEDropManual) - Вручную
  2(vbOLEDropAutomatic) - Авто
.OLEDragMode - активизирует объект в качестве передатчика
  может принимать значения:
  0 (vbOLEDragManual) - Вручную
  1 (vbOLEDragAutomatic) - Авто

Эти свойства можно задавать как в окне свойств, так и программно, в ходе выполнения программы.

Но, к сожалению, не все элементы управления (объекты) поддерживают автоматическое перетаскивание. Некоторые элементы поддерживают оба свойства - и .OLEDropMode и .OLEDragMode, а некоторые - только OLEDragMode. А ряд элементов вообще нельзя использовать для автоматического перетаскивания. Вот элементы и поддерживаемые ими свойства.

Элемент управления с режимом авто (OLE перетаскивание) .OLEDropMode OLEDragMode
ComboBox НЕТ ДА
DBComboBox НЕТ ДА
DBGrid ДА ДА
DBListBox НЕТ ДА
DirecoryListBox НЕТ ДА
FileListBox НЕТ ДА
Image ДА ДА
ListBox НЕТ ДА
ListView НЕТ ДА
MaskedEdit ДА ДА
PictureBox ДА ДА
RichTextBox ДА ДА
TextBox ДА ДА
TreeView НЕТ ДА

Создадим новый exe-проект. Положим на форму PictureBox1 и Image1. Установим программно свойства перетаскивания в автоматический режим:

Private Sub Form_Load()
Picture1.OLEDropMode = vbOLEDropAutomatic 'автоматический прием
Picture1.OLEDragMode = vbOLEDragAutomatic 'автоматическая передача
Image1.OLEDropMode = vbOLEDropAutomatic
Image1.OLEDragMode = vbOLEDragAutomatic
End Sub

Это, собственно, все. Запустим проект. Если теперь мы откроем какую-нибудь картинку в приложении, поддерживающем технологию OLE-перетаскивания (например Photoshop, но при этом должен быть включен инструмент " Двигать" (" Move")), то запросто можем перетащить картинку из него в наш проект и обратно.
Также можно перетаскивать и внутри нашего проекта из Picture1 в Image1 и наоборот. При этом обратите внимание на то, что при перетаскивании нажатой кнопкой мыши картинка в объекте-передатчике уничтожается, т.е. происходит перемещение. Чтобы происходило копирование (картинка сохранялась) перетаскивание надо осуществлять с нажатой кнопкой Ctrl.
При автоматической реализации OLE-технологии Drag& Drop мы не обрабатываем результаты перетаскивания. Картинка (или другие данные) должны быть загружены в объект-передатчик. Т.е. мы не можем, например, перетащить в Image1 иконку графического файла.jpg из проводника Windows в надежде, что этот файл там неожиданно откроется. Поскольку мы программно этого не описали, никаких сюрпризов ждать не приходится.
Для более гибкого (и соответственно более сложного) управления перетаскиванием можно попробовать ручное перетаскивание.

Метод OLEDrag - ручное перетаскивание.

Ручное управление перетаскиванием позволяет программировать различные дополнительные действия. Кроме того с его помощью можно работать с такими элементами управления, не поддерживающими автоматическое перетаскивание, как CommandButton, Label, CheckBox, OptionButton, Frame и DriveListBox.

Итак, приступим. Помимо рассмотренных нами уже свойств .OLEDropMode и .OLEDragMode мы имеем еще целый ряд событий и их нам, как говорится, надо:

 
Private Sub объект_OLEDragDrop(data As DataObject, effect As Long, button As Integer, shift As Integer, x As Single, y As Single) Возникает при перетаскивании объекта-источника в объект-приемник. data - объектDataObject содержит форматы (и возможно данные для этих форматов), которые обеспечивает источник. Если в объекте никаких данных не содержится, то они предоставляются при вызове метода GetData. Методы SetData и Clear использованы быть не могут. effect - число long, устанавливаемое приемником, для опознавания действия, которое выполнено (например удалять или копировать содержимое источника). Может принимать значения следующих констант: 0 (vbDropEffectNone) - приемник не может принять данные 1 (vbDropEffectCopy) - передача копии (исходник источника сохраняется) 2 (vbDropEffectMove) - перемещение данных (исходник источника удаляется) button - соответствует состоянию кнопки мыши. 1 - левая кнопка, 2 - правая и 4 - средняя. shift - указывает состояние кнопок shift, alt и ctrl (1- shift, 2- alt и 4 - ctrl). При удержании больше одной кнопки их значения складываются (ctrl-alt = 4+2=6). Значения переменных x и y возвращают текущие координаты курсора мыши (x - по-горизонтали, y - по-вертикали) в единицах измерения, заданных свойствами ScaleHeight, ScaleWidth.
 
Private Sub объект_OLEDragOver(data As DataObject, effect As Long, button As Integer, shift As Integer, x As Single, y As Single, state As Integer)   Возникает при перетаскивании одного компонента над другим. data - объектDataObject содержит форматы (и возможно данные для этих форматов), которые обеспечивает источник. Если в объекте никаких данных не содержится, то они предоставляются при вызове метода GetData. Методы SetData и Clear использованы быть не могут. effect - число long, устанавливаемое приемником, для опознавания действия, которое выполнено (например удалять или копировать содержимое источника). Может принимать значения следующих констант: 0 (vbDropEffectNone) - приемник не может принять данные 1 (vbDropEffectCopy) - передача копии (исходник источника сохраняется) 2 (vbDropEffectMove) - перемещение данных (исходник источника удаляется) -2147483648 (& H80000000) (VbDropEffectScroll) - происходит или подготавливается прокрутка в приемнике (только при выполнении пользовательской прокрутки в приемнике). button - соответствует состоянию кнопки мыши. 1 - левая кнопка, 2 - правая и 4 - средняя. shift - указывает состояние кнопок shift, alt и ctrl (1- shift, 2- alt и 4 - ctrl). При удержании больше одной кнопки их значения складываются (ctrl-alt = 4+2=6). Значения переменных x и y возвращают текущие координаты курсора мыши (x - по-горизонтали, y - по-вертикали) в единицах измерения, заданных свойствами ScaleHeight, ScaleWidth. state - показывает состояние перетаскиваемого объекта по отношению к форме. Может принимать следующие значения: 0 (vbEnter) - источник в пределах приемника 1 (vbLeave) - источник вне окрестности приемника 2 (vbOver) - источник перемещается в приемнике из одного положения в другое
 
Private Sub объект_OLEGiveFeedback (effect As Long, defaultcursors As Boolean) Происходит после каждого события _OLEDragOver. Позволяет показывать пользователю (например с помощью изменения курсора мыши) ход перетаскивания. effect - число long, устанавливаемое в событии _OLEDragOver, и определяет действие, которое может быть педпринято, если пользователь опускает объект на компонент. Используется для визуализации перетаскивания. Может принимать значения следующих констант: 0 (vbDropEffectNone) - приемник не может принять данные 1 (vbDropEffectCopy) - передача копии (исходник источника сохраняется) 2 (vbDropEffectMove) - перемещение данных (исходник источника удаляется) -2147483648 (& H80000000) (VbDropEffectScroll) - происходит или подготавливается прокрутка в приемнике (только при выполнении пользовательской прокрутки в приемнике). defaultcursors - значение True, если использовать курсор мыши по умолчанию и False, если не использовать. (Курсор может быть установлен свойством.MousePointer объекта Screen)
 
Private Sub объект_OLEStartDrag (data As DataObject, a llowedeffects As Long) Происходит, когда выполняется метод OLEDrag или когда объект инициирует операцию перемещения, если свойство OLEDragMode установлено в значение 1 - авто. data - объектDataObject содержит форматы (и возможно данные для этих форматов), которые обеспечивает источник. Если в объекте никаких данных не содержится, то они предоставляются при вызове метода GetData. Методы SetData и Clear использованы быть не могут. allowedeffect - число long, содержит результаты, поддерживаемые приемником. Значения данного параметра устанавливаются программистом. Может принимать значения следующих констант: 0 (vbDropEffectNone) - приемник не может принять данные 1 (vbDropEffectCopy) - передача копии (источник сохраняется) 2 (vbDropEffectMove) - перемещение данных (источник удаляется)
 
Private Sub объект_OLESetData(data As DataObject, dataformat As Integer) Происходит на источнике, когда приемник выполняет метод GetData на объекте DataObject, но данные указанного формата еще не загружены. data - объектDataObject, в который необходимо поместить запрашиваемые данные. Компонент вызывает метод SetData, чтобы загрузить запрашиваемый формат. dataformat - целое число, уточняющее формат данных. Используется для указания источнику, что загружать в объект DataObject.
 
Private Sub объект_OLECompleteDrag ([ effec t As Long]) Возникает, когда источник опускается на получатель, информируя источник, что операция перетаскивания выполнена или отменена. effect - число long, устанавливаемое источником, позволяющее определить действие, которое выполнено. Может принимать значения следующих констант: 0 (vbDropEffectNone) - приемник не может принять данные 1 (vbDropEffectCopy) - передача копии (источник сохраняется) 2 (vbDropEffectMove) - перемещение данных (источник удаляется)
 

Прочитав этот полубезумный бред, мы не будем впадать в истерику. Нам известна аксиома - " Visual Basic - это не просто просто, а очень просто". Исходя из этой аксиомы, морща лоб от напряжения и пуская слюни от усердия, мы попытаемся сейчас реализовать технологию перетаскивания на раз-два-готово.
Изначально будем считать, что у нас есть наше приложение и некое чужое. Вот между ними мы и будем таскать объекты, как китайские кули.

Итак, указаные выше события возникают каждое на своем объекте:

на стороне объекта-источника на стороне объекта-приемника
OLEStartDrop OLEDragDrop
OLESetData OLEDragOver
OLEGetFeedback  
OLECompleteDrag  

Вроде как на стороне приемника их меньше, вот и начнем с конца. Создадим новый exe-проект и положим на него Picture1 и Text1. В них мы должны перетащить картинку и текст соответственно из неких сторонних приложений. Таким образом, на нашем проекте имеется только объекты-приемники, а формирование на стороне объекта-источника мы оставим на совести чужого приложения. Сперва мы должны инициализировать наши Picture1 и Text1 как объекты-приемники. Для этого мы используем то же свойство .OLEDropMode, что и при автоматическом перетаскивании, только значение его должно быть в этот раз vbOLEDropManual, т.е. ручное. Сделаем это в процедуре загрузки формы (хотя можно и в окне свойств проекта):

Private Sub Form_Load()
Picture1.OLEDropMode = vbOLEDropManual
Text1.OLEDropMode = vbOLEDropManual
End Sub

Зная, что при окончании перетаскивания на стороне приемника возникает событие _OLEDragDrop, используем его для загрузки картинки в Picture1. Но как же нам передать в нашу процедуру, что за картинка у нас, собственно, перетаскивается? А данные об этом хранятся в объекте DataObject. Прежде всего, этот объект позволяет нам проверить, того ли формата данные мы пытаемся загрузить в приемник (Picture1), так как, например, текст в PictureBox загружать не очень хорошо. Для этого объект DataObject имеет метод GetFormat. Его синтаксис следующий:


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.01 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал