Опубликован: 13.09.2006 | Уровень: для всех | Доступ: свободно | ВУЗ: Тверской государственный университет
Лекция 7:

Организация диалога. Объект Assistant

< Лекция 6 || Лекция 7: 12345 || Лекция 8 >
CallBack процедура в немодальном диалоге

Процедура обратного вызова (CallBack)- это такая процедура, которая вызывается системными, а не написанными самим программистом процедурами. Типичная ситуация такова: Программист явно или неявно вызывает системную процедуру, а та, в свою очередь, вызывает CallBack процедуру программиста. Естественно, что для CallBack процедур система определяет форму их вызова - имя процедуры, число и типы формальных параметров (но не их имена, которые могут быть произвольными).

CallBack процедуры необходимы при немодальном диалоге, организованном объектами Balloon. Система вызывает CallBack процедуру, передавая ей в качестве одного из параметров номер кнопки, которую выбрал пользователь в окне немодального диалога. Напомним, что при модальном диалоге этот номер возвращает метод Show. Организовать модальный диалог достаточно просто, а с не модальным всегда возникают некоторые сложности. В данном случае они преодолеваются за счет использования процедуры обратного вызова. Эту процедуру пишет сам программист, но вызывает ее система, передавая в процедуру номер кнопки, известный ей в момент вызова. Используя полученный параметр, конечно, нетрудно написать тело самой процедуры так, чтобы она правильно реагировала на выбор, сделанный пользователем.

Теперь, когда общая идея понятна, уточним некоторые детали. Прежде всего заметим, что объект Balloon имеет еще одно ранее не описанное важное свойство CallBack. Значением этого свойства является строка, задающая имя CallBack процедуры. Заметьте, что в данном случае Вы сами определяете имя процедуры и сообщаете его системе. Но число параметров и их типы все-таки фиксированы. Процедура, имя которой Вы указали в свойстве CallBack, должна иметь следующий синтаксис:

< имя процедуры> (Ball As Balloon, NumberOfButton As Long, iPriv As Long)
Листинг 7.6.

Повторяем, имена формальных параметров могут быть произвольными. Важно только понимать, что первый параметр задает объект Balloon, вызвавший немодальный диалог, второй - номер кнопки, выбранной пользователем (это может быть системная кнопка или кнопка, определенная меткой). Третий параметр, как правило, не используется в теле процедуры. Он необходим системному Wizard (Мастеру), работающему с объектом Assistant. Конечно, если Вы пишите свой собственный пользовательский Wizard, то этот параметр понадобится. В соответствии с этим синтаксисом необходимо написать тело процедуры, определяющее реакцию на выбор пользователя. Процедуру естественно следует поместить в тот же модуль, в котором задается немодальный диалог. Процедура будет вызываться в тот момент, когда пользователь щелкает выбранную им кнопку в окне немодального диалога. Напомним, что до закрытия пользователь может многократно входить и выходить из этого окна, выполняя другие работы. В заключение приведем пример немодального диалогового окна:

Public Sub UnModal()
	Dim FirstBall As Balloon
	Dim Text1 As String, Text2 As String
	Dim Text3 As String, Text4 As String
	Dim myPath As String
	myPath = ActiveDocument.Path
'Формирование свойства Text
'Вставка графики в начало текста
	Text1 = "{wmf " & myPath & " /Cabbage.wmf}"
	Text2 = "Вы уже перевезли на другой берег "
	Text3 = "Волка и Козу! Осталось съездить за капустой."
	Text4 = "Отправляясь назад, Вы возьмете с собой: "
	Set FirstBall = Assistant.NewBalloon
	With FirstBall
		.Mode = msoModeModeless
		.Callback = "Answer"
		.Icon = msoIconAlert
		.Heading = "ВОЛК, КОЗА И КАПУСТА"
		.Text = Text1 & Text2 & Text3 & Text4
		.BalloonType = msoBalloonTypeButtons
		.Button = msoButtonSetNone
		.Labels(1).Text = "Волка"
		.Labels(2).Text = "Козу"
		.Labels(3).Text = "Капусту"
		.Labels(4).Text = "Никого"
		.Show
	End With
End Sub

Public Sub Answer(Ball As Balloon, Count As Long, iPriv As Long)
'Анализ принятого решения
Select Case Count
	Case 1
		Call Explain("Это возможное, но не лучшее решение!")
	Case 2
		Call Explain("Это правильно!")
	Case 3
		Call Explain("Это невозможно!")
	Case 4
		Call Explain("Ужасная трагедия: Волк съест Козу!")
	Case Else
		'Пропускаем
End Select
' При желании можно закрыть окно диалога
	Ball.Close
End Sub


Public Sub Explain(Txt As String)
	Dim ExplainBall As Balloon
	Set ExplainBall = Assistant.NewBalloon
	With ExplainBall
		.Heading = "ВОЛК, КОЗА И КАПУСТА"
		.Text = Txt
		.Show
	End With
End Sub
Листинг 7.7.

Здесь, как Вы видите, вместо переменной Answer появилась CallBack процедура Answer, которая и определяет реакцию на выбор пользователя. Заметьте, что в конце этой процедуры метод Close закрывает диалог. Если этого не делать, то после выдачи сообщения о неудачном решении, можно вернуться в окно немодального диалога и изменить свой выбор! В этом сила немодального диалога. Тем не менее, следует быть весьма аккуратным и во время закрыть окно немодального диалога. В противном случае это окно будет постоянно (до перезагрузки компьютера) сопровождать Помощника на экране. Сложность состоит в том, что локальная переменная, определяющая объект Balloon, может прекратить свое существование, а немодальное окно будет продолжать существовать. Поэтому лучше такие переменные определять как глобальные переменные модуля, тогда метод Close может быть вызван в любой из процедур, завершающих работу приложения.

Несерьезный интерфейс для серьезных задач

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

В этих серьезных приложениях, ориентированных на юных или начинающих пользователей, такой интерфейс позволяет вести пользователя шаг за шагом по всей системе, демонстрируя ее возможности. В предыдущей лекции в качестве примера "документа-обложки" я рассмотрел создание известной игры для младших школьников "Волк, Коза и Капуста". В этой реализации не использовался объект Assistant, для того чтобы выдержать чистоту эксперимента и иметь возможность экспорта полученной реализации в чистый VB, создав затем исполняемый файл или ActiveX. При подготовке этой лекции я добавил к этой игре объект Assistant, поручив ему вести весь диалог по ходу игры, сообщать о правилах игры, давать советы о действии, которое следует выполнить, уведомлять о неудачах, возникающих при неверном ходе.

Не возникло никаких принципиальных трудностей с добавлением объекта Assistant к уже имеющейся реализации игры. Понятно, что пришлось слегка изменить интерфейс, - в игре появились еще два визуальных объекта. Одним из них является Помощник, роль которого играет Рокки, вторым - остров, где живет Рокки. Чтобы дать представление о том, как теперь выглядит интерфейс игры, как выглядит диалог, приведу пару рисунков, отображающих некоторые моменты общения с Помощником "Рокки" в процессе игры:

Приветствие Рокки в момент начала игры

увеличить изображение
Рис. 7.7. Приветствие Рокки в момент начала игры

На следующих двух рисунках Рокки рассказывает о правилах игры и дает совет по поводу очередного хода:

Рокки сообщает о правилах игры

увеличить изображение
Рис. 7.8. Рокки сообщает о правилах игры
Рокки дает совет

увеличить изображение
Рис. 7.9. Рокки дает совет
< Лекция 6 || Лекция 7: 12345 || Лекция 8 >
Андрей Гуменюк
Андрей Гуменюк
Молдова