Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
New Документ Microsoft Word (3).doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
1.34 Mб
Скачать

Управление строкой состояния

Стандартной строке состояния присваивается идентификатор дочернего окна AFX_IDW_STATUS_BAR. Именно его каркас приложений ищет для вывода подсказки по элементам меню. Обработчики сообщений обновления пользовательского интерфейса используют три идентификатора строковых ресурсов для индикаторов состояния клавиатуры в базовом классе окна-рамки: ID_INDICATOR_CAPS, ID_INDICATOR_NUM и ID_INDICATOR_SCRL. Чтобы самому управлять строкой состояния, нужно применить другой идентификатор дочернего окна и другие константы для индикаторов.

Примечание. Изменять идентификатор дочернего окна строки состояния имеет смысл только в том случае, если Вы хотите предотвратить вывод каркасом приложений подсказок в секцию 0.

Идентификатор для окна строки состояния назначается вызовом CStatusBar::Create() в функции-члене OnCreate() производного класса окна-рамки. Эта функция содержится в файле MainFrm.cpp, генерируемом мастером. Третий параметр функции Create() – идентификатор окна – по умолчанию равен AFX_IDW_STATUS_BAR.

Чтобы назначить свой идентификатор, замените вызов

m_wndStatusBar.Create(this);

на

m_wndStatusBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_BOTTOM,

ID_MY_STATUS_BAR);

Конечно, нужно определить и константу ID_MY_STATUS_BAR в файле resource.h, используя редактор символов. (Предполагается, что пока Вы не изменяете программный код, а просто наматываете информацию на свой ус.)

Но Вы кое-что забыли. Стандартное меню View, формируемое каркасом приложений, позволяет включать и отключать показ строки состояния. Эта логика реализуется кодом, использующим идентификатор окна AFX_IDW_STATUS_BAR, который тоже придется изменить. В своем производном классе окна-рамки напишите элементы таблицы сообщений и обработчики для команды ID_VIEW_STATUS_BAR и сообщений, связанных с обновлением пользовательского интерфейса. ID_VIEW_STATUS_BAR – это идентификатор элемента меню Status Bar. Как Вы будете лицезреть ниже, обработчики в производном классе переопределяют стандартные обработчики из базового класса.

11.4.Сценарий выполнения второй части работы

Сейчас мы заменим, для тренажа, стандартную строку состояния новой со следующими текстовыми секциями:

Индекс секции

Идентификатор строки

Тип

Описание

0

ID_SEPARATOR (0)

Строка сообщений

х-координата курсора

1

ID_SEPARATOR (0)

Строка сообщений

у-координата курсора

2

ID_INDICATOR_LEFT

Индикатор состояния

Состояние ЛКМ

3

ID_INDICATOR_RIGHT

Индикатор состояния

Состояние ПКМ

Новая строка состояния показана на рис. 3. Обратите внимание: при увеличении размеров окна-рамки крайняя левая секция растягивается за пределы своей обычной длины в 1/4 ширины экрана.

Рис. 3. Новая строка состояния программы

Шаг 11. Отредактируйте в редакторе ресурсов ресурс строковой таблицы. Чтобы запустить редактор строковых ресурсов, дважды щелкните папку String Table на странице ResourceView. Затем дважды щелкните пустой элемент в конце списка, чтобы перейти в режим редактирования ресурса, задайте идентификатор ID равным ID_INDICATOR_RIGHT и Caption==Right. Значение Value оставьте неизменным (рис. 4).

Рис. 4. Добавление новой строки ресурса

Аналогичным образом добавьте ID==ID_INDICATOR_LEFT и Caption==Left.

Шаг 12. Выберите из меню Edit команду Resource Symbols. В появившемся окне с помощью кнопаря New добавьте новый идентификатор ID_MY_STATUS_BAR и оставьте для него значение, предлагаемое по умолчанию.

Шаг 13. Добавьте в класс CMainFrame обработчики команд, содержащихся в меню View. Добавьте заготовки следующих обработчиков командных сообщений:

Идентификатор объекта

Сообщение

Член-функция

ID_VIEW_STATUS_BAR

COMMAND

OnViewStatusBar

ID_VIEW_STATUS_BAR

UPDATE_COMMAND_UI

OnUpdateViewStatusBar

Кроме того, объявите m_wndTollBar открытой, а не защищенной переменной (файл MainFrm.h).

Шаг 14. Отредактируйте файл MainFrm.cpp. Замените старое содержимое массива indicators новым:

Далее отредактируйте функцию-член OnCreate(). Замените оператор

if (!m_wndStatusBar.Create(this) ||

!m_wndStatusBar.SetIndicators(indicators,

sizeof(indicators)/sizeof(UINT)))

{

TRACE0("Failed to create status bar\n");

return -1; // fail to create

}

следующим

В модифицированном вызове функции Create() вместо AFX_IDW_STATUS_BAR (объект строки состояния, формируемый каркасом приложений и используемый по умолчанию) используется наш идентификатор строки состояния ID_MY_STATUS_BAR.

Теперь добавьте, вручную, следующие элементы таблицы сообщений для класса CMainFrame, так как ИС (такая тупая, как любит говорить Задорнов, американская ИС!) это сделать не в состоянии по причине отсутствия способности к распознаванию идентификаторов из строковой таблицы в качестве идентификаторов объектов:

ON_UPDATE_COMMAND_UI(ID_INDICATOR_LEFT, OnUpdateLeft)

ON_UPDATE_COMMAND_UI(ID_INDICATOR_RIGHT, OnUpdateRight)

В результате таблица сообщений (файл MainFrm.cpp) должна приобрести такое обличье:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

ON_WM_CREATE()

ON_WM_SETFOCUS()

ON_COMMAND(ID_VIEW_STATUS_BAR, &CMainFrame::OnViewStatusBar)

ON_UPDATE_COMMAND_UI(ID_VIEW_STATUS_BAR, &CMainFrame::OnUpdateViewStatusBar)

ON_UPDATE_COMMAND_UI(ID_INDICATOR_LEFT, OnUpdateLeft)

ON_UPDATE_COMMAND_UI(ID_INDICATOR_RIGHT, OnUpdateRight)

END_MESSAGE_MAP()

Затем вставьте функции-члены класса CMainFrame, отвечающие за обновление индикаторов состояния кнопочек мыши:

Заметьте: левой и правой кнопкам мыши, как и клавишам на клавиатуре, соответствуют коды виртуальных клавиш, поэтому при определении состояния кнопок можно обойтись без обработки сообщений от мыши.

Не забудьте также добавить прототипы этих функций в заголовочный файл MainFrm.h (то бишь тело класса CMainFrm) в следующем виде и месте (добавленные строки выделены курсивом):

DECLARE_MESSAGE_MAP()

public:

afx_msg void OnViewStatusBar();

afx_msg void OnUpdateViewStatusBar(CCmdUI *pCmdUI);

afx_msg void OnUpdateLeft(CCmdUI* pCmdUI); // добавлено

afx_msg void OnUpdateRight(CCmdUI* pCmdUI); // добавлено

И, в конце концов, отредактируйте следующие функции для меню View, заготовки которых были сгенерированы в файле MainFrm.cpp:

Эти функции обеспечивают надлежащую связь команды Status Bar меню View с новой строкой состояния.

Соберите приложение и запустите на выполнение. Убедитесь в том, что нашу строку состояния можно показывать и прятать с помощью команды Status Bar меню View. Также проверьте, что при нажатии ЛКМ или ПКМ в строке состояния появляется, как черт из коробочки, текст Left или Right. Проверили, не появляется? Попробуйте сильно увеличить ширину окна, чтобы появилось место для отображения состояния ЛКМ и ПКМ. Теперь получается?

Для того чтобы уменьшить ширину строки статуса, которая отводится для первых двух панелей, добавьте в функцию CMainFrame::OnCreate() (после вызова функции Create для строки состояния) следующие операторы:

m_wndStatusBar.SetPaneInfo(0, 0, 0, 50);

m_wndStatusBar.SetPaneInfo(1, 0, SBPS_STRETCH, 50);

Узнайте назначение параметров SetPaneInfo() из MSDN. Проверьте, что теперь строка состояния ведет себя подобающим образом.

Шаг 14. Добавьте вывод координат мыши в строку состояния. Для этого присовокупите сначала к классу вида обработчик сообщения WM_MOUSEMOVE и наполните его таким кодом:

Соберите и тестируйте приложение. Не получается? В чем проблема? Попробуйте сами устранить ошибки. Если не получится – станьте на голову и прочтите ценные указания.

Боевое задание для совершения подвига. В нынешнем виде программа открывает для просмотра файлы только с расширениями .bmp, .jpg, .gif и .png, хотя система поддерживает большее число форматов. Вам предоставляется возможность расширить функциональность программы, научив ее открывать и файлы других графических форматов. Найдите в MSDN описание функции CImage::GetExporterFilterString() и … Вы сможете решить эту проблему. Убедитесь в том, что программа корректно сохраняет открытый файл любого формата. Для этого, очевидно, Вам понадобится отредактировать текст функции CChildView::OnSaveimage(). Вообще говоря, было бы уместно передать перечень типов файлов, возвращаемых функцией CImage::GetExporterFilterString(), в функцию CChildView::OnSaveimage().

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]