- •Объект Debug и его методы
- •Метод Print
- •Метод Assert
- •Доказательство правильности программ
- •Условная компиляция и отладка
- •Директива #const
- •#If … Then … #Else директива
- •Ошибки периода выполнения и их обработка
- •Модель управления ошибками в языке vba.
- •Оператор On Error
- •Оператор Resume
- •Объект Err
- •Метод Clear
- •Метод Raise
- •Класс и обработка ошибок
- •Обработчики ошибок и вложенные вызовы процедур
- •Структура обработчика ошибок
- •Функция CvErr
- •Оптимизация программ
- •Приемы оптимизации кода
- •Объявление переменных
- •Математические операции
- •Строковые операции
- •Проектирование интерфейса. Меню
- •Общие объекты Office 2000
- •Коллекция CommandBars
- •Свойства и методы коллекции CommandBars
- •Свойства и методы объекта CommandBar
- •Коллекция CommandBarControls и ее элементы
- •О роли интерфейса
- •Создание собственных и модификация встроенных меню
- •Немного терминологии
- •Возможности настройки и изменения системы меню
- •Создание собственного головного меню
- •Использование диалогового окна Настройка
- •Создание меню с помощью vba
- •Добавление выпадающих меню
- •Использование диалогового окна Настройка
- •Как добавить встроенное меню
- •Добавление выпадающего меню с помощью vba
- •Добавление подменю
- •Вставка и группировка команд
- •Добавление встроенной команды с помощью окна Настройка
- •Добавление собственной команды с помощью окна Настройка
- •Добавление команд с помощью vba
- •Пример построения документа с собственным меню
- •Группировка команд меню
- •Удаление команд меню
- •Удаление команды с помощью окна Настройка
- •Удаление команды с помощью vba
- •Как восстановить удаленные встроенные компоненты меню
- •Изменение меню во время работы программы
- •Вывод собственной панели меню
- •Динамическое изменение видимости команд меню
- •Управление доступом к командам меню
- •Переименование команды меню
- •Диалоговые окна и элементы управления
- •Общие сведения и применение
- •Встроенные диалоговые окна Коллекция Dialogs и объект Dialog
- •Вывод сообщений. Функция MsgBox
- •Окно ввода данных. Функция InputBox
- •Создание пользовательских диалоговых окон
- •Создание страниц и вкладок в диалоговых окнах
- •Добавление дополнительных элементов управления
- •Пример создания диалогового окна
- •Разработка процедур, обрабатывающих события диалогового окна и его устройств
- •Вызов собственного диалогового окна
- •Установка начальных значений свойств элементов управления
- •Использование Me в качестве имени текущего диалогового окна
- •Модификация управляющих элементов во время работы
- •Управление доступом к элементу
- •Перемещение фокуса на элемент управления
- •Изменение размеров диалогового окна
- •Проверка корректности данных
- •Обмен данными с диалоговым окном
- •Закрытие диалогового окна
- •Объект UserForm (диалоговое окно), коллекция UserForms (диалоговые окна)
- •Коллекция Controls
- •Объекты - элементы управления Перечень основных элементов управления
- •Общие свойства элементов управления Объект-родитель
- •Имя объекта
- •Значение объекта
- •Расположение объекта
- •Параметры внешнего вида объекта
- •Свойства поведения объекта
- •Другие свойства
- •CheckBox - флажок (кнопка выбора)
- •ComboBox - комбинированный список
- •CommandButton - командная кнопка
- •Frame - рамка (группы)
- •Image - изображение
- •Label - метка (надпись, статический текст)
- •ListBox - список
- •MultiPage - набор страниц
- •OptionButton - кнопка-переключатель
- •ScrollBar - полоса прокрутки
- •SpinButton - счетчик
- •TabStrip - полоса вкладок
- •TextBox - поле ввода (окно редактирования)
- •ToggleButton - выключатель
- •Объект DataObject
- •Перемещение объектов. Как реализовать технику DragAndDrop
- •События Событие AddControl (добавился элемент)
- •Событие AfterUpdate (После модификации)
- •Событие BeforeDragOver (Перед завершением перетаскивания)
- •Событие BeforeDropOrPaste (Перед опусканием или вставкой)
- •Событие BeforeUpdate (Перед модификацией)
- •Событие Change (Изменение)
- •Событие Click (Щелчок)
- •Событие DblClick (Двойной щелчок)
- •Событие DropButtonClick (Щелчок кнопки списка)
- •События Enter, Exit (Вход, Выход)
- •Событие Error (Ошибка)
- •События KeyDown, KeyUp (Клавиша нажата, Клавиша отпущена)
- •Событие KeyPress (Клавиша нажата)
- •Событие Layout (Расположение)
- •События MouseDown, MouseUp (Мышь нажата, Мышь отпущена)
- •Событие MouseMove (Мышь движется)
- •Событие RemoveControl (Удаление элемента)
- •Событие Scroll (Прокрутка)
- •События SpinDown (Уменьшить счетчик), SpinUp (Увеличить счетчик)
- •Событие Zoom (Расширение)
- •Методы Метод Add (Добавить)
- •Метод AddItem (Добавить элемент)
- •Метод Clear (Очистить)
- •Метод Copy (Копировать)
- •Метод Cut (Вырезать)
- •Метод DropDown (Вывести список)
- •Метод Move (Сдвинуть)
- •Метод Paste (Вставить)
- •Реализация операций Cut, Copy, Paste в диалоговых окнах
- •Метод RedoAction (Повторить действие)
- •Метод Remove (Удалить)
- •Метод RemoveItem (Удалить элемент)
- •Метод Repaint (Перерисовать)
- •Метод Scroll (Прокрутить)
- •Метод SetDefaultTabOrder (Установить стандартный порядок обхода)
- •Метод SetFocus (Установить фокус)
- •Метод UndoAction (Отменить действие)
- •Реализация операций Undo и Redo в диалоговых окнах
- •Метод zOrder (z-упорядочить)
- •Основные виды файлов в Office 2000
- •Открытие и создание файлов
- •Закрытие файлов
- •Запись в файлы последовательного доступа
- •Чтение файлов последовательного доступа
- •Ввод-вывод для файлов произвольного доступа и бинарных файлов
- •Работа с данными переменной длины
- •Один пример работы с Binary файлом
Перемещение объектов. Как реализовать технику DragAndDrop
При организации интерфейса в диалоговых формах зачастую полезно предоставить пользователю возможность использовать технику DragAndDrop (Переместить и Опустить), когда некоторый объект захватывается мышью, перетаскивается к другому целевому объекту и при опускании изменяет свойства целевого объекта. Типичным примером является возможность перетаскивания элементов из одного списка в другой. Другим примером является перетаскивание писем и опускание их в почтовый ящик. Важным элементом этой техники является изменение внешнего вида курсора. Захват объекта происходит при подведении курсора к объекту и нажатии левой кнопки мыши, В этот момент курсор меняет свою внешнюю форму. Затем, когда происходит перемещение мыши, то в тех областях, где расположен целевой объект, курсор снова меняет форму, показывая, что цель достигнута. Если в этот момент, отпустить левую кнопку, то операция перемещения заканчивается успешно, отпускание кнопки мыши в других областях приводит к неуспеху. Объект DataObject и его метод StartDrag является частью этой технологии работы. Достаточно сложно понять суть этого метода, не разобравшись и в остальных частях этой технологии, в частности, в целом ряде событий, возникающих в процессе перетаскивания.
О событиях пойдет речь чуть далее, а начнем рассмотрение все-таки с метода StartDrag, который инициирует операцию перетаскивания объекта DataObject, хранящего перетаскиваемую информацию. Но прежде стоит рассмотреть пример, на котором весь этот процесс будет объясняться. Будем рассматривать диалоговое окно, имеющее два элемента ѕ список и окно ввода. Список будет содержать цвета, а текстовое окно ввода ѕ цвет, любимый пользователем. Пользователь имеет возможность выбрать любой из элементов списка и перетащить его в окно ввода. Когда пользователь захватывает выбранный им элемент списка, то возникает некоторое событие. В нашем примере это событие MouseMove, обработчик которого и будет вызывать метод StartDrag объекта DataObject, хранящего значение перетаскиваемого элемента. Теперь, когда, хотя бы частично, прояснена ситуация, предшествующая вызову метода, рассмотрим его синтаксис:
Function StartDrag ([Effect As fmDropEffect]) As fmDropEffect
Эта функция обычно вызывается в операторе присваивания вида:
ResultEffect=объект. StartDrag ([Effect as fmDropEffect])
Необязательный параметр Effect и результат выполнения функции принадлежат перечислению fmDropEffect. Константы, входящие в это перечисление имеют следующие значения:
-
fmDropEffectNone = 0 - не копировать и не передвигать опущенный исходный элемент на место назначения,
-
fmDropEffectCopy = 1 - копировать опущенный исходный элемент на место назначения,
-
fmDropEffectMove = 2 - передвинуть опущенный исходный элемент на место назначения,
-
fmDropEffectCopyOrMove = 3 - скопировать или передвинуть опущенный исходный элемент на место назначения.
Параметр Effect задает цель операции и имеет по умолчанию значение 1 (fmDropEffectCopy). Обычно он опускается, поскольку значение по умолчанию задает наиболее вероятную цель операции. Возвращаемое методом StartDrag значение определяет результат выполнения операции. Его можно использовать для анализа того, что же произошло в результате перетаскивания на самом деле. Важно только понимать, что между запуском метода StartDrag в правой части оператора присваивания и присваиванием результата левой части переменной ResultEffect происходит много событий в процессе перемещения объекта, работают обработчики этих событий и результат говорит о том, как закончился этот процесс.
Вот как выглядит спроектированное нами диалоговое окно "Поле и Список" в процессе работы с ним:
Рис. 13. 6. Окно "Поле и Список" в процессе работы
В этом диалоговом окне пользователь имеет возможность выбрать произвольный элемент списка "Цвета" и перетащить его мышью в поле "Любимый цвет"
Рассмотрим обработчики событий, поддерживающие процесс перетаскивания. Начнем с обработчика события Initialize для диалогового окна, обеспечивающего инициализацию начального состояния:
Private Sub UserForm_Initialize ()
With Me. DraggedList
. AddItem "Красный"
. AddItem "Оранжевый"
. AddItem "Желтый"
. AddItem "Зеленый"
. AddItem "Голубой"
. AddItem "Синий"
. AddItem "Фиолетовый"
. AddItem "Черный"
. AddItem "Белый"
End With
End Sub
Здесь инициализируется список "Цвета", имеющий имя DraggedList. Когда пользователь, выбирая элемент этого списка, нажимает левую клавишу мыши, готовясь перетащить этот элемент в другое место, у списка возникает событие MouseMove, обработчик которого имеет много параметров. Описание этого события, всех его параметров, описание других используемых нами событий, будут даны в последующих параграфах, а сейчас приведем текст этого обработчика:
Private Sub DraggedList_MouseMove (ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
Dim MyDataObject As DataObject
Dim Msg As String
Msg = "Видимо, Вы уронили цвет при перетаскивании. Повторите операцию!"
If Button = 1 Then
Debug. Print "MouseMove"
Set MyDataObject = New DataObject
Dim Effect As Integer
MyDataObject. SetText DraggedList. Value
Effect = MyDataObject. StartDrag (fmDropEffectCopy)
If Effect = 0 Then MsgBox (Msg)
Debug. Print "Effect = ", Effect
End If
End Sub
О параметрах, как уже говорилось речь пойдет впереди, а сейчас прокомментируем его работу. Если в момент возникновения события нажата левая кнопка мыши, то создается новый объект DataObject, его метод SetText копирует значение выбранного элемента списка, а метод StartDrug запускает процесс перетаскивания. Заметьте, что метод StartDrug можно было бы вызывать без параметра, ѕ на результат это не повлияло бы. Результат перетаскивания анализируется и, если он закончился неуспехом (Effect = 0), то выдается уведомляющее сообщение. Исполняемые операторы окаймлены отладочной печатью, что позволит нам продемонстрировать, что между первой печатью, уведомляющей о начале работы обработчика MouseMove, и последней печатью, уведомляющей о результате работы, будут напечатаны сообщения других обработчиков, к рассмотрению которых мы и переходим.
Событие BeforeDragOver возникает для объекта TextIn (поле ввода "Любимый цвет"), когда курсор в процессе перетаскивания попадает в область, занятую объектом. Заметьте, событие возникает многократно, поскольку курсор находится в этой области некоторое время. Вот текст обработчика этого события:
Private Sub TextIn_BeforeDragOver (ByVal Cancel As MSForms. ReturnBoolean, _
ByVal Data As MSForms. DataObject, ByVal X As Single, _
ByVal Y As Single, ByVal DragState As MSForms. fmDragState, _
ByVal Effect As MSForms. ReturnEffect, ByVal Shift As Integer)
Cancel = True
Effect = fmDropEffectCopy
Debug. Print "DragOver"
End Sub
Заметьте, основное, что делает этот обработчик, он устанавливает значение параметра Effect. Поскольку эффект совпадает с целевым эффектом, то курсор в области, занятой полем TextIn, будет менять свою форму, принимая вид прямоугольника со знаком "+", указывающим, что цель достигнута и можно отпустить левую клавишу мыши. Завершающий оператор отладочной печати позволит проследить за числом вызовов этого обработчика.
Следующее событие для объекта TextIn возникает, когда отпущена левая клавиша мыши в области этого объекта. Вот его обработчик:
Private Sub TextIn_BeforeDropOrPaste (ByVal Cancel As MSForms. ReturnBoolean, _
ByVal Action As MSForms. fmAction, ByVal Data As MSForms. DataObject, _
ByVal X As Single, ByVal Y As Single, ByVal Effect As MSForms. ReturnEffect, _
ByVal Shift As Integer)
Cancel = True
Effect = fmDropEffectCopy
TextIn. Text = Data. GetText
Debug. Print "DragPaste"
End Sub
Здесь также возвращается значение эффекта. Главное, завершается операция перетаскивания копированием текста в поле ввода из переданного в качестве параметра объекта Data класса DataObject, хранящего значение цвета, выбранного пользователем.
Совместная работа этих трех обработчиков событий и вызываемые в них методы объекта DataObject - SetText, GetText, StartDrag - обеспечивают в совокупности технику DragAndDrop. В заключение о двух экспериментах при работе с диалоговым окном. Вначале, мы не донесли выбранный нами цвет до окна ввода, отпустив левую клавишу мыши на дороге к нему. Вот как выглядело сообщение, полученное нами:
Рис. 13.7. Сообщение о потере объекта при перетаскивании
Затем повторно выбранный нами зеленый цвет был успешно перетащен в окно "Любимый цвет". Приведем отладочную печать этих двух экспериментов:
MouseMove
Effect = 0
MouseMove
DragOver
DragOver
DragOver
DragPaste
Effect = 1
Первые две строчки связаны с неудачной попыткой переноса, когда эффект был нулевым. Следующие строки описывают успешный эксперимент. Заметьте, что между печатью, информирующей о начале работы обработчика MouseMove и его заключительной печатью об успешном эффекте, вклинились сообщения, поступающие от обработчиков событий DragOver и DropOrPaste. Заметьте, я оставил только три сообщения от обработчика DragOver, реально их было 25. На этом описание примера заканчивается, но разговор о событиях еще предстоит.