В этой лекции мы продолжим разговор о создании справочной системы. В предыдущей лекции подробно рассматривались вопросы создания справочного руководства, используя возможности инструментария HTML Help
Итак, в этой лекции нам предстоит обсудить целый ряд важных вопросов и познакомиться с новыми инструментами, используемыми при создании справочной системы. И начнем с того, что рассмотрим, как можно облегчить пользователю общение с уже созданным справочным руководством, позволяя ему задавать вопросы на естественном языке.
Пользователи Office 2000 уже привыкли, что всякий раз, когда возникает необходимость в получении справки, у них под рукой Помощник - Office
В состав Office 2000 Developer входит специальный инструмент, называемый Answer Wizard Builder. С его помощью можно подготовить специальные файлы с уточнением ".aw", которые и использует Помощник при подготовке ответов на вопросы. Инструмент Answer Wizard Builder (AWB) в своей работе использует уже созданное справочное руководство. Поскольку, как мы знаем, есть две основные возможности представления справочного руководства - в виде откомпилированного chm - файла или Web-узла, то Мастеру Ответов также приходится ориентироваться в своей работе на оба возможных случая.
В чем суть работы Мастера Ответов? Она - в автоматическом индексировании разделов справочной системы. Мастер строит индексный файл, позволяющий установить соответствие между словами, встречающимися в вопросе, и словами, используемыми в тексте разделов. Анализируя текст каждого раздела, Мастер создает систему индексов (ключевых слов), характеризующих данный раздел. Когда в вопросе, заданном в Помощнике, встречается ключевое слово, выбранное Мастером в качестве индекса некоторого раздела, то при ответе Помощника данный раздел войдет в число разделов, рекомендуемых пользователю.
Процесс анализа содержимого разделов и построения индексов идет автоматически без участия разработчика справочной системы. Но, чтобы не оставить его совсем в стороне и дать ему возможность повлиять на процесс создания индексов, в состав Мастера включены дополнительные средства. С каждым разделом справочного руководства разработчик может связать серию вопросов. Эти вопросы в определенной мере предвосхищают возможные вопросы, задаваемые конечными пользователями при работе со справочной системой. Мастер Ответов использует эти вопросы при создании индексного файла. Если множество вопросов подобрано удачно, то есть шанс, что вопросы пользователя будут близки к этому множеству и, следовательно, пользователю будет рекомендован действительно нужный ему раздел. В данном контексте "близость" означает совпадение используемых терминов в пользовательских вопросах и вопросах, заранее заготовленных.
Давайте посмотрим, как это все работает на самом деле. Что работает, а что работает не совсем так, как хотелось бы. В предыдущей лекции я описал процесс создания справочного руководства "Справка о справке". Поэтому у меня имелся соответствующий chm - файл, с которым и будет работать Мастер Ответов при построении индексного aw - файла.
Поскольку у меня на компьютере установлен Office 2000 в редакции Developer, то у меня уже был инсталлирован Answer Wizard Builder. Мне осталось только запустить его на выполнение. Если у Вас нет версии Developer и нет Answer Wizard Builder, то Вы можете скачать этот инструмент с сервера Microsoft по адресу: http:// www.microsoft.com\office\ork\2000\download\AWBuild.exe
Инструментарий Answer Wizard Builder распространяется свободно, но работать на компьютере будет при условии, что установлен Office 2000.
(рис 9.1) Мастер Ответов в момент открытияМастер AWB наряду с индексным aw-файлом создает проект - файл с уточнением ".awb". Наличие проекта позволяет при необходимости возвращаться и корректировать уже созданные индексные файлы. Понятно, что такая необходимость может возникать при корректировке справочного руководства, добавлении или удалении разделов, существенного изменения их содержания.
Как видно из рисунка, при создании нового проекта я использую chm-файл "HelpOfHelp". Заметьте, на этом этапе возможны альтернативы - во-первых, можно открыть существующий проект, взяв его за основу для нового проекта, во-вторых - можно при построении проекта использовать Web-узел.
Сделаю два замечания. Возможно, внимательный читатель заметил, что я отказался от использования русского имени файла и использую новый chm-файл, в котором заменил имя "Справка о справке" на имя "HelpOfHelp". В процессе построения этого файла я заменил также имя файла "Содержание", содержащего оглавление, на имя "Contents". При работе с AWB нельзя использовать русские имена файлов из-за возникающих проблем.
Еще одно замечание также может быть полезным. Изучая документацию MSDN на сервере Microsoft, я нашел уведомление об ошибке - в открывающемся окне, где задается имя скомпилированного chm - файла, уточнение "chm" следует набирать в нижнем регистре. В противном случае, если указать, например, - "MyHelp.Chm", появится сообщение о том, что файл с таким именем не найден, хотя он и существует и путь к нему будет указан правильно.
Но вернемся к первому диалоговому окну инструмента AWB. При нажатии кнопки "OK" происходит автоматическая декомпиляция chm - файла и открывается следующее окно AWB:
(рис 9.2) Основное окно Мастера Ответов В левом окошке показан весь список разделов справочного руководства. В этом списке можно выбрать один из разделов. Справа расположены два окошка - верхнее для задания заголовка раздела, выбранного в левом окне, нижнее - для задания списка вопросов, которые разработчик справочного руководства связывает с данным разделом. Этой работой я и занялся, задав для каждого из разделов свое множество вопросов. Конечно, меня больше интересовало не содержание вопросов, а такие проблемы, как возможность работы с русским языком, использование русских и английских терминов в одном вопросе, возможности редактирования и подобные детали. Замечу, что при создании текста вопросов все возможности по редактированию допустимы в полном объеме - копирование, вырезка и перенос вопросов из одного раздела в другой. Типичной является ситуация, когда одни и те же вопросы связываются с несколькими темами. Есть, правда, ограничение - один вопрос должен быть связан не более чем с пятью разделами. У каждого раздела может быть практически неограниченное число вопросов. Вот как выглядит множество вопросов, указанное мной для одного из разделов:
(рис 9.3) Задание вопросов в AWB Еще одно замечание связано с недопустимостью использования русского языка в окне заголовков. Хотя имена файлов разделов, появляющиеся в левом окне, в моем случае заданы латиницей, заголовки в левом верхнем окне, которые могут появляться автоматически, для большинства файлов были на русском языке. Опять-таки, мне пришлось изменить их на английские имена, поскольку в противном случае они не отображались нужным образом при тестировании Мастера ответов.
Как видите, я сформировал множество вопросов, как на русском, так и на английском языке. Формально, это вполне допустимо. Теперь можно переходить и к созданию проекта AWB с одновременным созданием индексного файла. Но вначале скажем несколько слов о главном меню и
За исключением двух уже описанных инструментальных кнопок все остальные типичны и соответствуют командам меню File и Edit. Как видите, среда достаточно проста, команд немного, так что трудностей в ее освоении теоретически не должно быть.
Рассмотрим те средства, которые есть в распоряжении разработчика при создании проекта AWB. По существу, возможностей не так уж и много. Можно, как уже говорилось, добавить к проекту дополнительные chm - файлы, можно добавить к каждому разделу множество вопросов, связав их с этим разделом. После этих двух шагов, каждый из которых может быть опущен, следующим шагом является непосредственное создание проекта для чего достаточно щелкнуть по кнопке, запускающей построение проекта. В моем случае построение проекта не заняло много времени, хотя, следует отметить, процесс построения индексов может быть весьма долгим. В результате построения было выдано следующее окно:
(рис 9.4) Окно выдачи сообщения о результатах построения awb - проекта Обратите внимание, в конце сообщения выдается некоторая оценка (pass rate), в нашем случае - 61,9%. Эта оценка задает долю принятых вопросов. Многие вопросы, заданные на чистом русском языке, Мастер отверг. Анализируя Log файл, можно понять, какие вопросы и в каких разделах были отвергнуты Мастером.
(рис 9.5) Вопросы, отвергнутые Мастером в Log файлеДоля принятых вопросов часто бывает значительно ниже 100 %, по крайней мере, в тех многочисленных экспериментах, которые я проводил, пытаясь понять логику работы Мастера. Но об этом мы еще поговорим позже, а сейчас отметим, что наряду с awb-файлом проекта построен и aw-файл, используемый Office
(рис 9.6) Тестирование Мастера ОтветовВся подготовительная работа закончена и можно переходить к завершающему этапу, на котором появится возможность задавать вопросы на русском языке в окне Office
Говоря о принципиальных сложностях, давайте начнем с Мастера Ответов - инструмента AWB. Работать с этим инструментом технически довольно просто - у него совсем немного команд. Значительно труднее понять, насколько хорошо Мастер Ответов справляется со своей работой. Напомню, что его задачей является индексация файлов разделов справочного руководства. Принципиальная сложность состоит в том, что Мастеру необходимо работать с русским языком при анализе текста разделов. Русский язык входит в число тех языков, с которыми умеет работать Мастер Ответов. Но индексация - поиск ключевых слов - это довольно тонкий процесс, здесь необходима сложная лингвистическая поддержка русского языка. На данном этапе такой поддержкой Мастер Ответов не обладает. Хотя он и справляется со своей задачей и обеспечивает построение индексов, иногда довольно удачно, но, в целом, вряд ли можно признать его работу удовлетворительной. Замечу, что при построении индексов у AWB нет даже такого простого средства, как "стоп-список", который используется при организации
Частично проблемы могут быть решены за счет возможности добавления вопросов к разделам. Удачно подобранные вопросы, принятые Мастером, гарантируют, что при подобных вопросах пользователя ему будут выданы действительно подходящие разделы справочного руководства. К сожалению, Мастер Ответов не все вопросы принимает, и понять его логику мне не удалось. Отмечу лишь некоторые экспериментально зафиксированные факты. Мастер Ответов не принимает в качестве вопросов символы латинского алфавита, что совершенно правильно по соображениям, о которых я уже говорил. Большинство символов русского алфавита, к сожалению, принимаются в качестве вопросов. Мастер Ответов может принять или отвергнуть вопрос в зависимости не только от самого вопроса, но и в зависимости от контекста - других вопросов и текста разделов. Поэтому в разных множествах вопросов одни и те же вопросы могут быть приняты в одном множестве и отвергнуты в другом.
Некоторой рекомендацией может быть использование в текстах разделов справочного руководства и в вопросах, их сопровождающих, ключевых слов на английском языке. С английским Мастер Ответов справляется значительно лучше, чем с русским. По понятным причинам этой рекомендации не всегда можно следовать в пользовательских справочных руководствах, ориентированных на русскоязычного читателя.
Еще одна принципиальная сложность связана с окном справки, в котором отображаются разделы справочного руководства. В предыдущей лекции было показано, как можно в приложение добавить собственный пункт меню или
То, что Помощник отображает справочное руководство в своем окне справки, не является ограничением. Достоинство предлагаемого подхода состоит в том, чтобы, сохраняя возможность получения стандартных справок по приложениям Office 2000, одновременно иметь возможность получать справки по терминам, специфичным для данного документа, отражающим его пользовательскую направленность. Поэтому в окне справки должны отображаться как разделы пользовательского, так и стандартного справочного руководства. Хотя окно справки является "слугой двух господ", свой внешний вид оно сохраняет постоянным, ориентированным на стандартное справочное руководство Office 2000. Конечно же, наряду с возможностью использования Office
А теперь прошу обратить особое внимание на одно важное требование, без соблюдения которого разделы пользовательского руководства не будут отображаться в стандартном окне справки. Скомпилированный chm-файл пользовательского справочного руководства должен быть зарегистрирован в реестре Windows. Без этого его разделы не будут отображаться в стандартном окне справки.
Регистрация не требуется при открытии справочного руководства в собственном окне.
Для регистрации chm-файла в реестре можно воспользоваться Редактором реестра (regedit.exe). Файл регистрируется в разделе: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\HTML Help
В этом разделе зарегистрированы все chm-файлы, задающие стандартные справочные руководства. Здесь же нужно для собственного справочного руководства ввести новый строковый параметр, имя которого совпадает с именем chm-файла, а значение задает путь к этому файлу.
(рис 9.7) Регистрация в реестре Windows chm-файлаДавайте займемся еще одной проблемой, возникающей при отображении разделов справочного руководства в стандартном окне справки. Как я уже говорил, Office
(рис 9.8) Отображение разделов стандартного и пользовательского руководств по заданному индексуКак видите, индексу "bitmap" соответствуют несколько тем из нашей справочной системы и множество тем стандартного справочного руководства. В правом подокне отображается один из разделов нашего руководства.
Но мы отвлеклись, и так и не сформулировали суть проблемы. А она связана с вкладкой "Содержание". Дело в том, что нельзя объединить содержание двух справочных руководств - стандартного и пользовательского. Так какое же содержание должно быть показано? Однозначного ответа нет. Все зависит от выбора разработчика, который может управлять этим процессом на этапе создания chm-файла. В предыдущей лекции я рассказывал об определении окна справки, задании его свойств, о том, что задание вкладок "Избранное" и "Поиск" осуществляется включением флажков, задающих соответствующие свойства окна, в котором будет отображаться справочное руководство. Я не стал там заострять внимание на возможных проблемах, связанных с просмотром справочного руководства в окне справки. Теперь пришла пора сказать об этом. Для того чтобы просматривать стандартное оглавление в окне справки, при его определении необходимо выполнить следующие условия:
Вот как выглядит редактирование проекта HTML Help
(рис 9.9) Редактирование hhp-проекта в окне текстового редактора "Блокнот"Для удобства восприятия рисунка я разорвал строку определения окна, что позволило увидеть весь текст этой строки. Фактически, определение окна задается одной строкой.
В том случае, когда окну справки дано собственное, а не стандартное имя, при работе Office
Подведем теперь некоторые итоги и суммируем те факты, которые необходимо учитывать для обеспечения гладкого взаимодействия между различными инструментальными средствами - HTML Help
В заключение рассказа о сложностях, которые могут возникнуть при создании справочной системы, хочу напомнить, что при работе в корпоративной сети справочное руководство, зачастую, представляется в виде Web-узла, а не в виде скомпилированного chm-файла. В этом случае возникают свои проблемы, о которых я здесь не упоминаю, поскольку решил ограничиться подробным изложением одного варианта, ориентированного на использование справочной системы, установленной на локальной машине.
Нам осталось рассмотреть в деталях заключительный шаг в обеспечении взаимодействия Office
Итак, будем полагать, что, используя инструментарий HHW, справочное руководство успешно создано, построен и зарегистрирован скомпилированный chm-файл. Будем полагать также, что инструментарий AWB позволил создать индексируемый aw-файл ответов на возможные вопросы пользователей, желающих получить нужную им справку. Как присоединить полученный aw-файл к Office
Прежде всего, напомню, что когда пользователь формирует свой вопрос в окне Помощника, то для ответа на этот вопрос Office
Public Sub HelpOfHelp()
'Создание объекта Answer Wizard
'добавление файлов ответа к справочной системе
Dim i As Integer
Dim customAnswerWizard As AnswerWizard
Set customAnswerWizard = Application.AnswerWizard
With customAnswerWizard
'Восстановление стандартного множества aw-файлов
.ResetFileList
'Показать Помощника
Assistant.Visible = True
Debug.Print .Files.Count
'Отключение стандартных файлов в тех случаях,
'когда используется только собственное справочное руководство
'.ClearFileList
'Добавление собственного справочного руководства
.Files.Add ("e:\O2000\Book2\Cd\Help1\HelpOfHelp.aw")
'Отладочная печать aw-файлов
For i = 1 To .Files.Count
Debug.Print .Files(i)
Next i
Debug.Print .Files.Count
End With
End Sub
В моем тестовом документе эта процедура вызывается в ответ на щелчок специально спроектированной командной кнопки. Но, конечно же, чаще всего подобную процедуру следует включать в процедуру инициализации документа, вызываемую в обработчике события Open.
Несколько комментариев к этой процедуре. Я ввел ResetFileList восстанавливает список стандартных файлов, присущих объекту AnswerWizard. Метод ClearFileList делает этот список пустым, он используется перед добавлением собственных aw-файлов, например, для того, чтобы можно было работать только с этими файлами. Заметьте, метод ClearFileList в процедуре закомментирован. Это позволяет одновременно работать со стандартным и собственным справочным руководством. Вот как выглядит запрос на справку, сформулированный в Office
(рис 9.10) Вопрос и ответ в Office Assistant Как видите, Мастер Ответов на вопрос "Help" указал разделы, как нашего справочного руководства, так и стандартного. Заметьте, в стандартном руководстве используются русские имена разделов. При создании собственного руководства мне не удалось справиться с решением этой задачи. И в заключение рассказа взгляните еще на один экран, на котором одновременно показаны два окна справки - стандартное окно и собственное окно. В обоих окнах отображается наше справочное руководство. Окна имеют разные закладки, одно из них открыто Office
(рис 9.11) Справочное руководство, открытое в двух окнах На этом и завершим рассказ о том, как Office
Важной составляющей профессионально создаваемых систем является предоставление пользователю возможности получить "на лету" справку ко всем элементам интерфейса. Для чего предназначена та или иная команда меню? Что произойдет при нажатии этой командной кнопки? Каков формат данных, вводимых в это поле ввода? На все подобные вопросы пользователь должен иметь возможность получить немедленную справку, не роясь в недрах справочного руководства. Такие специальные справки к элементам интерфейса называются справками типа "Что это такое?". Они представляют контекстно-чувствительные справочные сообщения, появляющиеся во всплывающих (pop up) окнах, когда, например, специальный курсор подводится к тому или иному элементу интерфейса или выбирается пункт меню из контекстного меню, открываемого при нажатии правой кнопки на элементе интерфейса, или нажимается клавиша F1, когда элемент интерфейса находится в фокусе ввода.
Тема организации подобных справок достаточно обширна, прежде всего, из-за разнообразия интерфейса. Одно дело организовать справку к элементам интерфейса внутри формы, скажем к
Я начну с подробного рассмотрения одного вопроса - создания контекстных справок для элементов интерфейса внутри формы. Во-первых, это, пожалуй, наиболее важный случай, во-вторых, организация справок для других ситуаций имеет много общего. Но есть и еще одна серьезная причина, она заключается в том, что мне не удалось полностью решить поставленную задачу. Полагаю, что рассказ о возникающих проблемах может быть не менее интересен для тех, кто будет решать аналогичную задачу. Тем более что часть из этих проблем мне удалось преодолеть, хотя и не в полном объеме. К проблемам я был готов, поскольку в Руководстве программиста по VBA Office 2000 сказано, что для организации контекстных справок следует использовать предыдущий вариант инструментария справочной системы, используя WinHelp, а не HTML Help. С другой стороны, в описании системы HTML Help
Работа по организации справок данного типа состоит из двух частей. Часть работы связана с программным проектом, формой, элементами интерфейса данной формы. Нужно уметь корректно задать нужные свойства при проектировании всех этих элементов, для того чтобы появились подобные справки. Вторая часть этой работы состоит в подготовке разделов справки, и она выполняется специальным инструментарием, например, Winhelp или HHW.
Для того чтобы обеспечить возможность появления всплывающих подсказок к элементам интерфейса в формах, следует выполнить три условия:
HelpContextID.HelpContextID, необходимо задать значение еще двух свойств - WhatThisButton и WhatThisHelp.Давайте поговорим обо всем этом подробнее. Прежде всего, обратите внимание, что справочное руководство связывается с проектом, а не с формой. Оно одно на весь проект, поэтому, сколько бы не было различных форм, все разделы справки должны быть собраны в одно руководство. Заметьте, также, что файл, содержащий руководство, может иметь расширение htm или chm в зависимости от того, каким инструментарием он подготовлен. Надеюсь, не надо объяснять, как нужно задавать свойства программного проекта. Ранее я уже об этом говорил.
Булевы свойства WhatThisButton и WhatThisHelp формы должны быть установлены как true (истина). Включение кнопки WhatThisHelp обеспечивает поддержку выдачи контекстных справок. Если же дополнительно включена кнопка WhatThisButton, то в этом случае в правом углу заголовка формы появится дополнительная кнопка со знаком вопроса, и форма приобретет новое качество. Всякий раз, когда пользователь щелкнет эту кнопку, курсор изменит свой внешний вид - рядом с курсором будет плавать знак вопроса. Достаточно теперь подвести такой курсор к выбранному элементу интерфейса и щелкнуть по нему, как в появившемся всплывающем окне отобразится контекстная справка, поясняющая суть данного элемента.
Понятно, что чудес не бывает и появляющийся раздел справки однозначно определяется числовым значением контекстного идентификатора - HelpContextID, установленного для каждого элемента интерфейса. Особых требований к этим идентификаторам не предъявляется, важно только, чтобы они были уникальными, позволяя для каждого элемента интерфейса во всем программном проекте однозначно установить нужный раздел справочного руководства. Возникает вопрос, - откуда берутся значения этих идентификаторов? Это вопрос о том, что было раньше - курица или яйцо. Если раньше строится справочное руководство, а уж потом контекстно-чувствительные справки добавляются к программному проекту, то значения идентификаторов определяются при построении справочного руководства. Чаще всего, возникает обратная ситуация, когда проектируется форма, задаются уникальные значения контекстных идентификаторов для каждого ее элемента, а потом уже строится справочное руководство, поддерживающее данные значения. В общем, правильный ответ состоит в том, что на этапе проектирования системы должны быть предусмотрены разделы справки для каждого элемента интерфейса и связанные с этими разделами два уникальных идентификатора - числовой (HelpContextID) и строковый, называемый символическим идентификатором раздела. О символических идентификаторах поговорим позже. Сейчас же замечу, что вся система контекстных справок, где бы они ни выдавались, - в формах или документах, построена на использовании этих двух видов идентификаторов. Скажу также, что и возникающие проблемы связаны с тем, что не всегда удается построить правильное отображение между идентификаторами и соответствующими разделами справки.
В качестве примера формы с элементами интерфейса, для которых попытаемся построить контекстные справки, я взял уже знакомую форму из игры "Волк, Коза и Капуста". Я слегка модифицировал интерфейс этой формы и вот как он теперь выглядит:
(рис 9.12) "Новый" интерфейс в игре "Волк, Коза и Капуста" Наша форма была достаточно специфичной, - все ее элементы интерфейса были рисунками, в ней отсутствовали типичные для форм элементы - поля ввода, списки, кнопки. К каждому рисунку я добавил подпись, вдвое увеличив тем самым число элементов интерфейса. Добавление подписей позволяет мне обратить Ваше внимание на два важных момента. Во-первых, рисунки не имеют свойства HelpContextID и поэтому для них не возможна контекстная справка. Так что добавление подписей является в данном случае вынужденной мерой, позволяя получить справку по подписи к рисунку. Во-вторых, и в тех случаях, когда элемент интерфейса, например, поле ввода, имеет HelpContextID и может реагировать на пользовательский запрос, целесообразно эту же справку связывать и с подписью, сопровождающей этот элемент. Дело в том, что пользователь часто предпочитает щелкнуть по подписи, чтобы получить справку, а не на сам элемент интерфейса. Щелкнуть по подписи кажется более естественным и более безопасным.
Итак, подведу некоторые итоги. У меня есть программный проект, в нем есть форма, в ней элементы интерфейса и я выполнил все три условия, необходимые для организации контекстной справки типа "Что это такое?". В свойствах элементов интерфейса (в данном случае - это одни подписи, что не играет принципиальной роли) я задал значения HelpContextID от 1000 до 1009. Для рисунков, напомню, задать идентификатор для получения контекстной справки, к сожалению, невозможно. Можно было бы задать идентификатор для самой формы, но я этого не сделал, поскольку в нашей форме из-за визуальных объектов не осталось "живого" места. На следующем шаге я изменил значения вышеупомянутых булевых свойств формы и, как можно видеть на рисунке, у формы появился знак вопроса в правом верхнем углу. Я установил в свойствах программного проекта имя файла справочного руководства, которое должно содержать разделы справки для каждого элемента интерфейса. Этот файлу я дал длинное имя "WhatThisHelpToWGC.chm" и его предстоит создать уже знакомыми средствами инструментария HTML Help
В предыдущей лекции подробно рассказывалось, как создать справочное руководство средствами HHW. Сейчас нам предстоит познакомиться с некоторыми новыми, ранее не упоминавшимися возможностями этой системы. Мы поговорим, конечно, о включении в руководство специальных контекстных справок, но не только об этом. Рассмотрим два основных вопроса:
Ранее, когда речь шла о создании справочного руководства и работы с ним, не возникала необходимость использования идентификаторов разделов, поскольку в нужном месте открывалась вся справочная система, и поиск раздела осуществлялся с помощью специальных средств - оглавления, указателей и других. Но в ряде случаев, как, например, при получении контекстной справки, необходимо сразу же открывать нужный раздел справочной системы. В этом случае без знания идентификаторов разделов не обойтись. Иногда нужно знать символьный идентификатор, иногда числовой, как, например, при работе с элементами интерфейса формы.
Для того чтобы разделы справочного руководства связать с числовыми и символьными идентификаторами, при работе в HHW требуется установить два отображения. Первое отображение задается в специальной секции MAP, оно устанавливает соответствие между двумя видами идентификаторов. Второе отображение задается в секции ALIAS, - оно связывает символьные идентификаторы с именами файлов, хранящих разделы справки. В совокупности оба отображения позволяют, зная любой из идентификаторов, найти нужный раздел справки.
Поскольку одной из наших целей является включение в справочное руководство специальных контекстных справок, то мы также рассмотрим создание в hhp-проекте секции TEXT POPUPS, в которой задается ссылка на текстовый файл, содержащий контекстные справки и устанавливается соответствие между этими справками и их идентификаторами.
Давайте перейдем к рассмотрению подробностей построения каждого из упомянутых отображений и формирования секций hhp-проекта: MAP, ALIAS, TEXT POPUPS.
Отображение между двумя видами идентификаторов - символьными и числовыми - представляется в виде определения последовательности
#define <символьный идентификатор> <числовой идентификатор>
Вот как выглядит отображение, задаваемое для нашего примера:
#define IDH_Man 1000 #define IDH_Wolf 1001 #define IDH_Goat 1002 #define IDH_Cabbage 1003 #define IDH_Boat 1004 #define IDH_River 1005 #define IDH_LeftBank 1006 #define IDH_RightBank 1007 #define IDH_Shark 1008 #define IDH_Island 1009
Заметьте, символьные идентификаторы начинаются префиксом IDH_. В этом случае система HHW опознает их как символьные идентификаторы и осуществляет весьма полезные проверки корректности задания отображения между идентификаторами и разделами справки. Так что рекомендуется всегда использовать этот префикс в символьных именах. Это отображение строится в обычном текстовом редакторе внутри HHW, в Блокноте или в Word, если Вы привыкли там работать. Файл сохраняется как текстовый файл с уточнением ".h". Это уточнение типично для заголовочных файлов языка C. По сути, файл таковым и является, он является частью hhp-проекта и хранится в каталоге проекта вместе с остальными файлами. Теперь несколько слов о том, как создается секция MAP.
При работе с вкладкой Project в главном окне среды HHW на левой
HTML Help API Information. Она называется так, потому что API функция HTML Help, которая явно или неявно используется при вызове разделов справочной системы, требует в качестве информации (параметров) задания числовых или символьных идентификаторов. Но об этом мы еще поговорим позже.
Щелчок по данной кнопке открывает диалоговое окно, три вкладки которого обеспечивают создание трех секций hhp-проекта, о которых идет речь. Вот как выглядит это окно, открытое на вкладке MAP:
(рис 9.13) Создание секции MAPПо существу, в этом окне нужно задать имя заголовочного (Header) файла, задающего отображение между символьными и числовыми идентификаторами. Как создается этот файл, я только что рассказал. Казалось бы, нет ничего проще, чем задать имя файла. В данном случае и, к сожалению, это не так. Процесс по непонятным причинам усложнен. При его выполнении возникают ошибочные ситуации, приводящие, по моему мнению, в дальнейшем к некорректной работе системы. Давайте подробно рассмотрим все этапы этого процесса.
(рис 9.14) Первое окно открытия файлаВ этом окне уже появилась кнопка Browse. Нажмем ее.
(рис 9.15) Второе окно открытия файлаТеперь прошу обратить особое внимание на два факта. Первый - в качестве шаблона для поиска файлов указан шаблон "*.h", Второй факт - в открытой папке HelpToWGC не найдено ни одного файла с таким уточнением. Могу Вас заверить, что заголовочные файлы с уточнением h присутствуют в этом каталоге. Прежде чем обсуждать данные факты, продолжим работу. Естественно я ввел известное мне имя заголовочного файла в поле имени и нажал кнопку "Открыть". В результате я получил ответ, что найти файл в каталоге не удалось:
(рис 9.16) Третье окно открытия файлаПосле этого мне осталось ничего другого, как вернуться к окну
(рис 9.17) Четвертое окно открытия файлаПосле моего утвердительного ответа было сформировано предложение #include, составляющее секцию MAP. Для тех, кто знает язык C, понятно, что предложение #include обрабатывается препроцессором и вставляет заголовочный файл в текст компилируемого модуля. Несмотря на то, что это предложение, в конечном итоге, было сформировано правильно, я понимаю, что система не видит заголовочный файл, а, следовательно, не может построить нужное отображение и в нужный момент открыть требуемый раздел справки
Даже, если бы все работало корректно, то весь этот длинный процесс открытия файла представляется мне примером неудачного, я бы даже сказал, непрофессионального решения.
Несколько слов о том, почему не виден файл с уточнением ".h". Он и не должен быть виден, поскольку это текстовый файл, и он будет отображаться, когда шаблоном будет служить уточнение ".txt". Другое дело, что в грамотной реализации нужно вначале найти все текстовые файлы и отобрать среди них те файлы, которые имеют уточнение h. Подводя итог, следует сказать, что хотя формально секция MAP была создана, но фактически процесс ее создания потерпел неудачу и файл, указанный в этой секции не будет виден системой. Выход из этой ситуации есть, но об этом чуть позже. Аналогичная ситуация с заголовочными файлами возникает и при работе с двумя другими вкладками в процессе создания секций ALIAS и TEXT POPUPS.
Прежде, чем формировать секцию ALIAS, в справочном руководстве HHW рекомендуется построить еще один заголовочный файл, задающий отображение межу символическими идентификаторами и именами файлов, содержащих соответствующие разделы справочного руководства. Я напомню, что
Символьный идентификатор> = <Имя файла>
В нашем примере этот заголовочный файл выглядит следующим образом:
IDH_Man = Man.htm IDH_Wolf = Wolf.htm IDH_Goat = Goat.htm IDH_Cabbage = Cabbage.htm IDH_River = River.htm IDH_LeftBank = LeftBank.htm IDH_RightBank = RightBank.htm IDH_Shark = Shark.htm IDH_Boat = Boat.htm IDH_Island = Island.htm
Перейдем теперь к формированию секции ALIAS. При выборе одноименной вкладки в отличие от вкладки MAP появляются две возможности создания секции.
(рис 9.18) Создание секции ALIASНажатие кнопки INCLUDE позволяет создать секцию ALIAS за один шаг, используя подготовленный в текстовом редакторе заголовочный файл. В этом случае открывается уже знакомое окно "
Я построил hhp-проект, в секциях MAP и ALIAS которого использовались заголовочные файлы. Но тестирование этого проекта показало, что заголовочные файлы реально не видны и нужное отображение не строится. Взгляните, как выглядит сообщение, полученное мной при тестировании одного из примеров:
(рис 9.19) "Неуспех" при тестировании проекта с заголовочными файламиЯ напомню, для тестирования проекта после его компиляции из пункта меню Test главного меню системы HHW следует выбрать команду HTML Help API. В открывшемся окне из списка Command следует поочередно выбрать и протестировать две команды: HH_DISPLAY_TOPIC и HH_HELP_CONTEXT. Первая из них отображает разделы, при задании имени файла, содержащего данный раздел. С этой командой особых трудностей обычно не возникает. Чтобы успешно работала вторая команда, где задается числовой идентификатор, требуется успешное создание раздела MAP. В нашем примере успеха нет и причина этого нам известна - заголовочные файлы не работают так, как нужно.
Как справиться с возникшей проблемой? На самом деле это не сложно. Вот что нужно сделать:
Вот как выглядят теперь результаты тестирования для предыдущего примера, когда я проделал всю указанную работу:
(рис 9.20) Успешное получение раздела справки по его числовому идентификаторуТо, что, в конечном счете, удается успешно создать числовые и символьные идентификаторы разделов, имеет крайне важно, поскольку эти идентификаторы широко используются при выдаче контекстных справок в самых разных ситуациях, о которых мы еще поговорим. А теперь пора перейти к проблеме, успешное решение которой мне так и не удалось найти. Но прежде хочу обратить Ваше внимание еще на одну ошибку, которая может возникать в процессе работы с hhp-проектом. Если возникает необходимость провести редактирование разделов MAP и ALIAS, то делать это нужно в текстовом редакторе "Блокнот". Попытка провести редактирование этих разделов в HHW приводит к непоправимой ошибке и снятию приложения.
Инструментарий HHW позволяет создавать и включать в справочное руководство специальную секцию TEXT POPUPS, предназначенную для обеспечения работы с контекстными справками к элементам интерфейса и появление этих справок во всплывающих окнах. Созданию секции TEXT POPUPS, которая необходима при работе с такими контекстными справками, должно предшествовать создание двух текстовых файлов. Один из них уже может существовать, если создавалась секция MAP, - это заголовочный файл, задающий отображение между символьными и числовыми идентификаторами. Второй текстовый файл содержит описание контекстных сообщений, которые будут появляться во всплывающих окнах. Чуть позже я расскажу о синтаксисе, которому должен удовлетворять этот файл. После того, как эти два файла будут созданы, можно переходить к созданию секции TEXT POPUPS, для чего достаточно нажать одноименную вкладку.
(рис 9.21) Создание секции TEXT POPUPSДве
Контекстные справки, появляющиеся во всплывающих окнах, как правило, представляют собой тексты небольшого размера. Поэтому в отличие от обычных разделов справочного руководства, каждый из которых содержится в отдельном файле, все такие контекстные справки могут быть собраны в одном файле. Иногда предпочтительнее вместо одного большого файла иметь несколько файлов, например, отдельные файлы для элементов каждой формы. Такой сборный файл с контекстными справками в HHW создается в текстовом, а не в HTML формате. Структура такого файла достаточно проста и удовлетворяет следующему синтаксису:
<Заголовок раздела> <Текст контекстной справки> [ <Заголовок раздела> <Текст контекстной справки>]…
Файл, как видите, представляет последовательность озаглавленных разделов.
.topic <Символьный идентификатор>
Текст контекстной справки представляет собой обычный текст без картинок и прочих украшений, возможных для текстов в формате HTML, используемых в разделах справочного руководства. Вот два начальных раздела из файла, созданного для очередного примера:
.topic IDH_Man Вот Человек, который следит за всеми зверьми. Он не допустит, чтобы волк съел козу, не разрешит козе съесть капусту. Он перевезет всех с левого берега на правый берег реки. Он помнит, что лодка его мала и не выдержит трех пассажиров. .topic IDH_Wolf Это волк, который дружен с человеком, равнодушен к капусте, но обязательно съест козу, если рядом нет человека.
В hhp-проект, создаваемый для игры "Волк, Коза и Капуста", были включены, как HTML-файлы с разделами справочного руководства, так и текстовый файл, содержащий контекстные справки к элементам интерфейса, подготовленные для показа во всплывающих окнах. Соответственно проект содержит все три секции - MAP, ALIAS и POPUPS. Заменить в секции POPUPS заголовочный файл на его содержание не удается, по причинам, о которых я уже говорил. В результате файл компилируется с ошибками и, хотя они носят характер предупреждений, нужное отображение между идентификаторами и разделами контекстной справки так и не строится. Вот как выглядит результат трансляции проекта:
(рис 9.22) Результат компиляции hhp-проекта игры "Волк, Коза и Капуста quot;С другой стороны стоит отметить, что при тестировании проекта обе команды HtmlHelp API функции работают успешно, что уже само по себе обеспечивает возможность организовать получение контекстных справок, используя вызовы функции HtmlHelp.
На этом я завершаю описание двух важных вопросов, возникающих при создании chm-файлов. В конечном итоге, мы научились связывать символьные и числовые идентификаторы с разделами справочного руководства. Я подробно описал, как можно построить сборный текстовый файл, содержащий контекстные справки, и как добавить секцию POPUPS в справочное руководство, но, к сожалению, мои усилия по разрешению проблем, возникающих на этом этапе, не увенчались успехом.
Проделана вся необходимая работу, как на стороне программного проекта "Волк, Коза и Капуста", так и на стороне создания справочного руководства для этой игры. Я создал и зарегистрировал chm-файл, содержащий, как разделы обычного справочного руководства, так и контекстные справки к элементам интерфейса формы, представляющей игровое поле. На основе chm-файла был создан и Aw-файл, позволяющий Рокки отвечать на вопросы. Осталось провести эксперименты и посмотреть, что из всего этого работает. Прежде всего, я попытался получить контекстные справки к тем надписям на форме, для которых определены числовые идентификаторы и созданы соответствующие разделы в справочном руководстве:
(рис 9.23) Попытка получения контекстной справки к элементу интерфейсаКак видите, выдается сообщение об отсутствии контекстной справки для этого элемента интерфейса. Хотя истинная причина состоит не в отсутствии раздела, а в том, что не задано нужное отображение числового идентификатора на символьный идентификатор и связанный с ним раздел, где содержится контекстная справка. Что же все-таки работает в данной ситуации? Если специализированный курсор со знаком вопроса не подводить к элементам интерфейса, для которых задан HelpContextID, а щелкнуть где-нибудь в произвольном месте формы, то откроется справочное руководство и можно будет получить справку обычным способом. Заметьте, что для этого не понадобилось создавать никаких дополнительных командных кнопок или команд меню. Это не совсем то, что хотелось бы, но вызывать справочное руководство в форме достаточно просто, что, в конечном счете, позволяет получить справки ко всем элементам интерфейса.
Для получения контекстных справок в формах может использоваться и клавиша F1. В нашем примере она работает также как и специальный курсор со знаком вопроса, позволяя открыть справочное руководство, но открывающийся раздел всегда задается самой формой - ее HelpContextID и не зависит от того, какой элемент интерфейса был активным. Заметьте, нажатие клавиши F1 приводит к открытию справочного руководства и в том случае, если свойство формы WhatThisButton выключено.
Справки может выдавать и Помощник.
(рис 9.24) Рокки отвечает на вопрос об основных героях игрыКак видите, Рокки показал все темы, в которых описаны запрашиваемые визуальные объекты. Это еще один способ решения поставленной задачи. Способ справиться с задачей всегда существует. Надеюсь, правда, что в следующей версии HHW не нужно будет искать обходные пути и будет доступен прямой способ решения данной задачи.
Подведем некоторые итоги и посмотрим, как в разных приложениях Office 2000 может использоваться справочное руководство. Во многих случаях получение справок основано на технике, использующей числовые идентификаторы, связанные с разделами справочного руководства. С объектной точки зрения многие объекты, так или иначе, входящие в состав Office 2000, обладают свойствами HelpFile и HelpContextID, определяющими файл, где хранится справочное руководство и числовой идентификатор, однозначно определяющий раздел внутри этого руководства. Файл справочного руководства может быть создан различными инструментальными средствами - HTML Help
Access, как известно, имеет свою специфику, и его объектная модель существенно отличается от других приложений Office 2000. Access не использует библиотеку MSForms и формы, создаваемые в Access, отличаются от форм, используемых в других приложениях, в том числе и по своим свойствам.
Для каждой формы или отчета Access можно создать собственное справочное руководство. Можно, конечно, иметь одно руководство для всех объектов базы данных Access. Объекты Form и Report в Access обладают свойствами HelpFile и HelpContextID, которые можно установить на этапе проектирования или программно. Элементы управления, размещаемые в формах, обладают свойством HelpContextID, задающим числовой идентификатор раздела справки, что позволяет связать каждый элемент с соответствующим разделом справочного руководства. Работая с формой, пользователю достаточно нажать клавишу F1, чтобы получить контекстную справку к тому или иному элементу управления. Зная HelpContextID элемента управления, находящегося в фокусе ввода, и файл, связанный с формой, система отображает в окне справки нужный раздел справочного руководства. Если HelpContextID для активного элемента управления не задан, то отображается раздел, связанный с формой.
В Word, Excel и Power Point формы представляются объектом UserForm, принадлежащим общей библиотеке MSForms, являющейся частью объектной модели этих приложений. В отличие от близкого по духу объекта Form в Access, объект UserForm не имеет ни свойства HelpFile ни свойства HelpContextID. Правда, на этапе проектирования для формы можно задать свойство HelpContextID. Это же свойство можно задать на этапе проектирования и для элементов управления, размещаемых в форме. С объектной точки зрения объект UserForm обладает коллекцией Controls, а каждый элемент этой коллекции - объект Control - обладает свойством HelpContextID.
Как уже говорилось ранее, с формой в этих приложениях нельзя связать отдельный файл справочного руководства. Единое справочное руководство связывается со всем программным проектом. Свойство HelpFile можно установить на этапе проектирования или программно, используя объект VBProject, входящий в общую библиотеку VBIDE. Этот объект имеет и свойство HelpContextID, которое используется в Object Browser, когда необходимо получить справку о данном проекте. О том, как работает клавиша F1 в формах, я написал выше.
Наряду с формами, основными элементами интерфейса, создаваемого для документов Office 2000, являются пользовательские CommandBar. Ее свойство Controls возвращает коллекцию класса CommandBarControls. На панелях располагаются элементы разного типа - меню и команды меню, кнопки нескольких возможных видов. Как объекты, эти элементы принадлежат следующим классам: CommandbarButton, CommandBarComboBox, CommandBarControl, CommandbarPopUp. Объекты всех этих классов обладают свойствами HelpFile и HelpContextID. Оба свойства должны быть заданы для каждого элемента. Заметьте, файл, задающий справку, не связывается ни с панелью, ни с документом, а указывается для каждого отдельного элемента. В принципе это дает некоторую свободу и позволяет, например, иметь отдельный файл для каждой
Public Sub AddHelpProps()
'Добавление контекстных справок к элементам панели
Dim panel As CommandBar
Dim ctrl As CommandBarButton
Dim HelpFilePath As String
HelpFilePath = "e:\O2000\DsCd\WhatThisHelpToWGC\HelpToWGC.chm"
Set panel = CommandBars("ButtonPanel")
'Устанавливаем свойства элементов панели
'Help Свойства кнопки
Set ctrl = panel.Controls(1)
ctrl.HelpFile = HelpFilePath
ctrl.HelpContextId = 1000
Set ctrl = panel.Controls(2)
ctrl.HelpFile = HelpFilePath
ctrl.HelpContextId = 1001
Set ctrl = panel.Controls(3)
ctrl.HelpFile = HelpFilePath
ctrl.HelpContextId = 1002
End Sub
Свойства HelpFile и HelpContextID имеют целый ряд программных объектов, начиная с главного программного объекта VBProject и кончая его компонентами - формами и модулями. Эти свойства имеет объект Err и метод Raise, используемые при обработке программных ошибок. Обладают этими свойствами и широко употребительные функции - MsgBox и InputBox. В конце этой лекции я чуть подробнее расскажу о том, как выдаются справки на разных этапах работы с программным проектом.
Я уже рассказывал в предыдущей лекции о том, как можно показать справочное руководство в ответ на запрос пользователя, нажавшего специально спроектированную
Поговорим теперь еще о двух способах программного вызова справочной системы в принципе, позволяющих не только вызвать справочное руководство, но и открыть его на нужном разделе. Эти два способа основаны на использовании:
Метода Help, которым обладают объекты Application приложений Office 2000.
Функции API - HtmlHelp.
Метод Help по-разному работает для разных приложений - в Word и Access он позволяет получать справки только по стандартным разделам. В приложениях Excel и Power Point метод Help позволяет получить справку к заданному разделу пользовательского справочного руководства.
В приложении Word этот метод имеет следующий синтаксис:
Help(HelpType)
Параметр HelpType задается константой типа wdHelpType. Каждая константа определяет тот или иной вид справки. Вот небольшой пример:
Public Sub CallHelp() 'Вызов стандартной справки Application.Help (wdHelpAbout) End Sub
Синтаксис метода Help в приложениях Excel и Power Point следующий: Help(HelpFile, HelpContextID)
Параметры этого метода нам хорошо знакомы. Тем самым, в этих приложениях становится доступна работа с пользовательским справочным руководством и его разделами. В конечном итоге, это позволяет организовать выдачу контекстных справок в обработчиках различных событий - по нажатию специальных кнопок, по нажатию клавиши F1 или любой другой специальной клавиши. Возможностей здесь много.
Я рассмотрю сейчас пример, в котором метод Help будет использоваться для получения справок об элементах интерфейса формы. Это будет все та же форма с игрой "Волк, Коза и Капуста". Для того, чтобы она заработала в Excel, мне пришлось, конечно, выполнить операции экспорта - импорта формы и соответствующих модулей. Еще одно типичное изменение в таких случаях связано с заменой объекта ActiveDocument на ActiveWorkBook, определяющих соответственно активные документы Word и Excel.
Моя цель состоит в том, чтобы получать контекстные справки к элементам интерфейса данной формы, используя возможности метода Help в Excel. Вот как я собирался достичь этой цели. Как Вы помните, в форме для каждого визуального объекта введен дополнительный объект - надпись (Label). Надписи полезны сами по себе, но введены они были и по той причине, что графические объекты не имеют важного свойства HelpContextID. Для надписей это свойство существует и на этапе проектирования его значение можно установить. В обработчике события Click для каждой надписи я предполагал вызывать метод Help, передавая ему в качестве параметра контекстный идентификатор соответствующей надписи. Так что все выглядело достаточно логично, - всякий раз, когда пользователь щелкает мышью по надписи, ему в ответ выдается справка о визуальном элементе, связанном с этой надписью. Вот как выглядит спроектированный мной обработчик события Click для надписи:
Private Sub Label1_Click() 'Выдача контекстной справки - не работает!!! 'Глобальный параметр Myf задает путь к файлу справочного руководства 'Второй параметр метода Help позволяет по HelpContextID определить нужный раздел Call Application.Help(Myf, Me.Label1.HelpContextID) End Sub
Однако мой хорошо продуманный план потерпел неудачу из-за очередного HelpContextID, значение которого можно установить на этапе проектирования, программно работать с этим свойством для надписей невозможно. Ни установить, ни прочесть значение этого свойства программно не удается. Ошибка возникает, как при явных попытках работать с этим свойством, так и при вызовах внутри процедуры. Поэтому в приведенном примере вызов метода Help терпит неудачу из-за невозможности получить значение свойства HelpContextID для надписи. Так что Вам повезло, - Вы узнали еще об одной ошибке. А мне не повезло, поскольку пришлось в очередной раз переделать интерфейс моей формы. Надеюсь, Вы понимаете, что найти выход из данной ситуации нетрудно, - я заменил надписи другими элементами интерфейса, для которых свойство HelpContextID корректно работает как на этапе проектирования, так и программно. Вместо надписей я использовал специальные утапливаемые кнопки - объекты класса ToggleButton. Для них также существует событие Click, так что наша схема по-прежнему работает, - изменился лишь тип элементов, нажатие которых приводит к выдаче контекстной справки. Я внес лишь небольшие усовершенствования и вот как выглядит обработчик события Click для кнопки ToggleButton:
Private Sub ToggleButton1_Click() 'Выдача контекстной справки - работает!!! 'Глобальный параметр Myf задает путь к файлу справочного руководства 'Второй параметр метода Help позволяет по HelpContextID определить нужный раздел If Me.ToggleButton1.Value Then Call Application.Help(Myf, Me.ToggleButton1.HelpContextID) End If End Sub
Прежде, чем выдать справку, я проверяю, в каком состоянии находится кнопка. Справка выдается при нажатии кнопки. Для кнопки, находящейся в утопленном состоянии, щелчок по ней не приводит к повторной выдаче справки. Надеюсь, понятно, что аналогичные процедуры написаны для всех 10 кнопок нашей формы. Взгляните, как выглядит наша форма в Excel:
(рис 9.25) Форма для игры "Волк, Коза и Капуста", открытая в Excel Вот справочное руководство, открывающееся при нажатии кнопки "Остров Рокки"
(рис 9.26) Контекстная справка к элементу интерфейса Метод Help, как видите, может с успехом использоваться в программном коде, позволяя организовать в документах Excel и Power Point выдачу собственных контекстных справок. К сожалению, в приложениях Word и Access такой способ не применим. Существует другой, более мощный способ решения этой проблемы, применимый для всех приложений. Он основан на непосредственном вызове функции API - HtmlHelp, которая реально обеспечивает работу со скомпилированным chm-файлом и всегда вызывается явно или неявно.
Как и другие функции API, функция HtmlHelp написана на языке C и ее "родное" описание имеет следующий синтаксис:
HtmlHelp, в котором будет появляться справка.Список возможных команд велик. С двумя основными командами мы познакомились при тестировании chm-файла, создаваемого в среде HHW. Этими командами являются HH_DISPLAY_TOPIC и HH_HELP_CONTEXT. Обе команды отображают в окне справки HTML-файл, но пользуются разной информацией. Для первой команды параметр pszFile задает имя chm-файла, а параметр dwData должен указывать на файл с разделом справки, являющийся частью скомпилированного chm-файла. Команда HH_HELP_CONTEXT позволяет отобразить в окне справки HTML-файл, заданный числовым идентификатором. Параметр dwData в этом случае задает значение HelpContextID.
Функция HtmlHelp входит в состав библиотеки, определяющей HTML Help ActiveX элемент управления (HHCtrl.
Для того, чтобы эту функцию можно было вызывать в программном коде VBA, необходимо предварительно объявить ее в операторе DECLARE. Необходимо объявить также используемые константы, а в общем случае и типы данных. Основная проблема при этом состоит в том, чтобы правильно отобразить типы языка C на типы языка VB. Приведу два возможных варианта объявления функции HtmlHelp на VBA, которые использовались мной в экспериментах:
Public Const Myf = "e:\O2000\DsCd\HelpToWGC\WhatThisHelpToWGC.chm" 'Константы, необходимые для вызова API функции HtmlHelp Public Const HH_DISPLAY_TOPIC = H0 'Вызов по имени раздела Public Const HH_HELP_CONTEXT = HF 'Вызов по Context ID 'Описание API функции HtmlHelp Public Declare Function HtmlHelp Lib "hhctrl.ocx" _ Alias "HtmlHelpA" _ (ByVal hwndCaller As Long, _ ByVal pszFile As String, _ ByVal uCommand As Long, _ dwData As Any) As Long 'Описание варианта API функции HtmlHelp Public Declare Function HtmlHelpLongArg Lib "hhctrl.ocx" _ Alias "HtmlHelpA" (ByVal hwndCaller As Long, _ ByVal pszFile As String, ByVal uCommand As Long, _ ByVal dwData As Long) As Long
Обратите внимание, в первом варианте тип параметра dwData описан как Any. В этом случае при вызове не проверяется тип передаваемых данных, и вся ответственность за корректность вызова лежит на программисте. Это описание функции является универсальным и позволяет вызывать любые возможные команды, доступные для функции HtmlHelp. Во втором варианте описания функции тип параметра dwData зафиксирован. Этот вариант может быть использован при вызове команды HH_HELP_CONTEXT, когда в качестве значения передается числовой идентификатор.
Для иллюстрации возможностей работы с функцией API я использовал предыдущий пример, заменив вызовы метода Help на вызов функции HtmlHelp:
Private Sub ToggleButton1_Click() 'Выдача контекстной справки - работает!!! 'Глобальный параметр Myf задает путь к файлу справочного руководства 'Второй параметр метода Help позволяет по HelpContextID определить нужный раздел If Me.ToggleButton1.Value Then 'Call Application.Help(Myf, Me.ToggleButton1.HelpContextID) 'Вызов API функции HtmlHelp Call HtmlHelpLongArg(0, Myf, HH_HELP_CONTEXT, Me.ToggleButton1.HelpContextID) End If End Sub
Окно справки задается по умолчанию, все остальные параметры сохранили значение, используемое в методе Help. Замечу, что работа метода Help реально сводится к вызову функции HtmlHelp. Вот как выглядит теперь вызов контекстной справки в нашей игре, открытой в Excel:
(рис 9.27) Вызов контекстной справки, использующий API функцию HtmlHelpОсталось выполнить обратный экспорт модифицированной формы в Word и проверить работоспособность данного способа, что я и сделал. Смею Вас уверить, что все работает, как нужно, поскольку вызов функции API и в приложении Word остается вызовом функции API, - слон он и в Африке слон.
В предыдущем параграфе я говорил о том, как программно организовать выдачу контекстных справок. А сейчас мы поговорим о том, как можно получать справки о самом программном проекте. Я рассмотрю два вопроса:
Я напомню, что в окне просмотра объектов - браузере объектов (Object Browser) можно увидеть структуру каждого объекта, так или иначе составляющего документ Office 2000. Еще в момент возникновения документа строится его каркас на основе совокупности библиотек объектов, составляющих по сути Office 2000. В зависимости от типа документа и выбора пользователя в каркас документа включаются те или иные библиотеки. Объекты, включенные в эти библиотеки, являются стандартными, и в окне просмотра объектов можно увидеть не только структуру объекта - свойства, методы, события, константы, но и получить подробную справку, как о самом объекте, так и о его элементах. Когда с документом работает программист, то он достраивает каркас документа, создавая полноценное строение. Работа программиста, прежде всего, сводится к созданию программного проекта, который является неотъемлемой частью документа. Компонентами программного проекта являются формы, стандартные модули, модули классов. Каждая форма, создаваемая программистом, имеет, тем не менее, множество стандартных свойств, методов и событий. Наряду с ними программист населяет форму элементами управления, и эти
Структура программного проекта и всех его компонент доступна для просмотра в окне браузера. Проект является такой же библиотекой, как и остальные библиотеки, составляющие документ. Имя этой библиотеки совпадает с именем проекта. По умолчанию, если проекту не дается собственное имя, используется имя "Project". Если из списка библиотек, выбрать имя библиотеки, задающей проект, то в окне просмотра откроется структура проекта, все его компоненты. Возникает вопрос, можно ли получать справку о компонентах проекта - формах модулях проекта, о компонентах каждого модуля? Можно ли, например, получать справку о свойствах, методах и событиях классов, созданных программистом? Ответ на эти вопросы положителен, хотя и с некоторыми оговорками и сетованиями на то, что не все работает так, как хотелось бы.
Я напомню, что с программным проектом можно связать только одно справочное руководство, поэтому разделы справки для всех элементов проекта должны быть собраны в этом руководстве. Если такое руководство создано, - построен chm-файл, содержащий секции MAP и ALIAS, то для получения справок работает техника числовых идентификаторов - HelpContextID, уже подробно описанная для других ситуаций. Взгляните, как выглядит структура программного проекта с именем WGCProject:
(рис 9.28) Структура программного проекта WGCProject Заметьте, в левом окне Classes показаны все компоненты проекта, в правом окне MembersOf для компоненты, выбранной в левом окне, показана ее структура, - все элементы, входящие в ее состав. На рисунке для выбранного в левом окне класса объектов с именем WGCClass, показаны все элементы этого класса - заданные для него свойства и методы. В нижнем окне для выбранной компоненты показано ее определение. Давайте рассмотрим, как задаются определения компонент и разделы справочного руководства, появляющиеся при запросе справки о той или иной компоненте. Первым делом, в окне свойств проекта необходимо задать:
Никаких проблем не возникает и для компонент проекта, показанных в окне классов, то есть для форм и классов. Для задания определения такой компоненты и связывания с ней раздела справки необходимо:
HelpContextID и задать определение компоненты.Вот как выглядит диалоговое окно Member Options при задании характеристик класса с именем WGCClass:
(рис 9.29) Задание определения и HelpContextID для компоненты программного проекта Теперь конечный пользователь, которому будет передан документ, содержащий проект, в любой момент может получить справку о той или иной компоненте проекта. Для этого ему достаточно в окне браузера выбрать компоненту и нажать кнопку со знаком вопроса.
А теперь прошу обратить внимание, - аналогичная процедура задания определения и HelpContextID для элементов проекта более низкого уровня, заданных в правом окне MembersOf, в данной версии Office 2000 еще не работает. Поэтому, например, нельзя выдать контекстную справку о конкретном свойстве или методе пользовательского класса. Теоретически все должно работать аналогичным образом. Однако, если в этом окне на шаге 1 выбрать некоторое свойство, то на шаге 2 выбрать команду Properties не удастся, поскольку она недоступна (показана серым цветом). Для методов - команда доступна и появляется окно Member Options, в котором можно задать нужные характеристики. Однако они не запоминаются при нажатии кнопки "OK", так что заданные установки не вступают в силу. Можно, конечно, надеяться, что в последующих версиях все эти недоработки будут устранены.
Когда выполняется программный код, возможно возникновение ошибок, причины которых могут быть самыми разными. Это могут быть ошибки программиста, создающего код. Но часто причиной ошибок является нарушение спецификаций, гарантирующих корректную работу программы. Поэтому во многих ситуациях, когда уже ошибка возникла, очень важно выдать справку, объясняющую возможные причины ошибки. Понятно, что только стандартными справками в таких ситуациях не обойтись. Например, если ошибка возникает при работе объекта класса, созданного программистом, то именно он и должен позаботиться о выдаче корректных пользовательских справок, объясняющих природу ошибки. Для этой цели можно использовать те возможности, которые предоставляет объект Err и метод Raise, для которых можно указать имя chm-файла и HelpContextID соответствующего раздела.
Объект Err содержит информацию о последней ошибке выполнения. Этот объект создается вместе с проектом и имеет глобальную область определения. При возникновении ошибки заполняются свойства этого объекта и, тем самым, определяется имя chm-файла и HelpContextID данной ошибки. Затем эти свойства могут быть обработаны подходящим образом. Чаще всего, вызывается функция MsgBox, имеющая кнопку Help, нажатие которой приводит к выдаче контекстной справки. Метод Raise служит для возбуждения собственных ошибок, когда в результате анализа обнаружена исключительная ситуация, при которой невозможно нормальное выполнение программы. Метод Raise возбуждает ошибку, передавая нужные параметры объекту Err, в том числе имя chm-файла и HelpContextID собственной ошибки.
На этом я завершу изложение этой большой и важной темы, посвященной созданию справочной системы для документов Office 2000.
В этой лекции мы продолжим разговор о создании справочной системы. В предыдущей лекции подробно рассматривались вопросы создания справочного руководства, используя возможности инструментария HTML Help
Итак, в этой лекции нам предстоит обсудить целый ряд важных вопросов и познакомиться с новыми инструментами, используемыми при создании справочной системы. И начнем с того, что рассмотрим, как можно облегчить пользователю общение с уже созданным справочным руководством, позволяя ему задавать вопросы на естественном языке.
Пользователи Office 2000 уже привыкли, что всякий раз, когда возникает необходимость в получении справки, у них под рукой Помощник - Office
В состав Office 2000 Developer входит специальный инструмент, называемый Answer Wizard Builder. С его помощью можно подготовить специальные файлы с уточнением ".aw", которые и использует Помощник при подготовке ответов на вопросы. Инструмент Answer Wizard Builder (AWB) в своей работе использует уже созданное справочное руководство. Поскольку, как мы знаем, есть две основные возможности представления справочного руководства - в виде откомпилированного chm - файла или Web-узла, то Мастеру Ответов также приходится ориентироваться в своей работе на оба возможных случая.
В чем суть работы Мастера Ответов? Она - в автоматическом индексировании разделов справочной системы. Мастер строит индексный файл, позволяющий установить соответствие между словами, встречающимися в вопросе, и словами, используемыми в тексте разделов. Анализируя текст каждого раздела, Мастер создает систему индексов (ключевых слов), характеризующих данный раздел. Когда в вопросе, заданном в Помощнике, встречается ключевое слово, выбранное Мастером в качестве индекса некоторого раздела, то при ответе Помощника данный раздел войдет в число разделов, рекомендуемых пользователю.
Процесс анализа содержимого разделов и построения индексов идет автоматически без участия разработчика справочной системы. Но, чтобы не оставить его совсем в стороне и дать ему возможность повлиять на процесс создания индексов, в состав Мастера включены дополнительные средства. С каждым разделом справочного руководства разработчик может связать серию вопросов. Эти вопросы в определенной мере предвосхищают возможные вопросы, задаваемые конечными пользователями при работе со справочной системой. Мастер Ответов использует эти вопросы при создании индексного файла. Если множество вопросов подобрано удачно, то есть шанс, что вопросы пользователя будут близки к этому множеству и, следовательно, пользователю будет рекомендован действительно нужный ему раздел. В данном контексте "близость" означает совпадение используемых терминов в пользовательских вопросах и вопросах, заранее заготовленных.
Давайте посмотрим, как это все работает на самом деле. Что работает, а что работает не совсем так, как хотелось бы. В предыдущей лекции я описал процесс создания справочного руководства "Справка о справке". Поэтому у меня имелся соответствующий chm - файл, с которым и будет работать Мастер Ответов при построении индексного aw - файла.
Поскольку у меня на компьютере установлен Office 2000 в редакции Developer, то у меня уже был инсталлирован Answer Wizard Builder. Мне осталось только запустить его на выполнение. Если у Вас нет версии Developer и нет Answer Wizard Builder, то Вы можете скачать этот инструмент с сервера Microsoft по адресу: http:// www.microsoft.com\office\ork\2000\download\AWBuild.exe
Инструментарий Answer Wizard Builder распространяется свободно, но работать на компьютере будет при условии, что установлен Office 2000.
(рис 9.1) Мастер Ответов в момент открытияМастер AWB наряду с индексным aw-файлом создает проект - файл с уточнением ".awb". Наличие проекта позволяет при необходимости возвращаться и корректировать уже созданные индексные файлы. Понятно, что такая необходимость может возникать при корректировке справочного руководства, добавлении или удалении разделов, существенного изменения их содержания.
Как видно из рисунка, при создании нового проекта я использую chm-файл "HelpOfHelp". Заметьте, на этом этапе возможны альтернативы - во-первых, можно открыть существующий проект, взяв его за основу для нового проекта, во-вторых - можно при построении проекта использовать Web-узел.
Сделаю два замечания. Возможно, внимательный читатель заметил, что я отказался от использования русского имени файла и использую новый chm-файл, в котором заменил имя "Справка о справке" на имя "HelpOfHelp". В процессе построения этого файла я заменил также имя файла "Содержание", содержащего оглавление, на имя "Contents". При работе с AWB нельзя использовать русские имена файлов из-за возникающих проблем.
Еще одно замечание также может быть полезным. Изучая документацию MSDN на сервере Microsoft, я нашел уведомление об ошибке - в открывающемся окне, где задается имя скомпилированного chm - файла, уточнение "chm" следует набирать в нижнем регистре. В противном случае, если указать, например, - "MyHelp.Chm", появится сообщение о том, что файл с таким именем не найден, хотя он и существует и путь к нему будет указан правильно.
Но вернемся к первому диалоговому окну инструмента AWB. При нажатии кнопки "OK" происходит автоматическая декомпиляция chm - файла и открывается следующее окно AWB:
(рис 9.2) Основное окно Мастера Ответов В левом окошке показан весь список разделов справочного руководства. В этом списке можно выбрать один из разделов. Справа расположены два окошка - верхнее для задания заголовка раздела, выбранного в левом окне, нижнее - для задания списка вопросов, которые разработчик справочного руководства связывает с данным разделом. Этой работой я и занялся, задав для каждого из разделов свое множество вопросов. Конечно, меня больше интересовало не содержание вопросов, а такие проблемы, как возможность работы с русским языком, использование русских и английских терминов в одном вопросе, возможности редактирования и подобные детали. Замечу, что при создании текста вопросов все возможности по редактированию допустимы в полном объеме - копирование, вырезка и перенос вопросов из одного раздела в другой. Типичной является ситуация, когда одни и те же вопросы связываются с несколькими темами. Есть, правда, ограничение - один вопрос должен быть связан не более чем с пятью разделами. У каждого раздела может быть практически неограниченное число вопросов. Вот как выглядит множество вопросов, указанное мной для одного из разделов:
(рис 9.3) Задание вопросов в AWB Еще одно замечание связано с недопустимостью использования русского языка в окне заголовков. Хотя имена файлов разделов, появляющиеся в левом окне, в моем случае заданы латиницей, заголовки в левом верхнем окне, которые могут появляться автоматически, для большинства файлов были на русском языке. Опять-таки, мне пришлось изменить их на английские имена, поскольку в противном случае они не отображались нужным образом при тестировании Мастера ответов.
Как видите, я сформировал множество вопросов, как на русском, так и на английском языке. Формально, это вполне допустимо. Теперь можно переходить и к созданию проекта AWB с одновременным созданием индексного файла. Но вначале скажем несколько слов о главном меню и
За исключением двух уже описанных инструментальных кнопок все остальные типичны и соответствуют командам меню File и Edit. Как видите, среда достаточно проста, команд немного, так что трудностей в ее освоении теоретически не должно быть.
Рассмотрим те средства, которые есть в распоряжении разработчика при создании проекта AWB. По существу, возможностей не так уж и много. Можно, как уже говорилось, добавить к проекту дополнительные chm - файлы, можно добавить к каждому разделу множество вопросов, связав их с этим разделом. После этих двух шагов, каждый из которых может быть опущен, следующим шагом является непосредственное создание проекта для чего достаточно щелкнуть по кнопке, запускающей построение проекта. В моем случае построение проекта не заняло много времени, хотя, следует отметить, процесс построения индексов может быть весьма долгим. В результате построения было выдано следующее окно:
(рис 9.4) Окно выдачи сообщения о результатах построения awb - проекта Обратите внимание, в конце сообщения выдается некоторая оценка (pass rate), в нашем случае - 61,9%. Эта оценка задает долю принятых вопросов. Многие вопросы, заданные на чистом русском языке, Мастер отверг. Анализируя Log файл, можно понять, какие вопросы и в каких разделах были отвергнуты Мастером.
(рис 9.5) Вопросы, отвергнутые Мастером в Log файлеДоля принятых вопросов часто бывает значительно ниже 100 %, по крайней мере, в тех многочисленных экспериментах, которые я проводил, пытаясь понять логику работы Мастера. Но об этом мы еще поговорим позже, а сейчас отметим, что наряду с awb-файлом проекта построен и aw-файл, используемый Office
(рис 9.6) Тестирование Мастера ОтветовВся подготовительная работа закончена и можно переходить к завершающему этапу, на котором появится возможность задавать вопросы на русском языке в окне Office
Говоря о принципиальных сложностях, давайте начнем с Мастера Ответов - инструмента AWB. Работать с этим инструментом технически довольно просто - у него совсем немного команд. Значительно труднее понять, насколько хорошо Мастер Ответов справляется со своей работой. Напомню, что его задачей является индексация файлов разделов справочного руководства. Принципиальная сложность состоит в том, что Мастеру необходимо работать с русским языком при анализе текста разделов. Русский язык входит в число тех языков, с которыми умеет работать Мастер Ответов. Но индексация - поиск ключевых слов - это довольно тонкий процесс, здесь необходима сложная лингвистическая поддержка русского языка. На данном этапе такой поддержкой Мастер Ответов не обладает. Хотя он и справляется со своей задачей и обеспечивает построение индексов, иногда довольно удачно, но, в целом, вряд ли можно признать его работу удовлетворительной. Замечу, что при построении индексов у AWB нет даже такого простого средства, как "стоп-список", который используется при организации
Частично проблемы могут быть решены за счет возможности добавления вопросов к разделам. Удачно подобранные вопросы, принятые Мастером, гарантируют, что при подобных вопросах пользователя ему будут выданы действительно подходящие разделы справочного руководства. К сожалению, Мастер Ответов не все вопросы принимает, и понять его логику мне не удалось. Отмечу лишь некоторые экспериментально зафиксированные факты. Мастер Ответов не принимает в качестве вопросов символы латинского алфавита, что совершенно правильно по соображениям, о которых я уже говорил. Большинство символов русского алфавита, к сожалению, принимаются в качестве вопросов. Мастер Ответов может принять или отвергнуть вопрос в зависимости не только от самого вопроса, но и в зависимости от контекста - других вопросов и текста разделов. Поэтому в разных множествах вопросов одни и те же вопросы могут быть приняты в одном множестве и отвергнуты в другом.
Некоторой рекомендацией может быть использование в текстах разделов справочного руководства и в вопросах, их сопровождающих, ключевых слов на английском языке. С английским Мастер Ответов справляется значительно лучше, чем с русским. По понятным причинам этой рекомендации не всегда можно следовать в пользовательских справочных руководствах, ориентированных на русскоязычного читателя.
Еще одна принципиальная сложность связана с окном справки, в котором отображаются разделы справочного руководства. В предыдущей лекции было показано, как можно в приложение добавить собственный пункт меню или
То, что Помощник отображает справочное руководство в своем окне справки, не является ограничением. Достоинство предлагаемого подхода состоит в том, чтобы, сохраняя возможность получения стандартных справок по приложениям Office 2000, одновременно иметь возможность получать справки по терминам, специфичным для данного документа, отражающим его пользовательскую направленность. Поэтому в окне справки должны отображаться как разделы пользовательского, так и стандартного справочного руководства. Хотя окно справки является "слугой двух господ", свой внешний вид оно сохраняет постоянным, ориентированным на стандартное справочное руководство Office 2000. Конечно же, наряду с возможностью использования Office
А теперь прошу обратить особое внимание на одно важное требование, без соблюдения которого разделы пользовательского руководства не будут отображаться в стандартном окне справки. Скомпилированный chm-файл пользовательского справочного руководства должен быть зарегистрирован в реестре Windows. Без этого его разделы не будут отображаться в стандартном окне справки.
Регистрация не требуется при открытии справочного руководства в собственном окне.
Для регистрации chm-файла в реестре можно воспользоваться Редактором реестра (regedit.exe). Файл регистрируется в разделе: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\HTML Help
В этом разделе зарегистрированы все chm-файлы, задающие стандартные справочные руководства. Здесь же нужно для собственного справочного руководства ввести новый строковый параметр, имя которого совпадает с именем chm-файла, а значение задает путь к этому файлу.
(рис 9.7) Регистрация в реестре Windows chm-файлаДавайте займемся еще одной проблемой, возникающей при отображении разделов справочного руководства в стандартном окне справки. Как я уже говорил, Office
(рис 9.8) Отображение разделов стандартного и пользовательского руководств по заданному индексуКак видите, индексу "bitmap" соответствуют несколько тем из нашей справочной системы и множество тем стандартного справочного руководства. В правом подокне отображается один из разделов нашего руководства.
Но мы отвлеклись, и так и не сформулировали суть проблемы. А она связана с вкладкой "Содержание". Дело в том, что нельзя объединить содержание двух справочных руководств - стандартного и пользовательского. Так какое же содержание должно быть показано? Однозначного ответа нет. Все зависит от выбора разработчика, который может управлять этим процессом на этапе создания chm-файла. В предыдущей лекции я рассказывал об определении окна справки, задании его свойств, о том, что задание вкладок "Избранное" и "Поиск" осуществляется включением флажков, задающих соответствующие свойства окна, в котором будет отображаться справочное руководство. Я не стал там заострять внимание на возможных проблемах, связанных с просмотром справочного руководства в окне справки. Теперь пришла пора сказать об этом. Для того чтобы просматривать стандартное оглавление в окне справки, при его определении необходимо выполнить следующие условия:
Вот как выглядит редактирование проекта HTML Help
(рис 9.9) Редактирование hhp-проекта в окне текстового редактора "Блокнот"Для удобства восприятия рисунка я разорвал строку определения окна, что позволило увидеть весь текст этой строки. Фактически, определение окна задается одной строкой.
В том случае, когда окну справки дано собственное, а не стандартное имя, при работе Office
Подведем теперь некоторые итоги и суммируем те факты, которые необходимо учитывать для обеспечения гладкого взаимодействия между различными инструментальными средствами - HTML Help
В заключение рассказа о сложностях, которые могут возникнуть при создании справочной системы, хочу напомнить, что при работе в корпоративной сети справочное руководство, зачастую, представляется в виде Web-узла, а не в виде скомпилированного chm-файла. В этом случае возникают свои проблемы, о которых я здесь не упоминаю, поскольку решил ограничиться подробным изложением одного варианта, ориентированного на использование справочной системы, установленной на локальной машине.
Нам осталось рассмотреть в деталях заключительный шаг в обеспечении взаимодействия Office
Итак, будем полагать, что, используя инструментарий HHW, справочное руководство успешно создано, построен и зарегистрирован скомпилированный chm-файл. Будем полагать также, что инструментарий AWB позволил создать индексируемый aw-файл ответов на возможные вопросы пользователей, желающих получить нужную им справку. Как присоединить полученный aw-файл к Office
Прежде всего, напомню, что когда пользователь формирует свой вопрос в окне Помощника, то для ответа на этот вопрос Office
Public Sub HelpOfHelp()
'Создание объекта Answer Wizard
'добавление файлов ответа к справочной системе
Dim i As Integer
Dim customAnswerWizard As AnswerWizard
Set customAnswerWizard = Application.AnswerWizard
With customAnswerWizard
'Восстановление стандартного множества aw-файлов
.ResetFileList
'Показать Помощника
Assistant.Visible = True
Debug.Print .Files.Count
'Отключение стандартных файлов в тех случаях,
'когда используется только собственное справочное руководство
'.ClearFileList
'Добавление собственного справочного руководства
.Files.Add ("e:\O2000\Book2\Cd\Help1\HelpOfHelp.aw")
'Отладочная печать aw-файлов
For i = 1 To .Files.Count
Debug.Print .Files(i)
Next i
Debug.Print .Files.Count
End With
End Sub
В моем тестовом документе эта процедура вызывается в ответ на щелчок специально спроектированной командной кнопки. Но, конечно же, чаще всего подобную процедуру следует включать в процедуру инициализации документа, вызываемую в обработчике события Open.
Несколько комментариев к этой процедуре. Я ввел ResetFileList восстанавливает список стандартных файлов, присущих объекту AnswerWizard. Метод ClearFileList делает этот список пустым, он используется перед добавлением собственных aw-файлов, например, для того, чтобы можно было работать только с этими файлами. Заметьте, метод ClearFileList в процедуре закомментирован. Это позволяет одновременно работать со стандартным и собственным справочным руководством. Вот как выглядит запрос на справку, сформулированный в Office
(рис 9.10) Вопрос и ответ в Office Assistant Как видите, Мастер Ответов на вопрос "Help" указал разделы, как нашего справочного руководства, так и стандартного. Заметьте, в стандартном руководстве используются русские имена разделов. При создании собственного руководства мне не удалось справиться с решением этой задачи. И в заключение рассказа взгляните еще на один экран, на котором одновременно показаны два окна справки - стандартное окно и собственное окно. В обоих окнах отображается наше справочное руководство. Окна имеют разные закладки, одно из них открыто Office
(рис 9.11) Справочное руководство, открытое в двух окнах На этом и завершим рассказ о том, как Office
Важной составляющей профессионально создаваемых систем является предоставление пользователю возможности получить "на лету" справку ко всем элементам интерфейса. Для чего предназначена та или иная команда меню? Что произойдет при нажатии этой командной кнопки? Каков формат данных, вводимых в это поле ввода? На все подобные вопросы пользователь должен иметь возможность получить немедленную справку, не роясь в недрах справочного руководства. Такие специальные справки к элементам интерфейса называются справками типа "Что это такое?". Они представляют контекстно-чувствительные справочные сообщения, появляющиеся во всплывающих (pop up) окнах, когда, например, специальный курсор подводится к тому или иному элементу интерфейса или выбирается пункт меню из контекстного меню, открываемого при нажатии правой кнопки на элементе интерфейса, или нажимается клавиша F1, когда элемент интерфейса находится в фокусе ввода.
Тема организации подобных справок достаточно обширна, прежде всего, из-за разнообразия интерфейса. Одно дело организовать справку к элементам интерфейса внутри формы, скажем к
Я начну с подробного рассмотрения одного вопроса - создания контекстных справок для элементов интерфейса внутри формы. Во-первых, это, пожалуй, наиболее важный случай, во-вторых, организация справок для других ситуаций имеет много общего. Но есть и еще одна серьезная причина, она заключается в том, что мне не удалось полностью решить поставленную задачу. Полагаю, что рассказ о возникающих проблемах может быть не менее интересен для тех, кто будет решать аналогичную задачу. Тем более что часть из этих проблем мне удалось преодолеть, хотя и не в полном объеме. К проблемам я был готов, поскольку в Руководстве программиста по VBA Office 2000 сказано, что для организации контекстных справок следует использовать предыдущий вариант инструментария справочной системы, используя WinHelp, а не HTML Help. С другой стороны, в описании системы HTML Help
Работа по организации справок данного типа состоит из двух частей. Часть работы связана с программным проектом, формой, элементами интерфейса данной формы. Нужно уметь корректно задать нужные свойства при проектировании всех этих элементов, для того чтобы появились подобные справки. Вторая часть этой работы состоит в подготовке разделов справки, и она выполняется специальным инструментарием, например, Winhelp или HHW.
Для того чтобы обеспечить возможность появления всплывающих подсказок к элементам интерфейса в формах, следует выполнить три условия:
HelpContextID.HelpContextID, необходимо задать значение еще двух свойств - WhatThisButton и WhatThisHelp.Давайте поговорим обо всем этом подробнее. Прежде всего, обратите внимание, что справочное руководство связывается с проектом, а не с формой. Оно одно на весь проект, поэтому, сколько бы не было различных форм, все разделы справки должны быть собраны в одно руководство. Заметьте, также, что файл, содержащий руководство, может иметь расширение htm или chm в зависимости от того, каким инструментарием он подготовлен. Надеюсь, не надо объяснять, как нужно задавать свойства программного проекта. Ранее я уже об этом говорил.
Булевы свойства WhatThisButton и WhatThisHelp формы должны быть установлены как true (истина). Включение кнопки WhatThisHelp обеспечивает поддержку выдачи контекстных справок. Если же дополнительно включена кнопка WhatThisButton, то в этом случае в правом углу заголовка формы появится дополнительная кнопка со знаком вопроса, и форма приобретет новое качество. Всякий раз, когда пользователь щелкнет эту кнопку, курсор изменит свой внешний вид - рядом с курсором будет плавать знак вопроса. Достаточно теперь подвести такой курсор к выбранному элементу интерфейса и щелкнуть по нему, как в появившемся всплывающем окне отобразится контекстная справка, поясняющая суть данного элемента.
Понятно, что чудес не бывает и появляющийся раздел справки однозначно определяется числовым значением контекстного идентификатора - HelpContextID, установленного для каждого элемента интерфейса. Особых требований к этим идентификаторам не предъявляется, важно только, чтобы они были уникальными, позволяя для каждого элемента интерфейса во всем программном проекте однозначно установить нужный раздел справочного руководства. Возникает вопрос, - откуда берутся значения этих идентификаторов? Это вопрос о том, что было раньше - курица или яйцо. Если раньше строится справочное руководство, а уж потом контекстно-чувствительные справки добавляются к программному проекту, то значения идентификаторов определяются при построении справочного руководства. Чаще всего, возникает обратная ситуация, когда проектируется форма, задаются уникальные значения контекстных идентификаторов для каждого ее элемента, а потом уже строится справочное руководство, поддерживающее данные значения. В общем, правильный ответ состоит в том, что на этапе проектирования системы должны быть предусмотрены разделы справки для каждого элемента интерфейса и связанные с этими разделами два уникальных идентификатора - числовой (HelpContextID) и строковый, называемый символическим идентификатором раздела. О символических идентификаторах поговорим позже. Сейчас же замечу, что вся система контекстных справок, где бы они ни выдавались, - в формах или документах, построена на использовании этих двух видов идентификаторов. Скажу также, что и возникающие проблемы связаны с тем, что не всегда удается построить правильное отображение между идентификаторами и соответствующими разделами справки.
В качестве примера формы с элементами интерфейса, для которых попытаемся построить контекстные справки, я взял уже знакомую форму из игры "Волк, Коза и Капуста". Я слегка модифицировал интерфейс этой формы и вот как он теперь выглядит:
(рис 9.12) "Новый" интерфейс в игре "Волк, Коза и Капуста" Наша форма была достаточно специфичной, - все ее элементы интерфейса были рисунками, в ней отсутствовали типичные для форм элементы - поля ввода, списки, кнопки. К каждому рисунку я добавил подпись, вдвое увеличив тем самым число элементов интерфейса. Добавление подписей позволяет мне обратить Ваше внимание на два важных момента. Во-первых, рисунки не имеют свойства HelpContextID и поэтому для них не возможна контекстная справка. Так что добавление подписей является в данном случае вынужденной мерой, позволяя получить справку по подписи к рисунку. Во-вторых, и в тех случаях, когда элемент интерфейса, например, поле ввода, имеет HelpContextID и может реагировать на пользовательский запрос, целесообразно эту же справку связывать и с подписью, сопровождающей этот элемент. Дело в том, что пользователь часто предпочитает щелкнуть по подписи, чтобы получить справку, а не на сам элемент интерфейса. Щелкнуть по подписи кажется более естественным и более безопасным.
Итак, подведу некоторые итоги. У меня есть программный проект, в нем есть форма, в ней элементы интерфейса и я выполнил все три условия, необходимые для организации контекстной справки типа "Что это такое?". В свойствах элементов интерфейса (в данном случае - это одни подписи, что не играет принципиальной роли) я задал значения HelpContextID от 1000 до 1009. Для рисунков, напомню, задать идентификатор для получения контекстной справки, к сожалению, невозможно. Можно было бы задать идентификатор для самой формы, но я этого не сделал, поскольку в нашей форме из-за визуальных объектов не осталось "живого" места. На следующем шаге я изменил значения вышеупомянутых булевых свойств формы и, как можно видеть на рисунке, у формы появился знак вопроса в правом верхнем углу. Я установил в свойствах программного проекта имя файла справочного руководства, которое должно содержать разделы справки для каждого элемента интерфейса. Этот файлу я дал длинное имя "WhatThisHelpToWGC.chm" и его предстоит создать уже знакомыми средствами инструментария HTML Help
В предыдущей лекции подробно рассказывалось, как создать справочное руководство средствами HHW. Сейчас нам предстоит познакомиться с некоторыми новыми, ранее не упоминавшимися возможностями этой системы. Мы поговорим, конечно, о включении в руководство специальных контекстных справок, но не только об этом. Рассмотрим два основных вопроса:
Ранее, когда речь шла о создании справочного руководства и работы с ним, не возникала необходимость использования идентификаторов разделов, поскольку в нужном месте открывалась вся справочная система, и поиск раздела осуществлялся с помощью специальных средств - оглавления, указателей и других. Но в ряде случаев, как, например, при получении контекстной справки, необходимо сразу же открывать нужный раздел справочной системы. В этом случае без знания идентификаторов разделов не обойтись. Иногда нужно знать символьный идентификатор, иногда числовой, как, например, при работе с элементами интерфейса формы.
Для того чтобы разделы справочного руководства связать с числовыми и символьными идентификаторами, при работе в HHW требуется установить два отображения. Первое отображение задается в специальной секции MAP, оно устанавливает соответствие между двумя видами идентификаторов. Второе отображение задается в секции ALIAS, - оно связывает символьные идентификаторы с именами файлов, хранящих разделы справки. В совокупности оба отображения позволяют, зная любой из идентификаторов, найти нужный раздел справки.
Поскольку одной из наших целей является включение в справочное руководство специальных контекстных справок, то мы также рассмотрим создание в hhp-проекте секции TEXT POPUPS, в которой задается ссылка на текстовый файл, содержащий контекстные справки и устанавливается соответствие между этими справками и их идентификаторами.
Давайте перейдем к рассмотрению подробностей построения каждого из упомянутых отображений и формирования секций hhp-проекта: MAP, ALIAS, TEXT POPUPS.
Отображение между двумя видами идентификаторов - символьными и числовыми - представляется в виде определения последовательности
#define <символьный идентификатор> <числовой идентификатор>
Вот как выглядит отображение, задаваемое для нашего примера:
#define IDH_Man 1000 #define IDH_Wolf 1001 #define IDH_Goat 1002 #define IDH_Cabbage 1003 #define IDH_Boat 1004 #define IDH_River 1005 #define IDH_LeftBank 1006 #define IDH_RightBank 1007 #define IDH_Shark 1008 #define IDH_Island 1009
Заметьте, символьные идентификаторы начинаются префиксом IDH_. В этом случае система HHW опознает их как символьные идентификаторы и осуществляет весьма полезные проверки корректности задания отображения между идентификаторами и разделами справки. Так что рекомендуется всегда использовать этот префикс в символьных именах. Это отображение строится в обычном текстовом редакторе внутри HHW, в Блокноте или в Word, если Вы привыкли там работать. Файл сохраняется как текстовый файл с уточнением ".h". Это уточнение типично для заголовочных файлов языка C. По сути, файл таковым и является, он является частью hhp-проекта и хранится в каталоге проекта вместе с остальными файлами. Теперь несколько слов о том, как создается секция MAP.
При работе с вкладкой Project в главном окне среды HHW на левой
HTML Help API Information. Она называется так, потому что API функция HTML Help, которая явно или неявно используется при вызове разделов справочной системы, требует в качестве информации (параметров) задания числовых или символьных идентификаторов. Но об этом мы еще поговорим позже.
Щелчок по данной кнопке открывает диалоговое окно, три вкладки которого обеспечивают создание трех секций hhp-проекта, о которых идет речь. Вот как выглядит это окно, открытое на вкладке MAP:
(рис 9.13) Создание секции MAPПо существу, в этом окне нужно задать имя заголовочного (Header) файла, задающего отображение между символьными и числовыми идентификаторами. Как создается этот файл, я только что рассказал. Казалось бы, нет ничего проще, чем задать имя файла. В данном случае и, к сожалению, это не так. Процесс по непонятным причинам усложнен. При его выполнении возникают ошибочные ситуации, приводящие, по моему мнению, в дальнейшем к некорректной работе системы. Давайте подробно рассмотрим все этапы этого процесса.
(рис 9.14) Первое окно открытия файлаВ этом окне уже появилась кнопка Browse. Нажмем ее.
(рис 9.15) Второе окно открытия файлаТеперь прошу обратить особое внимание на два факта. Первый - в качестве шаблона для поиска файлов указан шаблон "*.h", Второй факт - в открытой папке HelpToWGC не найдено ни одного файла с таким уточнением. Могу Вас заверить, что заголовочные файлы с уточнением h присутствуют в этом каталоге. Прежде чем обсуждать данные факты, продолжим работу. Естественно я ввел известное мне имя заголовочного файла в поле имени и нажал кнопку "Открыть". В результате я получил ответ, что найти файл в каталоге не удалось:
(рис 9.16) Третье окно открытия файлаПосле этого мне осталось ничего другого, как вернуться к окну
(рис 9.17) Четвертое окно открытия файлаПосле моего утвердительного ответа было сформировано предложение #include, составляющее секцию MAP. Для тех, кто знает язык C, понятно, что предложение #include обрабатывается препроцессором и вставляет заголовочный файл в текст компилируемого модуля. Несмотря на то, что это предложение, в конечном итоге, было сформировано правильно, я понимаю, что система не видит заголовочный файл, а, следовательно, не может построить нужное отображение и в нужный момент открыть требуемый раздел справки
Даже, если бы все работало корректно, то весь этот длинный процесс открытия файла представляется мне примером неудачного, я бы даже сказал, непрофессионального решения.
Несколько слов о том, почему не виден файл с уточнением ".h". Он и не должен быть виден, поскольку это текстовый файл, и он будет отображаться, когда шаблоном будет служить уточнение ".txt". Другое дело, что в грамотной реализации нужно вначале найти все текстовые файлы и отобрать среди них те файлы, которые имеют уточнение h. Подводя итог, следует сказать, что хотя формально секция MAP была создана, но фактически процесс ее создания потерпел неудачу и файл, указанный в этой секции не будет виден системой. Выход из этой ситуации есть, но об этом чуть позже. Аналогичная ситуация с заголовочными файлами возникает и при работе с двумя другими вкладками в процессе создания секций ALIAS и TEXT POPUPS.
Прежде, чем формировать секцию ALIAS, в справочном руководстве HHW рекомендуется построить еще один заголовочный файл, задающий отображение межу символическими идентификаторами и именами файлов, содержащих соответствующие разделы справочного руководства. Я напомню, что
Символьный идентификатор> = <Имя файла>
В нашем примере этот заголовочный файл выглядит следующим образом:
IDH_Man = Man.htm IDH_Wolf = Wolf.htm IDH_Goat = Goat.htm IDH_Cabbage = Cabbage.htm IDH_River = River.htm IDH_LeftBank = LeftBank.htm IDH_RightBank = RightBank.htm IDH_Shark = Shark.htm IDH_Boat = Boat.htm IDH_Island = Island.htm
Перейдем теперь к формированию секции ALIAS. При выборе одноименной вкладки в отличие от вкладки MAP появляются две возможности создания секции.
(рис 9.18) Создание секции ALIASНажатие кнопки INCLUDE позволяет создать секцию ALIAS за один шаг, используя подготовленный в текстовом редакторе заголовочный файл. В этом случае открывается уже знакомое окно "
Я построил hhp-проект, в секциях MAP и ALIAS которого использовались заголовочные файлы. Но тестирование этого проекта показало, что заголовочные файлы реально не видны и нужное отображение не строится. Взгляните, как выглядит сообщение, полученное мной при тестировании одного из примеров:
(рис 9.19) "Неуспех" при тестировании проекта с заголовочными файламиЯ напомню, для тестирования проекта после его компиляции из пункта меню Test главного меню системы HHW следует выбрать команду HTML Help API. В открывшемся окне из списка Command следует поочередно выбрать и протестировать две команды: HH_DISPLAY_TOPIC и HH_HELP_CONTEXT. Первая из них отображает разделы, при задании имени файла, содержащего данный раздел. С этой командой особых трудностей обычно не возникает. Чтобы успешно работала вторая команда, где задается числовой идентификатор, требуется успешное создание раздела MAP. В нашем примере успеха нет и причина этого нам известна - заголовочные файлы не работают так, как нужно.
Как справиться с возникшей проблемой? На самом деле это не сложно. Вот что нужно сделать:
Вот как выглядят теперь результаты тестирования для предыдущего примера, когда я проделал всю указанную работу:
(рис 9.20) Успешное получение раздела справки по его числовому идентификаторуТо, что, в конечном счете, удается успешно создать числовые и символьные идентификаторы разделов, имеет крайне важно, поскольку эти идентификаторы широко используются при выдаче контекстных справок в самых разных ситуациях, о которых мы еще поговорим. А теперь пора перейти к проблеме, успешное решение которой мне так и не удалось найти. Но прежде хочу обратить Ваше внимание еще на одну ошибку, которая может возникать в процессе работы с hhp-проектом. Если возникает необходимость провести редактирование разделов MAP и ALIAS, то делать это нужно в текстовом редакторе "Блокнот". Попытка провести редактирование этих разделов в HHW приводит к непоправимой ошибке и снятию приложения.
Инструментарий HHW позволяет создавать и включать в справочное руководство специальную секцию TEXT POPUPS, предназначенную для обеспечения работы с контекстными справками к элементам интерфейса и появление этих справок во всплывающих окнах. Созданию секции TEXT POPUPS, которая необходима при работе с такими контекстными справками, должно предшествовать создание двух текстовых файлов. Один из них уже может существовать, если создавалась секция MAP, - это заголовочный файл, задающий отображение между символьными и числовыми идентификаторами. Второй текстовый файл содержит описание контекстных сообщений, которые будут появляться во всплывающих окнах. Чуть позже я расскажу о синтаксисе, которому должен удовлетворять этот файл. После того, как эти два файла будут созданы, можно переходить к созданию секции TEXT POPUPS, для чего достаточно нажать одноименную вкладку.
(рис 9.21) Создание секции TEXT POPUPSДве
Контекстные справки, появляющиеся во всплывающих окнах, как правило, представляют собой тексты небольшого размера. Поэтому в отличие от обычных разделов справочного руководства, каждый из которых содержится в отдельном файле, все такие контекстные справки могут быть собраны в одном файле. Иногда предпочтительнее вместо одного большого файла иметь несколько файлов, например, отдельные файлы для элементов каждой формы. Такой сборный файл с контекстными справками в HHW создается в текстовом, а не в HTML формате. Структура такого файла достаточно проста и удовлетворяет следующему синтаксису:
<Заголовок раздела> <Текст контекстной справки> [ <Заголовок раздела> <Текст контекстной справки>]…
Файл, как видите, представляет последовательность озаглавленных разделов.
.topic <Символьный идентификатор>
Текст контекстной справки представляет собой обычный текст без картинок и прочих украшений, возможных для текстов в формате HTML, используемых в разделах справочного руководства. Вот два начальных раздела из файла, созданного для очередного примера:
.topic IDH_Man Вот Человек, который следит за всеми зверьми. Он не допустит, чтобы волк съел козу, не разрешит козе съесть капусту. Он перевезет всех с левого берега на правый берег реки. Он помнит, что лодка его мала и не выдержит трех пассажиров. .topic IDH_Wolf Это волк, который дружен с человеком, равнодушен к капусте, но обязательно съест козу, если рядом нет человека.
В hhp-проект, создаваемый для игры "Волк, Коза и Капуста", были включены, как HTML-файлы с разделами справочного руководства, так и текстовый файл, содержащий контекстные справки к элементам интерфейса, подготовленные для показа во всплывающих окнах. Соответственно проект содержит все три секции - MAP, ALIAS и POPUPS. Заменить в секции POPUPS заголовочный файл на его содержание не удается, по причинам, о которых я уже говорил. В результате файл компилируется с ошибками и, хотя они носят характер предупреждений, нужное отображение между идентификаторами и разделами контекстной справки так и не строится. Вот как выглядит результат трансляции проекта:
(рис 9.22) Результат компиляции hhp-проекта игры "Волк, Коза и Капуста quot;С другой стороны стоит отметить, что при тестировании проекта обе команды HtmlHelp API функции работают успешно, что уже само по себе обеспечивает возможность организовать получение контекстных справок, используя вызовы функции HtmlHelp.
На этом я завершаю описание двух важных вопросов, возникающих при создании chm-файлов. В конечном итоге, мы научились связывать символьные и числовые идентификаторы с разделами справочного руководства. Я подробно описал, как можно построить сборный текстовый файл, содержащий контекстные справки, и как добавить секцию POPUPS в справочное руководство, но, к сожалению, мои усилия по разрешению проблем, возникающих на этом этапе, не увенчались успехом.
Проделана вся необходимая работу, как на стороне программного проекта "Волк, Коза и Капуста", так и на стороне создания справочного руководства для этой игры. Я создал и зарегистрировал chm-файл, содержащий, как разделы обычного справочного руководства, так и контекстные справки к элементам интерфейса формы, представляющей игровое поле. На основе chm-файла был создан и Aw-файл, позволяющий Рокки отвечать на вопросы. Осталось провести эксперименты и посмотреть, что из всего этого работает. Прежде всего, я попытался получить контекстные справки к тем надписям на форме, для которых определены числовые идентификаторы и созданы соответствующие разделы в справочном руководстве:
(рис 9.23) Попытка получения контекстной справки к элементу интерфейсаКак видите, выдается сообщение об отсутствии контекстной справки для этого элемента интерфейса. Хотя истинная причина состоит не в отсутствии раздела, а в том, что не задано нужное отображение числового идентификатора на символьный идентификатор и связанный с ним раздел, где содержится контекстная справка. Что же все-таки работает в данной ситуации? Если специализированный курсор со знаком вопроса не подводить к элементам интерфейса, для которых задан HelpContextID, а щелкнуть где-нибудь в произвольном месте формы, то откроется справочное руководство и можно будет получить справку обычным способом. Заметьте, что для этого не понадобилось создавать никаких дополнительных командных кнопок или команд меню. Это не совсем то, что хотелось бы, но вызывать справочное руководство в форме достаточно просто, что, в конечном счете, позволяет получить справки ко всем элементам интерфейса.
Для получения контекстных справок в формах может использоваться и клавиша F1. В нашем примере она работает также как и специальный курсор со знаком вопроса, позволяя открыть справочное руководство, но открывающийся раздел всегда задается самой формой - ее HelpContextID и не зависит от того, какой элемент интерфейса был активным. Заметьте, нажатие клавиши F1 приводит к открытию справочного руководства и в том случае, если свойство формы WhatThisButton выключено.
Справки может выдавать и Помощник.
(рис 9.24) Рокки отвечает на вопрос об основных героях игрыКак видите, Рокки показал все темы, в которых описаны запрашиваемые визуальные объекты. Это еще один способ решения поставленной задачи. Способ справиться с задачей всегда существует. Надеюсь, правда, что в следующей версии HHW не нужно будет искать обходные пути и будет доступен прямой способ решения данной задачи.
Подведем некоторые итоги и посмотрим, как в разных приложениях Office 2000 может использоваться справочное руководство. Во многих случаях получение справок основано на технике, использующей числовые идентификаторы, связанные с разделами справочного руководства. С объектной точки зрения многие объекты, так или иначе, входящие в состав Office 2000, обладают свойствами HelpFile и HelpContextID, определяющими файл, где хранится справочное руководство и числовой идентификатор, однозначно определяющий раздел внутри этого руководства. Файл справочного руководства может быть создан различными инструментальными средствами - HTML Help
Access, как известно, имеет свою специфику, и его объектная модель существенно отличается от других приложений Office 2000. Access не использует библиотеку MSForms и формы, создаваемые в Access, отличаются от форм, используемых в других приложениях, в том числе и по своим свойствам.
Для каждой формы или отчета Access можно создать собственное справочное руководство. Можно, конечно, иметь одно руководство для всех объектов базы данных Access. Объекты Form и Report в Access обладают свойствами HelpFile и HelpContextID, которые можно установить на этапе проектирования или программно. Элементы управления, размещаемые в формах, обладают свойством HelpContextID, задающим числовой идентификатор раздела справки, что позволяет связать каждый элемент с соответствующим разделом справочного руководства. Работая с формой, пользователю достаточно нажать клавишу F1, чтобы получить контекстную справку к тому или иному элементу управления. Зная HelpContextID элемента управления, находящегося в фокусе ввода, и файл, связанный с формой, система отображает в окне справки нужный раздел справочного руководства. Если HelpContextID для активного элемента управления не задан, то отображается раздел, связанный с формой.
В Word, Excel и Power Point формы представляются объектом UserForm, принадлежащим общей библиотеке MSForms, являющейся частью объектной модели этих приложений. В отличие от близкого по духу объекта Form в Access, объект UserForm не имеет ни свойства HelpFile ни свойства HelpContextID. Правда, на этапе проектирования для формы можно задать свойство HelpContextID. Это же свойство можно задать на этапе проектирования и для элементов управления, размещаемых в форме. С объектной точки зрения объект UserForm обладает коллекцией Controls, а каждый элемент этой коллекции - объект Control - обладает свойством HelpContextID.
Как уже говорилось ранее, с формой в этих приложениях нельзя связать отдельный файл справочного руководства. Единое справочное руководство связывается со всем программным проектом. Свойство HelpFile можно установить на этапе проектирования или программно, используя объект VBProject, входящий в общую библиотеку VBIDE. Этот объект имеет и свойство HelpContextID, которое используется в Object Browser, когда необходимо получить справку о данном проекте. О том, как работает клавиша F1 в формах, я написал выше.
Наряду с формами, основными элементами интерфейса, создаваемого для документов Office 2000, являются пользовательские CommandBar. Ее свойство Controls возвращает коллекцию класса CommandBarControls. На панелях располагаются элементы разного типа - меню и команды меню, кнопки нескольких возможных видов. Как объекты, эти элементы принадлежат следующим классам: CommandbarButton, CommandBarComboBox, CommandBarControl, CommandbarPopUp. Объекты всех этих классов обладают свойствами HelpFile и HelpContextID. Оба свойства должны быть заданы для каждого элемента. Заметьте, файл, задающий справку, не связывается ни с панелью, ни с документом, а указывается для каждого отдельного элемента. В принципе это дает некоторую свободу и позволяет, например, иметь отдельный файл для каждой
Public Sub AddHelpProps()
'Добавление контекстных справок к элементам панели
Dim panel As CommandBar
Dim ctrl As CommandBarButton
Dim HelpFilePath As String
HelpFilePath = "e:\O2000\DsCd\WhatThisHelpToWGC\HelpToWGC.chm"
Set panel = CommandBars("ButtonPanel")
'Устанавливаем свойства элементов панели
'Help Свойства кнопки
Set ctrl = panel.Controls(1)
ctrl.HelpFile = HelpFilePath
ctrl.HelpContextId = 1000
Set ctrl = panel.Controls(2)
ctrl.HelpFile = HelpFilePath
ctrl.HelpContextId = 1001
Set ctrl = panel.Controls(3)
ctrl.HelpFile = HelpFilePath
ctrl.HelpContextId = 1002
End Sub
Свойства HelpFile и HelpContextID имеют целый ряд программных объектов, начиная с главного программного объекта VBProject и кончая его компонентами - формами и модулями. Эти свойства имеет объект Err и метод Raise, используемые при обработке программных ошибок. Обладают этими свойствами и широко употребительные функции - MsgBox и InputBox. В конце этой лекции я чуть подробнее расскажу о том, как выдаются справки на разных этапах работы с программным проектом.
Я уже рассказывал в предыдущей лекции о том, как можно показать справочное руководство в ответ на запрос пользователя, нажавшего специально спроектированную
Поговорим теперь еще о двух способах программного вызова справочной системы в принципе, позволяющих не только вызвать справочное руководство, но и открыть его на нужном разделе. Эти два способа основаны на использовании:
Метода Help, которым обладают объекты Application приложений Office 2000.
Функции API - HtmlHelp.
Метод Help по-разному работает для разных приложений - в Word и Access он позволяет получать справки только по стандартным разделам. В приложениях Excel и Power Point метод Help позволяет получить справку к заданному разделу пользовательского справочного руководства.
В приложении Word этот метод имеет следующий синтаксис:
Help(HelpType)
Параметр HelpType задается константой типа wdHelpType. Каждая константа определяет тот или иной вид справки. Вот небольшой пример:
Public Sub CallHelp() 'Вызов стандартной справки Application.Help (wdHelpAbout) End Sub
Синтаксис метода Help в приложениях Excel и Power Point следующий: Help(HelpFile, HelpContextID)
Параметры этого метода нам хорошо знакомы. Тем самым, в этих приложениях становится доступна работа с пользовательским справочным руководством и его разделами. В конечном итоге, это позволяет организовать выдачу контекстных справок в обработчиках различных событий - по нажатию специальных кнопок, по нажатию клавиши F1 или любой другой специальной клавиши. Возможностей здесь много.
Я рассмотрю сейчас пример, в котором метод Help будет использоваться для получения справок об элементах интерфейса формы. Это будет все та же форма с игрой "Волк, Коза и Капуста". Для того, чтобы она заработала в Excel, мне пришлось, конечно, выполнить операции экспорта - импорта формы и соответствующих модулей. Еще одно типичное изменение в таких случаях связано с заменой объекта ActiveDocument на ActiveWorkBook, определяющих соответственно активные документы Word и Excel.
Моя цель состоит в том, чтобы получать контекстные справки к элементам интерфейса данной формы, используя возможности метода Help в Excel. Вот как я собирался достичь этой цели. Как Вы помните, в форме для каждого визуального объекта введен дополнительный объект - надпись (Label). Надписи полезны сами по себе, но введены они были и по той причине, что графические объекты не имеют важного свойства HelpContextID. Для надписей это свойство существует и на этапе проектирования его значение можно установить. В обработчике события Click для каждой надписи я предполагал вызывать метод Help, передавая ему в качестве параметра контекстный идентификатор соответствующей надписи. Так что все выглядело достаточно логично, - всякий раз, когда пользователь щелкает мышью по надписи, ему в ответ выдается справка о визуальном элементе, связанном с этой надписью. Вот как выглядит спроектированный мной обработчик события Click для надписи:
Private Sub Label1_Click() 'Выдача контекстной справки - не работает!!! 'Глобальный параметр Myf задает путь к файлу справочного руководства 'Второй параметр метода Help позволяет по HelpContextID определить нужный раздел Call Application.Help(Myf, Me.Label1.HelpContextID) End Sub
Однако мой хорошо продуманный план потерпел неудачу из-за очередного HelpContextID, значение которого можно установить на этапе проектирования, программно работать с этим свойством для надписей невозможно. Ни установить, ни прочесть значение этого свойства программно не удается. Ошибка возникает, как при явных попытках работать с этим свойством, так и при вызовах внутри процедуры. Поэтому в приведенном примере вызов метода Help терпит неудачу из-за невозможности получить значение свойства HelpContextID для надписи. Так что Вам повезло, - Вы узнали еще об одной ошибке. А мне не повезло, поскольку пришлось в очередной раз переделать интерфейс моей формы. Надеюсь, Вы понимаете, что найти выход из данной ситуации нетрудно, - я заменил надписи другими элементами интерфейса, для которых свойство HelpContextID корректно работает как на этапе проектирования, так и программно. Вместо надписей я использовал специальные утапливаемые кнопки - объекты класса ToggleButton. Для них также существует событие Click, так что наша схема по-прежнему работает, - изменился лишь тип элементов, нажатие которых приводит к выдаче контекстной справки. Я внес лишь небольшие усовершенствования и вот как выглядит обработчик события Click для кнопки ToggleButton:
Private Sub ToggleButton1_Click() 'Выдача контекстной справки - работает!!! 'Глобальный параметр Myf задает путь к файлу справочного руководства 'Второй параметр метода Help позволяет по HelpContextID определить нужный раздел If Me.ToggleButton1.Value Then Call Application.Help(Myf, Me.ToggleButton1.HelpContextID) End If End Sub
Прежде, чем выдать справку, я проверяю, в каком состоянии находится кнопка. Справка выдается при нажатии кнопки. Для кнопки, находящейся в утопленном состоянии, щелчок по ней не приводит к повторной выдаче справки. Надеюсь, понятно, что аналогичные процедуры написаны для всех 10 кнопок нашей формы. Взгляните, как выглядит наша форма в Excel:
(рис 9.25) Форма для игры "Волк, Коза и Капуста", открытая в Excel Вот справочное руководство, открывающееся при нажатии кнопки "Остров Рокки"
(рис 9.26) Контекстная справка к элементу интерфейса Метод Help, как видите, может с успехом использоваться в программном коде, позволяя организовать в документах Excel и Power Point выдачу собственных контекстных справок. К сожалению, в приложениях Word и Access такой способ не применим. Существует другой, более мощный способ решения этой проблемы, применимый для всех приложений. Он основан на непосредственном вызове функции API - HtmlHelp, которая реально обеспечивает работу со скомпилированным chm-файлом и всегда вызывается явно или неявно.
Как и другие функции API, функция HtmlHelp написана на языке C и ее "родное" описание имеет следующий синтаксис:
HtmlHelp, в котором будет появляться справка.Список возможных команд велик. С двумя основными командами мы познакомились при тестировании chm-файла, создаваемого в среде HHW. Этими командами являются HH_DISPLAY_TOPIC и HH_HELP_CONTEXT. Обе команды отображают в окне справки HTML-файл, но пользуются разной информацией. Для первой команды параметр pszFile задает имя chm-файла, а параметр dwData должен указывать на файл с разделом справки, являющийся частью скомпилированного chm-файла. Команда HH_HELP_CONTEXT позволяет отобразить в окне справки HTML-файл, заданный числовым идентификатором. Параметр dwData в этом случае задает значение HelpContextID.
Функция HtmlHelp входит в состав библиотеки, определяющей HTML Help ActiveX элемент управления (HHCtrl.
Для того, чтобы эту функцию можно было вызывать в программном коде VBA, необходимо предварительно объявить ее в операторе DECLARE. Необходимо объявить также используемые константы, а в общем случае и типы данных. Основная проблема при этом состоит в том, чтобы правильно отобразить типы языка C на типы языка VB. Приведу два возможных варианта объявления функции HtmlHelp на VBA, которые использовались мной в экспериментах:
Public Const Myf = "e:\O2000\DsCd\HelpToWGC\WhatThisHelpToWGC.chm" 'Константы, необходимые для вызова API функции HtmlHelp Public Const HH_DISPLAY_TOPIC = H0 'Вызов по имени раздела Public Const HH_HELP_CONTEXT = HF 'Вызов по Context ID 'Описание API функции HtmlHelp Public Declare Function HtmlHelp Lib "hhctrl.ocx" _ Alias "HtmlHelpA" _ (ByVal hwndCaller As Long, _ ByVal pszFile As String, _ ByVal uCommand As Long, _ dwData As Any) As Long 'Описание варианта API функции HtmlHelp Public Declare Function HtmlHelpLongArg Lib "hhctrl.ocx" _ Alias "HtmlHelpA" (ByVal hwndCaller As Long, _ ByVal pszFile As String, ByVal uCommand As Long, _ ByVal dwData As Long) As Long
Обратите внимание, в первом варианте тип параметра dwData описан как Any. В этом случае при вызове не проверяется тип передаваемых данных, и вся ответственность за корректность вызова лежит на программисте. Это описание функции является универсальным и позволяет вызывать любые возможные команды, доступные для функции HtmlHelp. Во втором варианте описания функции тип параметра dwData зафиксирован. Этот вариант может быть использован при вызове команды HH_HELP_CONTEXT, когда в качестве значения передается числовой идентификатор.
Для иллюстрации возможностей работы с функцией API я использовал предыдущий пример, заменив вызовы метода Help на вызов функции HtmlHelp:
Private Sub ToggleButton1_Click() 'Выдача контекстной справки - работает!!! 'Глобальный параметр Myf задает путь к файлу справочного руководства 'Второй параметр метода Help позволяет по HelpContextID определить нужный раздел If Me.ToggleButton1.Value Then 'Call Application.Help(Myf, Me.ToggleButton1.HelpContextID) 'Вызов API функции HtmlHelp Call HtmlHelpLongArg(0, Myf, HH_HELP_CONTEXT, Me.ToggleButton1.HelpContextID) End If End Sub
Окно справки задается по умолчанию, все остальные параметры сохранили значение, используемое в методе Help. Замечу, что работа метода Help реально сводится к вызову функции HtmlHelp. Вот как выглядит теперь вызов контекстной справки в нашей игре, открытой в Excel:
(рис 9.27) Вызов контекстной справки, использующий API функцию HtmlHelpОсталось выполнить обратный экспорт модифицированной формы в Word и проверить работоспособность данного способа, что я и сделал. Смею Вас уверить, что все работает, как нужно, поскольку вызов функции API и в приложении Word остается вызовом функции API, - слон он и в Африке слон.
В предыдущем параграфе я говорил о том, как программно организовать выдачу контекстных справок. А сейчас мы поговорим о том, как можно получать справки о самом программном проекте. Я рассмотрю два вопроса:
Я напомню, что в окне просмотра объектов - браузере объектов (Object Browser) можно увидеть структуру каждого объекта, так или иначе составляющего документ Office 2000. Еще в момент возникновения документа строится его каркас на основе совокупности библиотек объектов, составляющих по сути Office 2000. В зависимости от типа документа и выбора пользователя в каркас документа включаются те или иные библиотеки. Объекты, включенные в эти библиотеки, являются стандартными, и в окне просмотра объектов можно увидеть не только структуру объекта - свойства, методы, события, константы, но и получить подробную справку, как о самом объекте, так и о его элементах. Когда с документом работает программист, то он достраивает каркас документа, создавая полноценное строение. Работа программиста, прежде всего, сводится к созданию программного проекта, который является неотъемлемой частью документа. Компонентами программного проекта являются формы, стандартные модули, модули классов. Каждая форма, создаваемая программистом, имеет, тем не менее, множество стандартных свойств, методов и событий. Наряду с ними программист населяет форму элементами управления, и эти
Структура программного проекта и всех его компонент доступна для просмотра в окне браузера. Проект является такой же библиотекой, как и остальные библиотеки, составляющие документ. Имя этой библиотеки совпадает с именем проекта. По умолчанию, если проекту не дается собственное имя, используется имя "Project". Если из списка библиотек, выбрать имя библиотеки, задающей проект, то в окне просмотра откроется структура проекта, все его компоненты. Возникает вопрос, можно ли получать справку о компонентах проекта - формах модулях проекта, о компонентах каждого модуля? Можно ли, например, получать справку о свойствах, методах и событиях классов, созданных программистом? Ответ на эти вопросы положителен, хотя и с некоторыми оговорками и сетованиями на то, что не все работает так, как хотелось бы.
Я напомню, что с программным проектом можно связать только одно справочное руководство, поэтому разделы справки для всех элементов проекта должны быть собраны в этом руководстве. Если такое руководство создано, - построен chm-файл, содержащий секции MAP и ALIAS, то для получения справок работает техника числовых идентификаторов - HelpContextID, уже подробно описанная для других ситуаций. Взгляните, как выглядит структура программного проекта с именем WGCProject:
(рис 9.28) Структура программного проекта WGCProject Заметьте, в левом окне Classes показаны все компоненты проекта, в правом окне MembersOf для компоненты, выбранной в левом окне, показана ее структура, - все элементы, входящие в ее состав. На рисунке для выбранного в левом окне класса объектов с именем WGCClass, показаны все элементы этого класса - заданные для него свойства и методы. В нижнем окне для выбранной компоненты показано ее определение. Давайте рассмотрим, как задаются определения компонент и разделы справочного руководства, появляющиеся при запросе справки о той или иной компоненте. Первым делом, в окне свойств проекта необходимо задать:
Никаких проблем не возникает и для компонент проекта, показанных в окне классов, то есть для форм и классов. Для задания определения такой компоненты и связывания с ней раздела справки необходимо:
HelpContextID и задать определение компоненты.Вот как выглядит диалоговое окно Member Options при задании характеристик класса с именем WGCClass:
(рис 9.29) Задание определения и HelpContextID для компоненты программного проекта Теперь конечный пользователь, которому будет передан документ, содержащий проект, в любой момент может получить справку о той или иной компоненте проекта. Для этого ему достаточно в окне браузера выбрать компоненту и нажать кнопку со знаком вопроса.
А теперь прошу обратить внимание, - аналогичная процедура задания определения и HelpContextID для элементов проекта более низкого уровня, заданных в правом окне MembersOf, в данной версии Office 2000 еще не работает. Поэтому, например, нельзя выдать контекстную справку о конкретном свойстве или методе пользовательского класса. Теоретически все должно работать аналогичным образом. Однако, если в этом окне на шаге 1 выбрать некоторое свойство, то на шаге 2 выбрать команду Properties не удастся, поскольку она недоступна (показана серым цветом). Для методов - команда доступна и появляется окно Member Options, в котором можно задать нужные характеристики. Однако они не запоминаются при нажатии кнопки "OK", так что заданные установки не вступают в силу. Можно, конечно, надеяться, что в последующих версиях все эти недоработки будут устранены.
Когда выполняется программный код, возможно возникновение ошибок, причины которых могут быть самыми разными. Это могут быть ошибки программиста, создающего код. Но часто причиной ошибок является нарушение спецификаций, гарантирующих корректную работу программы. Поэтому во многих ситуациях, когда уже ошибка возникла, очень важно выдать справку, объясняющую возможные причины ошибки. Понятно, что только стандартными справками в таких ситуациях не обойтись. Например, если ошибка возникает при работе объекта класса, созданного программистом, то именно он и должен позаботиться о выдаче корректных пользовательских справок, объясняющих природу ошибки. Для этой цели можно использовать те возможности, которые предоставляет объект Err и метод Raise, для которых можно указать имя chm-файла и HelpContextID соответствующего раздела.
Объект Err содержит информацию о последней ошибке выполнения. Этот объект создается вместе с проектом и имеет глобальную область определения. При возникновении ошибки заполняются свойства этого объекта и, тем самым, определяется имя chm-файла и HelpContextID данной ошибки. Затем эти свойства могут быть обработаны подходящим образом. Чаще всего, вызывается функция MsgBox, имеющая кнопку Help, нажатие которой приводит к выдаче контекстной справки. Метод Raise служит для возбуждения собственных ошибок, когда в результате анализа обнаружена исключительная ситуация, при которой невозможно нормальное выполнение программы. Метод Raise возбуждает ошибку, передавая нужные параметры объекту Err, в том числе имя chm-файла и HelpContextID собственной ошибки.
На этом я завершу изложение этой большой и важной темы, посвященной созданию справочной системы для документов Office 2000.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.