Обработка сообщений от элементов управления
В окно диалога мы ввели четыре кнопки, при нажатии которых в класс диалогового окна посылается уведомляющее сообщение BN_CLICKED. При изменении данных в окнах редактирования посылаются другие сообщения EN_CHANGE. При воздействии на ползунки также посылаются уведомляющие сообщения, которые мы рассматривали в предыдущей главе. Однако, как было отмечено, ползунки посылают и обычные сообщения (WM_HSCROLL или WM_VSCROLL). Если в окне диалога имеется более одного ползунка, то сообщения от них удобно обработать в одной функции, которая вызывается в ответ на сообщение о прокрутке. Введите в класс CPolyDlg реакцию на WM_HSCROLL, так как наши ползунки ориентированы горизонтально:
void CPolyDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { //====== Неинтересное для нас сообщение if (nSBCode==SB_ENDSCROLL) return; //====== Устанавливаем флаг сообщений от ползунков m_bScroll = true; //====== Узнаем идентификатор активного ползунка switch (GetFocus() › GetDlgCTRLID()) { case IDC_RSLIDER: //====== Считываем текущую позицию движка m_nRed = m_rSlider.GetPos(); //====== Синхронизируем поле, редактирования SetDlgltemlnt(IDC_RED, m_nRed); break; case IDC_GSLIDER: m_nGreen = m_gSlider.GetPos(); SetDlgltemlnt(IDC_GREEN, m_nGreen); break; case IDC_BSLIDER: m_nBlue = m_bSlider.GetPos(); SetDlgltemlnt(IDC_BLUE, m_nBlue); break; } //====== Снимаем флаг сообщений от ползунков m_bScroll = false; }
Сообщения от всех ползунков обрабатываются в одной функции. Идентификатор активного ползунка определяется путем последовательного вызова двух функций GetFocus и GetDlgCTRLiD, являющихся методами класса cwnd.
Флаг сообщений от ползунков (m_bScroll) понадобился нам для того, чтобы при синхронизации элементов управления не происходили повторные вызовы функций-обработчиков. Дело в том, что при изменении позиции ползунка мы должны привести в соответствие окно редактирования, а при ручном изменении числа в окне редактирования мы должны синхронизировать позицию ползунка. Но сообщение EN_CHANGE посылается как при ручном изменении, так и при программном изменении с помощью функции SetDlgltemlnt. Проследим цепь таких событий: пользователь подвинул движок ползунка, мы вызываем SetDlgltemlnt, она провоцирует посылку сообщения EN_CHANGE, а обработчик этого сообщения корректирует положение ползунка, которое и без того верно.
Введите в класс диалога реакции на уведомления EN_CHANGE от четырех элементов IDC_PEN, IDC_RED, IDC_GREEN И IDC_BLUE. Вы помните, что это надо делать с помощью кнопки Events в окне Properties. Вставьте коды в остовы функций обработки, как показано ниже:
void CPolyDlg::OnChangePen (void) { BOOL bSuccess; //====== Попытка преобразовать в число UINT nSize = GetDlgltemlnt(IDC_PEN, SbSuccess, FALSE); if (bSuccess && nSize < 101) { m_nPen = nSize; m_pDoc › m_Poly-m_nPenWidth = m_nPen; m_pDoc › UpdateDrawView(); } }