На этом шаге мы рассмотрим изменение строки состояния.
В некоторых случаях для оповещения о состоянии приложения недостаточно простой модификации меню и кнопки панели инструментов. Вернемся к приложению МуАрр. Команда 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" ("База данных не подсоединена"). На этом этапе можно не выбирать источник данных из списка, ограничившись выводом фиксированного имени.
Создадим переменную-член класса СМуАррАрр для хранения имени текущего источника данных.
Рис.1. Задание переменной m_strDSN
m_strDSN = "MyDatabase";
Рис.2. Текст конструктора СМуАррАрр
Создадим идентификатор строки для нового индикатора.
Рис.3. Выбор пункта New String
Рис.4. Вставка строки в таблицу строк
Теперь Вам предстоит модифицировать код создания строки состояния, заменив три стандартных индикатора одним индикаторов ID_INDICATOR_DB.
static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, };
Рис.5. Массив indicators[]
static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_DB, };
Взгляните на код, расположенный ниже функции CMainFrm::OnCreate(). Обратите внимание, что массив indicators передается в качестве параметра функции CStatusBar::SetIndicators(), которая вызывается для объекта CMainFrame::m_wndStatusBar.
Рис.6. Текст функции CMainFrm::OnCreate()
Сейчас Вы вручную добавите новый элемент в карту сообщении и создадите функцию-обработчик для обновления индикаторов.
ON_UPDATE_COMMAND_UI(ID_INDICATOR_DB, OnUpdateDB)
Обратите внимание, что все элементы карты сообщений, создаваeмые нe ClassWizard, должны находиться вне блока, выделенного строками //{{AFX_MSG_MAP. Полностью карта сообщений будет выглядеть следующим образом:
Рис.7. Карта сообщений
afx_msg void OnUpdateDB(CCmdUI *pCmdUI);
Помните, что эту строку также нужно разместить вне блока //{{AFX_MSG.
Рис.8. Описание функции 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<>().
Обратите внимание и на отладочный макрос ASSERT_VALID, проверяющий достоверность полученного указателя.
Со следующего шага мы начнем знакомиться с созданием диалоговых окон.