На этом шаге мы рассмотрим изменение строки состояния.
В некоторых случаях для оповещения о состоянии приложения недостаточно простой модификации меню и кнопки
панели инструментов. Вернемся к приложению МуАрр. Команда Connect позволяет установить
соединение лишь с одним источником данных. А как быть, если имеется несколько альтернативных источников и
требуется часто переключаться между ними?
В этом случае функция OnDataConnect() должна вывести список источников данных, из которого выбирается
нужный. Чтобы отобразить текущее состояние соединения, надо показать либо имя подключенного источника данных,
либо сообщение о том, что приложение не связано ни с одним источником.
Лучше всего такую информацию поместить в строку состояния (Status Bar) приложения.
В строку состояния MFC-приложения уже выводится приглашение команды меню. Там же в отельных
полях-индикаторах может отображаться состояние клавиш CAPS LOCK, NUM LOCK и SCROLL LOCK.
В MFC поддержка строк состояния инкапсулирована в классе CStatusBar, посредством которого
можно управлять составом и стием индикаторов, а также текстом в строке состояния.
Сведения об индикаторах содержатся в массиве, где первый слева индикатор имеет индекс 0. По умолчанию первый
индикатор является "резиновым" - он занимает часть строки состояния, свободную
от остальных элементов, которые при этом выравниваются по правому краю. В первый индикатор каркас
MFC-приложения выводит и формацию о выбранной команде меню или панели управления.
При создании строки состояния используется массив идентификаторов строковых ресурсов, которые каркас связывает
с соответствующими индикаторами. В дальнейшем к индикатору можно обращаться либо по индексу, либо по
идентификатору строки.
Для изменения текста в строке состояния рекомендуется использовать запись карты сообщений
ON_UPDATE_COMMAND_ID, чтобы связать функцию-обработчик обновления пользовательского
интерфейса с идентификатором строки индикатора. Для вывода текста в индикатор следует вызвать функцию SetText()
объекта CCmdUI, передаваемого обработчику в качестве параметра. Учтите, что ClassWizard не
связывает автоматически идентификатор индикатора c функцией-обработчиком, поэтому соответствующую запись
в карту сообщений необходимо добавлять вручную.
Изменить текст в индикаторе можно средствами функции CStatusBar::SetPaneText(). Однако при этом требуется
создать обработчик обновления, потому что без него индикатор автоматически блокируется, а текст в нем удаляется.
Проиллюстрируем сказанное на конкретных примерах.
Заменим стандартные индикаторы CAPS LOCK, NUM LOCK и SCROLL LOCK приложения
МуАрр на один индикатор, показывающий имя подключенного источника данных, которое хранится в
переменной класса приложения. При отсутствии источника данных в индикатор должна выводиться строка
"Database not connected" ("База данных не подсоединена"). На этом этапе можно не выбирать источник данных из
списка, ограничившись выводом фиксированного имени.
Создадим переменную-член класса СМуАррАрр для хранения имени текущего источника данных.
- Добавление переменной-члена m_strDSN в класс СМуАррАрр.
- На вкладке ClassView щелкните правой кнопкой мыши значок класса СМуАррАрр.
- В контекстном меню выберите пункт Add Member Variable.
- В поле Variable Type диалогового окна Add Member Variable введите CString.
- В поле Variable Name наберите m_strDSN.
Рис.1. Задание переменной m_strDSN - Убедитесь, что указан тип доступа Public. Щелкните ОК, чтобы добавить переменную в класс СМуАррАрр.
- Дважды щелкните значок конструктора класса СМуАррАрр, что бы войти в редактор кода.
- Добавьте в код конструктора строку, определяющую начальное значение переменной m_strDSN:
m_strDSN = "MyDatabase";
Рис.2. Текст конструктора СМуАррАрр - Создание идентификатора индикатора ID_INDICATOR_DB.
- В окне Workspace приложения МуАрр щелкните вкладку ResourceView.
- Раскройте узел String Table.
- Двойным щелчком ресурса String Table откройте редактор таблицы строк.
- Найдите в столбце идентификаторов строки, начинающиеся с ID_INDICATOR_.
- Щелкните правой кнопкой мыши последнюю строку - ID_INDICATOR_REC.
- В контекстном меню выберите пункт New String.
Рис.3. Выбор пункта New String - В поле ID введите ID_INDICATOR_DB.
- В поле Caption введите Database not connected. Этот текст задан по умолчанию для элемента таблицы строк. Введите в конец этой
строки еще 15 пробелов. Это нужно для того, чтобы обеспечить в поле индикатора место для вывода самого длинного имени,
поскольку длина строки вместе с пробелами определяет длину индикатора. Результат Ваших действий должен выглядеть так,
как показано на рисунке 4.
Рис.4. Вставка строки в таблицу строк - Нажмите ENTER, чтобы добавить новую строку, и закройте редактор таблицы строк.
- Установка индикаторов строки состояния приложения МуАрр.
- В окне Workspace приложения МуАрр щелкните вкладку FileView.
- Раскройте узел Source Files.
- Двойным щелчком значка файла MainFrm.cpp откройте редактор кода.
- Найдите в программе описание массива индикаторов строки состояния, которое располагается сразу после карты
сообщений и должно выглядеть следующим образом:static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, };
Рис.5. Массив indicators[] - Удалите последние три элемента массива, оставив только ID_SEPARATOR. В качестве второго элемента
массива введите идентификатор ID_INDICATOR_DB:static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_DB, };
- Добавление записи в карту сообщений.
- Найдите в том же файле карту сообщений. Она должна располагаться над массивом, который Вы редактировали
в предыдущем упражнении. - Введите следующий макрос в карту сообщений:
ON_UPDATE_COMMAND_UI(ID_INDICATOR_DB, OnUpdateDB)
Обратите внимание, что все элементы карты сообщений, создаваeмые нe ClassWizard, должны находиться вне
блока, выделенного строками //{{AFX_MSG_MAP. Полностью карта сообщений будет выглядеть следующим
образом:
Рис.7. Карта сообщений - Добавление функции-обработчика.
- В окне Workspace приложения МуАрр щелкните вкладку FileView.
- Раскройте узел Header Files.
- Двойным щелчком значка файла MainFrm.h откройте редактор кода.
- В конце описания класса CMainFrame непосредственно над макросом DECLARE_MESSAGE_MAP
введите следующее описание функции:afx_msg void OnUpdateDB(CCmdUI *pCmdUI);
Помните, что эту строку также нужно разместить вне блока //{{AFX_MSG.
Рис.8. Описание функции OnUpdateDB() - Вернитесь к файлу MainFrm.cpp. В конце него введите код для функции OnUpdateDB():
void CMainFrame::OnUpdateDB(CCmdUI *pCmdUI) { CMyAppApp * pApp = dynamic_cast<CMyAppApp *>(AfxGetApp()); ASSERT_VALID(pApp); if (pApp->m_isDatabaseConnected) pCmdUI->SetText("Connected to: "+ pApp->m_strDSN); else pCmdUI->SetText("Database not connected"); }
Рис.9. Текст функции OnUpdateDB()
Работает эта функция достаточно просто. Сначала, чтобы узнать подключена ли программа к базе данных, проверяется
значение переменной СМуАррАрр:: m_isDatabaseConnected. Если ее значение равно TRUE, функция
извлекает имя текущего источника данных из CMyAppApp::m_strDSN и помещает его в строку состояния,
иначе выводится текст "Database not connected". Обратите внимание на вызов глобальной MFC-функции
AfxGetАрр(), возвращающей указатель на главный объект приложения. Эту функцию надо привести к типу
СМуАррАрр*, чтобы получить возможность ссылаться на переменные класса СМуАррАрр.
Для приведения типа с понижением в иерархии наследования требуется оператор dynamic_cast<>().
Замечание. Перед тем как использовать оператор dynamic_cast<>(), проверьте,
установлен ли флажок Enable Run-Time Type Information (RTTI) в параметрах языка на вкладке C/C++
параметров проекта. (Смотри 3 шаг, рисунок 7.)
Обратите внимание и на отладочный макрос ASSERT_VALID, проверяющий достоверность полученного
указателя. - Соберите и запустите программу МyAрр. Щелкните команду Connect и посмотрите, отображает
ли текст, появляющийся в правой части строки состояния, изменения в состоянии подключения к БД. В дальнейшем мы
модифицируем команду Connect таким образом, чтобы она открывала диалоговое окно, в котором можно
выбрать источник данных. Согласно этому сценарию, оповещение пользователей о том, с каким источником данных
связано приложение, будет производится индикатором в строке состояния.
Создадим идентификатор строки для нового индикатора.
Теперь Вам предстоит модифицировать код создания строки состояния, заменив три стандартных индикатора одним
индикаторов ID_INDICATOR_DB.
Взгляните на код, расположенный ниже функции CMainFrm::OnCreate(). Обратите внимание, что массив
indicators передается в качестве параметра функции CStatusBar::SetIndicators(), которая вызывается
для объекта CMainFrame::m_wndStatusBar.
Рис.6. Текст функции CMainFrm::OnCreate()
Сейчас Вы вручную добавите новый элемент в карту сообщении и создадите функцию-обработчик для обновления
индикаторов.
Текст измененного приложения можно взять здесь (46,0 Кб).
Со следующего шага мы начнем знакомиться с созданием диалоговых окон.