Тотальная неудачница и убийца жёстких дисков.
#post-id: 2758-23-07
#original-date: 13.02.2008 Wed
#original-time: 11:07 PM
#original-day:  2758
#original-host: WinXP Prof SP2 (Build 2600)

Откопала возможность VB, вокруг которой ходила чёрт знает сколько. А ведь круто же! Итак. Мы хотим чтобы нам в коно можно было бросить текст или ссылку из IE. А потом ещё какой текст можно было бы перетащить в тот же Word. Думаете сложно? Я тоже так думала, но для одной программки потребовалось, и я решила попробовать.

Кстати, судя по всему, так можно таскать не только текст и картинки, но и файлы из Проводника. И это без всяких DragAcceptFiles. Всё встроенными средствами. Но это я буду пробовать в будущих проектах ^_^ А DDD может попробовать это уже сейчас для улучшения замены Дисигна ^_~

Итак. Форма, а на ней ни чего не будем размещать - будем делать простой пример с коментариями. Ни чего особенного для неё делать не нужно, желательно только чтобы она выводилась на панели задач - так таскать удобнее, если окно скрыто: тащим что-то сначала на кнопку, держим там (не отпускаем!), форма появляется, а потом тащим это что-то на форму.

Сначала скажем форме, что мы будем принимать OLE объекты. Это можно сделать через свойства формы во время конструирования, но я, чтобы не забыть ни чего, пишу в коде:

Private Sub Form_Load()
 Me.OLEDropMode = vbOLEDropManual
End Sub



Если сейчас потащить что-то на форму, можно увидеть, что возле стрелочки появился плюсик. Но давайте будем обрабатывать броски ^_^

Private Sub Form_OLEDragDrop(Data As DataObject, _
                            Effect As Long, _
                            Button As Integer, _
                            Shift As Integer, _
                            X As Single, _
                            Y As Single)
 ParseOLEData Data, Effect
End Sub

Private Sub ParseOLEData(ByRef Data As DataObject, _
                        ByRef Effect As Long)
 Const CF_TEXT = 1
 Const CF_UNICODETEXT = 13
 
 On Error Resume Next
 
 If Data.GetFormat(CF_UNICODETEXT) Then
   MsgBox Data.GetData(CF_UNICODETEXT)
   Effect = vbDropEffectCopy
 ElseIf Data.GetFormat(CF_TEXT) Then
   MsgBox Data.GetData(CF_TEXT)
   Effect = vbDropEffectCopy
 Else
   Effect = vbDropEffectNone
 End If
End Sub



Объект Data похож на объект Clipboard и работает похожим образом. Константы форматов я определила сама чтобы иметь возможность получить Unicode текст, чтобы в XP не было глюков с кодировкой. В Win9x этого нет, так что дальше я пытаюсь получить ANSI текст.

Параметр Effect, я так поняла, указывает, что мы сделали с объектом. На всякий пожарный я говорю, что мы его скоприровали себе. Я так полагаю, что если мы вернём константу vbDropEffectMove, то источник просто удалит у себя эти данные.

Как видите, мы просто выводим на экран полученный текст, но на самом деле его можно помещать в тот же текстбокс. Кстати, OLEDropMode должно быть установлено для всех элементов, на которые можно будет бросать (в том числе и для Label), и для каждого бросок обрабатывается отдельно (поэтому я сделала отдельную функцию).

Хорошо. А теперь мы захотим некий текст перенести в какой-нибудь Word? /* Тут замечу, что IE копирует нам больше форматов, так что сама ссылка имеет другой формат. Поэтому CF_TEXT он не принимает как URL. Тут я пока не разбиралась... Но мне поможет утилита IDataObject Viewer, которая как раз и показывает все форматы ^^ */ Тогда делаем это:

Private Sub Form_MouseDown(Button As Integer, _
                          Shift As Integer, _
                          X As Single, _
                          Y As Single)
 DoDrag
End Sub

Private Sub DoDrag()
 On Error Resume Next
 
 Me.OLEDropMode = vbOLEDropNone
 
 Me.OLEDrag
 If Err.Number <> 0 Then Beep
 
 Me.OLEDropMode = vbOLEDropManual
End Sub



Здесь мы сообщили что надо начать перетаскивать объект. Заметьте, что начало мы инициируем при нажатии кнопки мыши ^^ В случае ошибки просто выдаём сигнал. Отключение приёма перетаскиваемых объектов я сделала для того чтобы нельзя был простым щелчком по форме перетащить файл на самого себя.

Но настоящая работа начинается ниже:

Private Sub Form_OLEStartDrag(Data As DataObject, _
                             AllowedEffects As Long)
 Dim xData() As Byte
 
 AllowedEffects = vbDropEffectCopy
 
 xData = "Byaka!" & vbNullChar
 Data.SetData xData, CF_UNICODETEXT
 Data.SetData "Byaka!", CF_TEXT
End Sub



Это событие вызывается при вызове метода OLEDrag. Здесь мы добавляем данные для переноски и указываем что с ними можно будет делать. Кстати, от значение AllowedEffects будет зависеть вид курсора ^^ Как видите, мы тут добавляем просто текст и юникод. Так как CF_UNICODETEXT не является поддерживаемым VB форматом, мы должны передать его как байтовый массив, а в конце должен быть NULL.

Вот, собственно, и всё. Есть другие события, но я их не рассматривала. Скажу только что вроде как узнать что сделало целевое приложения с данными (что записало в Effect как мы в самом начале) можно в событии OLECompleteDrag.

Да, и файлы из проводника перечисляются в свойстве Files класса DataObject.

#music: Jean Love\Initial D Fourth Stage D Selection 2\Steel Blade