Требования к интерфейсу пользователя приложений для Windows
11.1.1. Общие рекомендации по разработке графического интерфейса.
Работая с различными программами Windows, графический интерфейс пользователя любой серьезной программы должен включать в себя:
11.1.2. Многооконные приложения.
Модели управления окнами приложения: (1) SDI - с интерфейсом одного документа, которая предполагает:
- Наличие родительского (первичного) окна,
- Наличие ряда дочерних окон, т.н. окон документов, являющихся однородными. Чтобы создать на основе проектного шаблона прототип приложения для работы в режиме многодокументного интерфейса (MDI), произведите следующие действия: File => New => Application => Окно New Items => Вкладка Projects => пиктограмма MDI Application
Характеристики, задающие стиль окон приложения:
Свойства формы:
(1) = bsSingle - для основного окна приложения с неизменяемыми размерами - наиболее подходящий стиль;
(2) = bsDialog - для вторичных диалоговых окон - наиболее подходящий стиль.
Команда Project => Options => страница Application: (1), (2)
(1) Title - заголовок, который увидит пользователь в полосе задач при сворачивании приложения.
(2) Load Icon - позволяет выбрать пиктограмму, которая будет видна в полосе задач при сворачивании приложения или при просмотре пользователем каталога, в котором расположен выполняемый файл приложения.
(1) fsNormal - окно обычного приложения, это значение FormStyle принято по умолчанию.
(2) fsMDIForm - родительская форма приложения MDI, т.е. приложения с дочерними окнами, используемого при работе с несколькими документами одновременно.
(3) fsMDIChild - дочерняя форма приложения MDI.
(4) fsStayOnTop - окно, остающееся всегда поверх остальных окон Windows.
11.1.4. Цветовое решение приложения.
Большинство компонентов имеют свойство Color (цвет), который вы можете изменять в Инспекторе Объектов при проектировании или программно во время выполнения (если хотите, чтобы цвета в различных режимах работы приложения были разные). Щелкнув на этом свойстве в Инспекторе Объектов, вы можете увидеть в выпадающем списке большой набор предопределенных констант, обозначающих цвета. Все их можно разбить на две группы: статические цвета типа clBlack - черный, cIGreen - зеленый и т.д., и системные цвета типа clWindow - текущий цвет фона окон, clMenuText - текущий цвет текста меню и т.д.
Не злоупотребляйте в приложении яркими цветами Пестрое приложение - обычно признак дилетантизма разработчика, утомляет пользователя, рассеивает его внимание Как правило, используйте системные цвета, которые пользователь может перестраивать по своему усмотрению Из статических цветов обычно имеет смысл использовать только clBlack - черный, clWhite - белый и cIRed - красный цвет предупреждения об опасности.
Единству цветового решения отдельных частей экрана способствует также использование свойства ParentColor. Если это свойство установлено в true, то цвет компонента соответствует цвету содержащего его контейнера или формы. Это обеспечивает единство цветового решения окна и, кроме того, позволяет программно изменять цвет сразу группы компонентов, если вы, например, хотите, чтобы их цвет зависел от текущего режима работы приложения. Для такого группового изменения достаточно изменить только цвет контейнера.
11.1.5. Шрифты текстов.
Шрифт надписей и текстов компонентов C++Builder задается свойством Font, имеющим множество подсвойств. Кроме того, в компонентах имеется свойство ParentFont. Если это свойство установлено в true, то шрифт данного компонента берется из свойство Font его родительского компонента - панели или формы, на которой расположен компонент. Использование свойств ParentFont и ParentColor помогает обеспечить единообразие отображения компонентов в окне приложения.
По умолчанию для всех компонентов C++Builder задается имя шрифта MS Sans Serif и размер - 8. Константа множества символов Charset задается равной DEFAULT_CHARSET. Последнее означает, что шрифт выбирается только по его имени и размеру. Если описанный шрифт недоступен в системе, то Windows заменит его другим шрифтом.
Вы можете при установке вашего приложения узнать, имеется ли на компьютере пользователя нужный шрифт, например, с помощью следующего кода:
if (Screen ->Fonts ->IndexOf ("Arial") == -1)
Другой выход из положения - ввести в приложение команду выбора шрифта пользователем. Это позволит ему выбрать подходящий шрифт из имеющихся в его системе. Осуществляется подобный выбор с помощью стандартного диалога, оформленного в виде компонента FontDialog. Проведенную пользователем установку можно запоминать в файле .ini, в реестре или в другом файле конфигурации и читать автоматически информацию из этого файла при каждом запуске приложения.
11.1.6. Меню.
(1) главное меню с выпадающими списками разделов;
(2) каскадное меню, в котором разделу первичного меню соответствует список подразделов;
(3) всплывающее или контекстное меню, появляющееся, если пользователь щелкает правой кнопкой мыши на каком-то компоненте.
(1) компонент MainMenu - главное меню;
(2) компонент PopupMenu - всплывающее меню;
(3) меню, настраиваемое пользователем во время выполнения:
- компонент ActionManager,
- компонент ActionMainMenuBar.
- размещения общепринятых разделов;
- снабжения главного меню инструментальной панелью;
- расположения разделов в выпадающем меню, отделенных разделителями по функционально связанным группам разделов;
- привычности для пользователя названий разделов меню;
- заканчивания многоточием названий разделов меню, связанных с вызовом диалоговых окон;
- разделы, к которым относятся каскадные меню должны заканчиваться стрелкой, указывающей на наличие дочернего меню данного раздела;
- в каждом названии раздела должен быть выделен подчеркиванием символ, соответствующий клавише быстрого доступа к разделу (клавиша Alt плюс подчеркнутый симилл);
- многим разделам могут быть поставлены в соответствие "горячие" клавиши, позволяющие обратиться к команде данного раздела, даже не заходя в меню (например, "горячие" клавиши Ctrl-X, Ctrl-C, Ctrl-V);
- многие разделы меню желательно снабжать общеприянятыми пиктограммами;
- для контроля за управляемостью разделами отдельные разделы должны делаться времен-но недоступными или невидимыми, это осуществляется заданием значения false свойствами раздела Enabled или Visible соответственно.
(1) Save As Template - сохранение шаблона меню,
(2) Insert Form Template - загрузка шаблона меню.
11.1.7. Компоновка форм.
11.1.8. Последовательность фокусировки элементов.
- через свойства формы: ActiveControl и TabOrder;
- программное переключение фокуса - это метод SetFocus, например, Edit2 > SetFocus().
11.1.9. Подсказки и контекстно-зависимые справки.
Приложение должно предельно облегчать работу пользователя, снабжая его системой подсказок, помогающих сориентироваться в приложении. Эта система включает в себя:
Тексты ярлычков и подсказок панели состояния устанавливаются для любых визуальных компонентов в свойстве Hint в виде строки текста, состоящей из двух частей, разделенных символом вертикальной черты '|'. Первая часть, обычно очень краткая, предназначена для отображения в ярлычке; вторая более развернутая подсказка предназначена для отображения в панели состояния или ином заданном месте экрана. Например, в кнопке, соответствующей команде открытия файла, в свойстве Hint может быть задан текст:
Открыть|Открытие текстового файла
Как частный случай, в свойстве Hint может быть задана только первая часть подсказки без символа '|'.
Для того чтобы первая часть подсказки появлялась во всплывающем ярлычке, когда пользователь задержит курсор мыши над данным компонентом, надо сделать следующее:
1. Указать тексты свойства Hint для всех компонентов, для которых вы хотите обеспечить ярлычок подсказки.
2. Установить свойства ShowHint (показать подсказку) этих компонентов в true или установить в true свойство ParentShowHint (отобразить свойство ShowHint родителя) и установить в true свойство ShowHint контейнера, содержащего данные компоненты.
Конечно, вы можете устанавливать свойства в true или false программно, включая и отключая подсказки в различных режимах работы приложения.
При ShowHint, установленном в true, окно подсказки будет всплывать, даже если компонент в данный момент недоступен (свойство Enabled = false).
Если вы не задали значение свойства компонента Hint, но установили в true свойство ShowHint или установили в true свойство ParentShowHint, a в родительском компоненте ShowHint = true, то в окне подсказки будет отображаться текст Hint из родительского компонента.
Правда, все описанное выше справедливо при значении свойства ShowHint приложения Application равном true (это значение задано по умолчанию). Если установить Application->ShowHint в false, то окна подсказки не будут появляться независимо от значений ShowHint в любых компонентах.
Свойства Hint компонентов можно также использовать для отображения текстов заключенных в них сообщений в какой-то метке или панели с помощью функций GetShortHint и GetLongHint, первая из которых возвращает первую часть сообщения, а вторая - вторую (если второй части нет, то возвращается первая часть). Например, эти функции можно использовать в обработчиках событий OnMouseMove, соответствующих прохождению курсора мыши над данным компонентом. Так обработчик: void fastcall TForml::ButtonlMouseMove(TObject *Sender,
TShiftState Shift, int X, int У) {
TControl *Send = (TControl *)Sender;
Panel1->Caption = GetShortHint(Send->Hint);
Panel2->Caption = GetLongHint(Send->Hint); }
отобразит в панели Panel1 первую, а в панели Panel2 - вторую часть свойства Hint всех компонентов, над которыми будет перемещаться курсор, если в этих компонентах в событии OnMouseMove указан этот обработчик ButtonlMouseMove. Причем это не зависит от значения их свойства ShowHint.
Еще один пример. Пусть вы хотите, чтобы при нажатии некоторой кнопки Buttonl вашего приложения в панели Panel1 высвечивалась подсказка пользователю, например, "Укажите имя файла", а сама кнопка имела всплывающий ярлычок подсказки с текстом "Ввод". Тогда вы можете задать свойству Hint этой кнопки значение "Ввод|Укажите имя файла", задать значение true свойству ShowHint, а в обработчик события нажатия этой кнопки вставить оператор
Panell->Caption = GetLongHint(Buttonl->Hint);
Если же вы не хотите отображать ярлычок подсказки для кнопки, то можете ограничиться значением Hint, равным "Укажите имя файла", а приведенный выше оператор оставить неизменным или заменить на эквивалентный ему в данном случае оператор
Panel1->Caption = GetShortHint(Button1->Hint); или даже просто на оператор>br? Panell->Caption = Buttonl->Hint;
Перед тем моментом, когда должен отобразиться ярлычок какого-нибудь компонента, возникает событие приложения OnShowHint. В обработчике этого события можно организовать какие-то дополнительные действия, например, изменить отображаемый текст. Особенно легко работать с событиями приложения, начиная в C++Builder 5, в котором появился компонент ApplicationEvents, перехватывающий все эти события (см. подроб-нее в разд. 4.6). В обработчик его события OnShowHint можно поместить те операторы, которые надо выполнить перед отображением ярлычка. Заголовок этого обработчика имеет вид:
void __fastcall TForml::ApplicationEventslShowHint(
AnsiString SHintStr, bool SCanShow, THintInfo &HintInfo)
Здесь передаваемый по ссылке параметр HintStr - отображаемый в ярлычке текст. В обработчике этот текст можно изменить. Так же по ссылке передается параметр CanShow. Если в обработчике установить его равным false, то ярлычок отображаться не будет. Третий параметр, передаваемый по ссылке - HintInfo. Это струк-тура, поля которой содержат информацию о ярлычке: его координаты, цвет, задержки появления и т.п. В частности, имеется поле HintControl - компонент, сообщение которого должно отображаться в ярлычке, и поле HintStr - отображаемое сообщение. По умолчанию HintInfo. HintStr - первая часть свойства Hin компонента. Но в обработчике это значение можно изменить.
Имеется еще один способ отображения второй части сообщения, записанного в Hint, в строке состояния или какой-то области экрана в моменты, когда курсор мыши проходит над компонентом - это использование обработки события приложения OnHint. Это событие не того компонента, над которым проходит курсор мыши, а именно приложения - объекта Application. Начиная с C++Builder 5 это событие также перехватывается компонентом ApplicationEvents. Если обработчик этого события определен, то в момент прохождения курсора над компонентом, в котором задано свойство Hint, вторая часть сообщения компонента заносится в свойство Hint объекта Application. Если свойство Hint компонента содержит только одну часть, то в свойство Hint объекта Application заносится эта первая часть.
Если ваше приложение содержит инструментальную панель с быстрыми кнопками, то, как правило, эти кнопки должны снабжаться не только всплывающими ярлычками, но и развернутыми подсказками в панели состояния. Если у вас есть подобный пример, вы можете опробовать на нем методику отображения подсказок в панели состояния. А можете взять какой-нибудь более простой пример. Для реализации подсказок в панели состояния надо перенести на форму панель состояния - компонент StatusBar со страницы Win32. Если вам нужна односекционная панель, установите свойства SimplePanel и AutoHint панели StatusBar в true. Больше ничего делать не требуется - свойство AutoHint обеспечит автоматическое отображение подсказок. Запустите приложение на выполнение. Вы увидите, что тексты подсказок отображаются в панели состояния, когда курсор мыши перемещается над тем или иным окном редактирования. Причем это не мешает появляться ярлычкам, отображающим тексты окон.
Если вы используете многосекционную панель состояния, то свойство AutoHint обеспечит отображение подсказок только в первой секции. Для отображения подсказок в другой секции надо перенести на форму компонент ApplicationEvents и в обработчик его события OnHint компонента вставить оператор
StatusBarl->Panels->Items[I]->Text = Application->Hint;
где I - индекс секции.
Более подробные пояснения пользователю может дать контекстно-зависимая справка, встроенная в приложение. Она позволяет пользователю нажать в любой момент клавишу F1 и получить развернутую информацию о том компоненте в окне, который в данный момент находится в фокусе. Для того чтобы это осуществить, надо разработать для своего приложения файл справки .help. Как это сделать, подробно описано в [1]. Затем надо в каждом компоненте, для которого вы хотите обеспечить контекстно-зависимую справку, задать свойства, обеспечивающие ссылку на соответствующую тему.
В версиях, младше C++Builder 6, такое свойство одно - HelpContext. Это номер темы, который задается в проекте справки специальной таблицей [MAP], содержащей эти условные номера и соответствующие им идентификаторы тем. В C++Builder 6 появилось еще два свойства: HelpKeyword и HelpType. Первое из них является идентификатором темы, содержащимся в сноске К. А второе определяет, каким свойством - HelpContext или HelpKeyword задается ссылка на тему. Если HelpType = htContext - используется свойство HelpContext; если HelpType = htKeyword - используется свойство HelpKeyword.
Если HelpContext компонента равен нулю, то данный компонент наследует это свойство от своего родительского компонента. Например, для всех компонентов, размещенных на некоторой панели можно задать Help-Context = 0, а для самой панели задать отличное от нуля значение HelpContext, соответствующее теме, описывающей назначение всех компонентов панели.
Для того чтобы все это работало, надо выполнить команду Pro|ect | Options и в окне Project Options (опции проекта) на странице Application (приложение) установить значение опции Help file, равное имени подготовленного файла .hlp. Это приведет к тому, что в головном файле проекта появится оператор вида:
Application->HelpFile = "<имя файла>.hlp";
В этом операторе используется метод HelpFiIe, определяющий файл справки, к которому обращается проект. Этот метод и подобный оператор можно использовать в приложении в любом обработчике события, если в какие-то моменты требуется сменить используемый файл справки.
Если предполагается, что файл справки будет расположен в том же каталоге, где находится само приложение, то имя файла и в окне Опции проекта, и в приведенном выше операторе надо задавать без указания пути. Иначе приложение, работающее на вашем компьютере, перестанет работать на компьютере пользователя, у которого каталоги не совпадают с вашими.
Для того чтобы приложение в свойствах HelpContext могло ссылаться на какой-то номер контекстной справки, в файле проекта справки .hpj в разделе [MAP] надо поместить таблицу соответствия использованных значений HelpContext и тем файла .hlp.
В заключение поговорим о традиционном разделе меню Справка, позволяющем пользователю открыть файл справки .hlp и получить развернутую информацию по всем вопросам, связанным с данным приложением. В обработчик события при выборе данного раздела меню или при нажатии соответствующих кнопок помощи вставляются операторы вида
Application->HelpContext(<номеp темы>);
Задаваемые в этих операторах номера тем аналогичны используемым при задании свойств HelpContext. Это номер той темы, которая первой отобразится при открытии окна справки. А в дальнейшем пользователь, как обычно, может перейти, работая с программой справки, к любой интересующей его теме.
Имеется еще несколько методов объекта Application, обеспечивающих работу со справочными файлами.
Еще один механизм подсказок, связанный с файлом справок .hlp - кнопка справки, присутствующая в заголовках многих современных окон Windows. Нажав ее, пользователь может подвести курсор мыши, изменивший свою форму на вопросительный знак, к какому-то компоненту, щелкнуть и во всплывшем окне появится развернутая подсказка, поясняющая назначение данного компонента. Для того чтобы ввести такую возможность в свое приложение, надо установить в true подсвойство byHelp свойства BorderIcons вашей формы. Однако не для всех форм это вызовет появление в заголовке окна кнопки справки. Кнопка появится только в случае, если свойство BorderStyle формы установлено в bsDialog. Никакого программирования работа с кнопкой справки не требует. Все будет выполняться автоматически. Достаточно предусмотреть в файле .hlp соответствующие темы и сделать на них ссылки в свойствах HelpContext компонентов. Эти темы будут появляться при соответствующих действиях пользователя во всплывающих окнах.